summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt36
-rw-r--r--cmds/bootanimation/BootAnimation.cpp4
-rw-r--r--cmds/bootanimation/BootAnimation.h7
-rw-r--r--cmds/bootanimation/bootanimation_main.cpp2
-rw-r--r--cmds/dumpstate/dumpstate.c32
-rw-r--r--cmds/dumpstate/dumpstate.h2
-rw-r--r--cmds/dumpstate/utils.c2
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java69
-rw-r--r--cmds/screencap/screencap.cpp2
-rw-r--r--cmds/stagefright/Android.mk24
-rw-r--r--cmds/stagefright/SimplePlayer.cpp646
-rw-r--r--cmds/stagefright/SimplePlayer.h109
-rw-r--r--cmds/stagefright/codec.cpp408
-rw-r--r--cmds/stagefright/sf2.cpp21
-rw-r--r--cmds/stagefright/stagefright.cpp4
-rw-r--r--cmds/stagefright/stream.cpp3
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl3
-rw-r--r--core/java/android/accessibilityservice/UiTestAutomationBridge.java23
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/app/ApplicationPackageManager.java18
-rw-r--r--core/java/android/app/Fragment.java2
-rw-r--r--core/java/android/app/INotificationManager.aidl1
-rw-r--r--core/java/android/app/Notification.java493
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl6
-rw-r--r--core/java/android/content/pm/PackageInfo.java26
-rw-r--r--core/java/android/content/pm/PackageManager.java25
-rw-r--r--core/java/android/content/pm/PackageParser.java32
-rw-r--r--core/java/android/content/pm/PermissionInfo.java61
-rw-r--r--core/java/android/inputmethodservice/ExtractEditLayout.java6
-rw-r--r--core/java/android/provider/CalendarContract.java15
-rw-r--r--core/java/android/view/ActionMode.java28
-rw-r--r--core/java/android/view/GLES20Canvas.java69
-rw-r--r--core/java/android/view/View.java14
-rw-r--r--core/java/android/view/ViewGroup.java17
-rw-r--r--core/java/android/view/ViewRootImpl.java339
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java8
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java52
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfoCache.java (renamed from core/java/android/view/AccessibilityNodeInfoCache.java)104
-rw-r--r--core/java/android/view/accessibility/AccessibilityRecord.java7
-rw-r--r--core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl2
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java131
-rw-r--r--core/java/android/webkit/BrowserFrame.java115
-rw-r--r--core/java/android/webkit/CacheLoader.java79
-rw-r--r--core/java/android/webkit/CacheManager.java636
-rw-r--r--core/java/android/webkit/CallbackProxy.java8
-rw-r--r--core/java/android/webkit/ContentLoader.java98
-rw-r--r--core/java/android/webkit/CookieManager.java793
-rw-r--r--core/java/android/webkit/CookieSyncManager.java101
-rw-r--r--core/java/android/webkit/DataLoader.java77
-rw-r--r--core/java/android/webkit/FileLoader.java189
-rw-r--r--core/java/android/webkit/FrameLoader.java421
-rw-r--r--core/java/android/webkit/HTML5Audio.java22
-rw-r--r--core/java/android/webkit/HttpAuthHandlerImpl.java279
-rw-r--r--core/java/android/webkit/JniUtil.java25
-rw-r--r--core/java/android/webkit/LoadListener.java1685
-rw-r--r--core/java/android/webkit/Network.java394
-rw-r--r--core/java/android/webkit/SelectActionModeCallback.java6
-rw-r--r--core/java/android/webkit/SslErrorHandlerImpl.java273
-rw-r--r--core/java/android/webkit/StreamLoader.java204
-rw-r--r--core/java/android/webkit/WebResourceResponse.java22
-rw-r--r--core/java/android/webkit/WebView.java406
-rw-r--r--core/java/android/webkit/WebViewCore.java52
-rw-r--r--core/java/android/webkit/WebViewDatabase.java648
-rw-r--r--core/java/android/webkit/WebViewWorker.java233
-rw-r--r--core/java/android/widget/AbsListView.java31
-rwxr-xr-xcore/java/android/widget/AppSecurityPermissions.java308
-rw-r--r--core/java/android/widget/Spinner.java13
-rw-r--r--core/java/android/widget/TableLayout.java3
-rw-r--r--core/java/android/widget/TextView.java4700
-rw-r--r--core/java/android/widget/TimePicker.java2
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java10
-rw-r--r--core/java/com/android/internal/net/NetworkStatsFactory.java95
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarNotification.java27
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl11
-rw-r--r--core/java/com/android/internal/view/StandaloneActionMode.java10
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java33
-rw-r--r--core/java/com/android/internal/widget/ScrollingTabContainerView.java10
-rw-r--r--core/java/com/google/android/mms/ContentType.java6
-rw-r--r--core/java/com/google/android/mms/pdu/PduComposer.java4
-rw-r--r--core/java/com/google/android/mms/pdu/PduPersister.java2
-rw-r--r--core/jni/android/graphics/TextLayout.cpp5
-rw-r--r--core/jni/android_app_NativeActivity.cpp11
-rw-r--r--core/jni/android_database_CursorWindow.cpp2
-rw-r--r--core/jni/android_database_SQLiteConnection.cpp2
-rw-r--r--core/jni/android_hardware_Camera.cpp2
-rw-r--r--core/jni/android_view_Display.cpp2
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp36
-rw-r--r--core/jni/android_view_Surface.cpp8
-rw-r--r--core/jni/com_google_android_gles_jni_EGLImpl.cpp11
-rw-r--r--core/res/AndroidManifest.xml119
-rwxr-xr-xcore/res/res/layout/app_perms_summary.xml9
-rw-r--r--core/res/res/values-af/strings.xml6
-rw-r--r--core/res/res/values-am/strings.xml8
-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.xml10
-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.xml8
-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-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-pt-rPT/strings.xml6
-rw-r--r--core/res/res/values-pt/strings.xml6
-rw-r--r--core/res/res/values-rm/strings.xml6
-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.xml8
-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.xml14
-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.xml18
-rwxr-xr-xcore/res/res/values/attrs.xml31
-rw-r--r--core/res/res/values/attrs_manifest.xml30
-rw-r--r--core/res/res/values/public.xml18
-rwxr-xr-xcore/res/res/values/strings.xml10
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java7
-rw-r--r--docs/html/guide/developing/projects/projects-cmdline.jd2
-rw-r--r--docs/html/guide/developing/projects/projects-eclipse.jd2
-rw-r--r--docs/html/guide/topics/fundamentals/fragments.jd2
-rw-r--r--docs/html/images/training/lint_icon.pngbin0 -> 22128 bytes
-rw-r--r--docs/html/sdk/ndk/overview.jd2
-rw-r--r--docs/html/training/improving-layouts/optimizing-layout.jd45
-rwxr-xr-xdrm/java/android/drm/DrmErrorEvent.java30
-rwxr-xr-xdrm/java/android/drm/DrmEvent.java4
-rwxr-xr-xdrm/java/android/drm/DrmInfoEvent.java40
-rwxr-xr-xdrm/java/android/drm/DrmManagerClient.java1
-rwxr-xr-xdrm/java/android/drm/DrmStore.java32
-rw-r--r--graphics/java/android/graphics/PixelFormat.java4
-rw-r--r--graphics/java/android/graphics/Rect.java43
-rw-r--r--graphics/java/android/renderscript/Allocation.java2
-rw-r--r--graphics/java/android/renderscript/RenderScript.java44
-rw-r--r--graphics/java/android/renderscript/RenderScriptGL.java2
-rw-r--r--graphics/java/android/renderscript/ScriptC.java6
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp2
-rw-r--r--include/androidfw/CursorWindow.h (renamed from include/binder/CursorWindow.h)0
-rw-r--r--include/camera/ICamera.h4
-rw-r--r--include/gui/BufferQueue.h121
-rw-r--r--include/gui/IGraphicBufferAlloc.h (renamed from include/surfaceflinger/IGraphicBufferAlloc.h)10
-rw-r--r--include/gui/ISurface.h (renamed from include/surfaceflinger/ISurface.h)6
-rw-r--r--include/gui/ISurfaceComposer.h (renamed from include/surfaceflinger/ISurfaceComposer.h)10
-rw-r--r--include/gui/ISurfaceComposerClient.h (renamed from include/surfaceflinger/ISurfaceComposerClient.h)8
-rw-r--r--include/gui/Surface.h (renamed from include/surfaceflinger/Surface.h)12
-rw-r--r--include/gui/SurfaceComposerClient.h (renamed from include/surfaceflinger/SurfaceComposerClient.h)8
-rw-r--r--include/gui/SurfaceTexture.h54
-rw-r--r--include/gui/SurfaceTextureClient.h4
-rw-r--r--include/media/stagefright/ACodec.h43
-rw-r--r--include/media/stagefright/HardwareAPI.h2
-rw-r--r--include/media/stagefright/MediaCodec.h183
-rw-r--r--include/media/stagefright/MediaErrors.h1
-rw-r--r--include/media/stagefright/NativeWindowWrapper.h26
-rw-r--r--include/media/stagefright/NuMediaExtractor.h80
-rw-r--r--include/media/stagefright/foundation/AMessage.h20
-rw-r--r--include/private/gui/LayerState.h (renamed from include/private/surfaceflinger/LayerState.h)3
-rw-r--r--include/private/gui/SharedBufferStack.h (renamed from include/private/surfaceflinger/SharedBufferStack.h)0
-rw-r--r--include/private/opengles/gl_context.h640
-rw-r--r--include/ui/ANativeObjectBase.h (renamed from include/ui/egl/android_natives.h)15
-rw-r--r--include/ui/EGLNativeSurface.h55
-rw-r--r--include/ui/EGLUtils.h53
-rw-r--r--include/ui/FramebufferNativeWindow.h8
-rw-r--r--include/ui/GraphicBuffer.h7
-rw-r--r--include/ui/PixelFormat.h13
-rw-r--r--include/utils/AndroidThreads.h136
-rw-r--r--include/utils/Condition.h134
-rw-r--r--include/utils/KeyedVector.h6
-rw-r--r--include/utils/Mutex.h137
-rw-r--r--include/utils/RWLock.h126
-rw-r--r--include/utils/Thread.h113
-rw-r--r--include/utils/ThreadDefs.h123
-rw-r--r--include/utils/Trace.h166
-rw-r--r--include/utils/threads.h554
-rw-r--r--libs/androidfw/Android.mk1
-rw-r--r--libs/androidfw/CursorWindow.cpp (renamed from libs/binder/CursorWindow.cpp)2
-rw-r--r--libs/binder/Android.mk1
-rw-r--r--libs/camera/Camera.cpp3
-rw-r--r--libs/camera/ICamera.cpp2
-rw-r--r--libs/gui/BufferQueue.cpp284
-rw-r--r--libs/gui/DisplayEventReceiver.cpp3
-rw-r--r--libs/gui/IGraphicBufferAlloc.cpp2
-rw-r--r--libs/gui/ISurface.cpp2
-rw-r--r--libs/gui/ISurfaceComposer.cpp10
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp6
-rw-r--r--libs/gui/LayerState.cpp4
-rw-r--r--libs/gui/Surface.cpp11
-rw-r--r--libs/gui/SurfaceComposerClient.cpp13
-rw-r--r--libs/gui/SurfaceTexture.cpp191
-rw-r--r--libs/gui/SurfaceTextureClient.cpp22
-rw-r--r--libs/gui/tests/SurfaceTexture_test.cpp6
-rw-r--r--libs/gui/tests/Surface_test.cpp6
-rw-r--r--libs/hwui/Debug.h2
-rw-r--r--libs/hwui/DisplayListRenderer.cpp40
-rw-r--r--libs/hwui/DisplayListRenderer.h4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp71
-rw-r--r--libs/hwui/OpenGLRenderer.h6
-rw-r--r--libs/hwui/PathCache.cpp5
-rw-r--r--libs/rs/Allocation.cpp471
-rw-r--r--libs/rs/Allocation.h126
-rw-r--r--libs/rs/Android.mk9
-rw-r--r--libs/rs/BaseObj.cpp67
-rw-r--r--libs/rs/BaseObj.h52
-rw-r--r--libs/rs/Element.cpp428
-rw-r--r--libs/rs/Element.h199
-rw-r--r--libs/rs/RenderScript.cpp164
-rw-r--r--libs/rs/RenderScript.h156
-rw-r--r--libs/rs/Script.cpp69
-rw-r--r--libs/rs/Script.h84
-rw-r--r--libs/rs/ScriptC.cpp (renamed from include/private/ui/android_natives_priv.h)19
-rw-r--r--libs/rs/ScriptC.h (renamed from services/audioflinger/AudioBufferProvider.cpp)24
-rw-r--r--libs/rs/Type.cpp160
-rw-r--r--libs/rs/Type.h99
-rw-r--r--libs/rs/driver/rsdBcc.cpp29
-rw-r--r--libs/rs/driver/rsdCore.h1
-rw-r--r--libs/rs/driver/rsdGL.cpp61
-rw-r--r--libs/rs/driver/rsdGL.h9
-rw-r--r--libs/rs/driver/rsdRuntimeStubs.cpp8
-rw-r--r--libs/rs/rsRuntime.h4
-rw-r--r--libs/rs/rsScript.cpp4
-rw-r--r--libs/rs/rsScript.h3
-rw-r--r--libs/rs/rsScriptC.cpp5
-rw-r--r--libs/rs/rsScriptC.h3
-rw-r--r--libs/rs/rsScriptC_Lib.cpp4
-rw-r--r--libs/rs/rsScriptC_LibGL.cpp18
-rw-r--r--libs/rs/tests/Android.mk30
-rw-r--r--libs/rs/tests/ScriptC_mono.cpp87
-rw-r--r--libs/rs/tests/ScriptC_mono.h (renamed from include/ui/android_native_buffer.h)14
-rw-r--r--libs/rs/tests/compute.cpp58
-rw-r--r--libs/surfaceflinger_client/Android.mk10
-rw-r--r--libs/ui/Android.mk6
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp22
-rw-r--r--libs/ui/GraphicBuffer.cpp17
-rw-r--r--libs/ui/PixelFormat.cpp5
-rw-r--r--libs/utils/Android.mk3
-rw-r--r--libs/utils/Trace.cpp47
-rw-r--r--media/java/android/media/MediaCodec.java210
-rw-r--r--media/java/android/media/MediaExtractor.java78
-rw-r--r--media/jni/Android.mk5
-rw-r--r--media/jni/android_media_MediaCodec.cpp552
-rw-r--r--media/jni/android_media_MediaCodec.h81
-rw-r--r--media/jni/android_media_MediaExtractor.cpp400
-rw-r--r--media/jni/android_media_MediaExtractor.h60
-rw-r--r--media/jni/android_media_MediaPlayer.cpp14
-rw-r--r--media/jni/android_media_MediaRecorder.cpp2
-rw-r--r--media/jni/android_media_Utils.cpp262
-rw-r--r--media/jni/android_media_Utils.h8
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp3
-rwxr-xr-xmedia/libeffects/preprocessing/PreProcessing.cpp15
-rw-r--r--media/libmedia/IMediaPlayer.cpp2
-rw-r--r--media/libmedia/IMediaRecorder.cpp2
-rw-r--r--media/libmedia/IOMX.cpp2
-rw-r--r--media/libmedia/mediaplayer.cpp2
-rw-r--r--media/libmedia/mediarecorder.cpp1
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp15
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp11
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp7
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.cpp6
-rw-r--r--media/libstagefright/ACodec.cpp1131
-rw-r--r--media/libstagefright/Android.mk73
-rw-r--r--media/libstagefright/AwesomePlayer.cpp2
-rwxr-xr-xmedia/libstagefright/CameraSource.cpp2
-rw-r--r--media/libstagefright/MPEG2TSWriter.cpp12
-rw-r--r--media/libstagefright/MediaCodec.cpp1179
-rw-r--r--media/libstagefright/NuMediaExtractor.cpp433
-rw-r--r--media/libstagefright/OMXClient.cpp4
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp3
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp5
-rw-r--r--media/libstagefright/codecs/aacenc/basic_op/basic_op.h157
-rw-r--r--media/libstagefright/codecs/aacenc/basic_op/oper_32b.h2
-rw-r--r--media/libstagefright/codecs/aacenc/basic_op/typedefs.h4
-rw-r--r--media/libstagefright/codecs/aacenc/inc/aacenc_core.h2
-rw-r--r--media/libstagefright/codecs/aacenc/inc/bitbuffer.h2
-rw-r--r--media/libstagefright/codecs/aacenc/inc/psy_configuration.h4
-rw-r--r--media/libstagefright/codecs/aacenc/src/aacenc_core.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/adj_thr.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/bitbuffer.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/dyn_bits.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/interface.c4
-rw-r--r--media/libstagefright/codecs/aacenc/src/psy_configuration.c4
-rw-r--r--media/libstagefright/codecs/aacenc/src/psy_main.c3
-rw-r--r--media/libstagefright/codecs/aacenc/src/qc_main.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/quantize.c4
-rw-r--r--media/libstagefright/codecs/aacenc/src/sf_estim.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/transform.c6
-rw-r--r--media/libstagefright/codecs/amrnb/common/include/az_lsp.h2
-rw-r--r--media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h2
-rw-r--r--media/libstagefright/codecs/amrnb/common/include/log2_norm.h2
-rw-r--r--media/libstagefright/codecs/amrnb/common/include/pow2.h2
-rw-r--r--media/libstagefright/codecs/amrnb/common/include/sqrt_l.h2
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp2
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp24
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp23
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/bytesused.cpp2
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp6
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp6
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp6
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp2
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp12
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp13
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp5
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/common/src/window_tab.cpp7
-rw-r--r--media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp5
-rw-r--r--media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp2
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp5
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp5
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp4
-rw-r--r--media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp3
-rw-r--r--media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h2
-rw-r--r--media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp3
-rw-r--r--media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp20
-rw-r--r--media/libstagefright/codecs/amrwb/src/isp_isf.cpp2
-rw-r--r--media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp6
-rw-r--r--media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp4
-rw-r--r--media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab4
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c2
-rw-r--r--media/libstagefright/colorconversion/SoftwareRenderer.cpp5
-rw-r--r--media/libstagefright/foundation/AMessage.cpp39
-rw-r--r--media/libstagefright/include/SoftwareRenderer.h2
-rw-r--r--media/libstagefright/rtsp/AAMRAssembler.cpp2
-rw-r--r--media/libstagefright/rtsp/AAVCAssembler.cpp2
-rw-r--r--media/libstagefright/rtsp/AH263Assembler.cpp2
-rw-r--r--media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp2
-rw-r--r--media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.cpp8
-rw-r--r--media/libstagefright/rtsp/ARTPSession.cpp6
-rw-r--r--media/libstagefright/rtsp/ARTSPConnection.cpp2
-rw-r--r--media/libstagefright/rtsp/ARawAudioAssembler.cpp2
-rw-r--r--media/libstagefright/rtsp/MyHandler.h13
-rw-r--r--media/libstagefright/tests/SurfaceMediaSource_test.cpp8
-rw-r--r--media/libstagefright/timedtext/Android.mk5
-rw-r--r--media/libstagefright/timedtext/TimedText3GPPSource.cpp (renamed from media/libstagefright/timedtext/TimedTextInBandSource.cpp)67
-rw-r--r--media/libstagefright/timedtext/TimedText3GPPSource.h (renamed from media/libstagefright/timedtext/TimedTextInBandSource.h)14
-rw-r--r--media/libstagefright/timedtext/TimedTextSource.cpp13
-rw-r--r--native/android/native_window.cpp2
-rw-r--r--opengl/libagl/TextureObjectManager.cpp2
-rw-r--r--opengl/libagl/context.h658
-rw-r--r--opengl/libagl/egl.cpp6
-rw-r--r--opengl/libagl/texture.cpp1
-rw-r--r--opengl/libs/EGL/eglApi.cpp5
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_api.cpp2431
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_fixup.cpp229
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_fixup.h2
-rwxr-xr-xopengl/libs/GLES_trace/tools/genapi.py17
-rw-r--r--opengl/tests/angeles/Android.mk9
-rw-r--r--opengl/tests/angeles/app-linux.cpp2
-rw-r--r--opengl/tests/angeles/gpustate.c39
-rw-r--r--opengl/tests/fillrate/Android.mk2
-rw-r--r--opengl/tests/fillrate/fillrate.cpp2
-rw-r--r--opengl/tests/filter/Android.mk2
-rw-r--r--opengl/tests/filter/filter.cpp2
-rw-r--r--opengl/tests/finish/Android.mk2
-rw-r--r--opengl/tests/finish/finish.cpp2
-rw-r--r--opengl/tests/gl2_basic/Android.mk2
-rw-r--r--opengl/tests/gl2_basic/gl2_basic.cpp2
-rw-r--r--opengl/tests/gl2_copyTexImage/Android.mk2
-rw-r--r--opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp2
-rw-r--r--opengl/tests/gl2_yuvtex/Android.mk2
-rw-r--r--opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp2
-rw-r--r--opengl/tests/gl_basic/Android.mk2
-rw-r--r--opengl/tests/gl_basic/gl_basic.cpp2
-rw-r--r--opengl/tests/gl_perf/Android.mk2
-rw-r--r--opengl/tests/gl_perf/gl2_perf.cpp2
-rw-r--r--opengl/tests/gl_yuvtex/Android.mk2
-rw-r--r--opengl/tests/gl_yuvtex/gl_yuvtex.cpp2
-rw-r--r--opengl/tests/hwc/hwcColorEquiv.cpp1
-rw-r--r--opengl/tests/hwc/hwcCommit.cpp1
-rw-r--r--opengl/tests/hwc/hwcRects.cpp1
-rw-r--r--opengl/tests/hwc/hwcStress.cpp1
-rw-r--r--opengl/tests/hwc/hwcTestLib.cpp2
-rw-r--r--opengl/tests/hwc/hwcTestLib.h1
-rw-r--r--opengl/tests/include/EGLUtils.h (renamed from libs/ui/EGLUtils.cpp)47
-rw-r--r--opengl/tests/include/glTestLib.h4
-rw-r--r--opengl/tests/lib/glTestLib.cpp2
-rw-r--r--opengl/tests/linetex/Android.mk2
-rw-r--r--opengl/tests/linetex/linetex.cpp2
-rw-r--r--opengl/tests/swapinterval/Android.mk2
-rw-r--r--opengl/tests/swapinterval/swapinterval.cpp2
-rw-r--r--opengl/tests/textures/Android.mk2
-rw-r--r--opengl/tests/textures/textures.cpp2
-rw-r--r--opengl/tests/tritex/Android.mk2
-rw-r--r--opengl/tests/tritex/tritex.cpp2
-rw-r--r--packages/SystemUI/res/values/colors.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java121
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java158
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java6
-rw-r--r--packages/VpnDialogs/res/layout/manage.xml4
-rw-r--r--packages/VpnDialogs/res/values/strings.xml2
-rw-r--r--packages/VpnDialogs/res/values/styles.xml1
-rw-r--r--packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java13
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java10
-rw-r--r--services/audioflinger/Android.mk1
-rw-r--r--services/audioflinger/AudioBufferProvider.h7
-rw-r--r--services/audioflinger/AudioFlinger.cpp234
-rw-r--r--services/audioflinger/AudioFlinger.h93
-rw-r--r--services/audioflinger/AudioMixer.cpp4
-rw-r--r--services/camera/libcameraservice/CameraHardwareInterface.h2
-rw-r--r--services/camera/libcameraservice/CameraService.cpp2
-rw-r--r--services/camera/tests/CameraServiceTest/CameraServiceTest.cpp1
-rw-r--r--services/input/SpriteController.h4
-rw-r--r--services/java/com/android/server/BootReceiver.java6
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java111
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java61
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java5
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java153
-rw-r--r--services/java/com/android/server/pm/Settings.java4
-rw-r--r--services/java/com/android/server/wm/DimAnimator.java4
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java7
-rw-r--r--services/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/jni/com_android_server_PowerManagerService.cpp3
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.cpp26
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.h2
-rw-r--r--services/surfaceflinger/Layer.cpp78
-rw-r--r--services/surfaceflinger/Layer.h8
-rw-r--r--services/surfaceflinger/LayerBase.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp22
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h6
-rw-r--r--services/surfaceflinger/tests/Transaction_test.cpp9
-rw-r--r--services/surfaceflinger/tests/resize/resize.cpp5
-rw-r--r--services/surfaceflinger/tests/screencap/screencap.cpp2
-rw-r--r--services/surfaceflinger/tests/surface/surface.cpp5
-rw-r--r--telephony/java/android/telephony/ServiceState.java152
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java10
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java18
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java4
-rw-r--r--telephony/java/com/android/internal/telephony/ServiceStateTracker.java6
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java57
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java26
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java6
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java24
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java12
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml9
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java31
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java100
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.pngbin0 -> 7529 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl10
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl10
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl4
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl4
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl4
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl2
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl2
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl2
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3dbin0 -> 29068 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java6
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java13
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java38
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java52
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java20
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java14
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java145
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java6
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java12
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java5
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java57
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs42
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs44
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java58
-rw-r--r--tools/aapt/XMLNode.cpp12
-rw-r--r--tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java191
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java4
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java3
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java13
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java11
510 files changed, 19953 insertions, 13230 deletions
diff --git a/api/current.txt b/api/current.txt
index d034b89c9d5c..137b6728edb1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3631,12 +3631,22 @@ package android.app {
field public static final int DEFAULT_VIBRATE = 2; // 0x2
field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
- field public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
+ field public static final deprecated int FLAG_HIGH_PRIORITY = 128; // 0x80
field public static final int FLAG_INSISTENT = 4; // 0x4
field public static final int FLAG_NO_CLEAR = 32; // 0x20
field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+ field public static final java.lang.String KIND_CALL = "android.call";
+ field public static final java.lang.String KIND_EMAIL = "android.email";
+ field public static final java.lang.String KIND_EVENT = "android.event";
+ field public static final java.lang.String KIND_MESSAGE = "android.message";
+ field public static final java.lang.String KIND_PROMO = "android.promo";
+ field public static final int PRIORITY_DEFAULT = 0; // 0x0
+ field public static final int PRIORITY_HIGH = 1; // 0x1
+ field public static final int PRIORITY_LOW = -1; // 0xffffffff
+ field public static final int PRIORITY_MAX = 2; // 0x2
+ field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final int STREAM_DEFAULT = -1; // 0xffffffff
field public int audioStreamType;
field public android.app.PendingIntent contentIntent;
@@ -3647,11 +3657,13 @@ package android.app {
field public android.app.PendingIntent fullScreenIntent;
field public int icon;
field public int iconLevel;
+ field public java.lang.String[] kind;
field public android.graphics.Bitmap largeIcon;
field public int ledARGB;
field public int ledOffMS;
field public int ledOnMS;
field public int number;
+ field public int priority;
field public android.net.Uri sound;
field public java.lang.CharSequence tickerText;
field public android.widget.RemoteViews tickerView;
@@ -3661,6 +3673,7 @@ package android.app {
public static class Notification.Builder {
ctor public Notification.Builder(android.content.Context);
+ method public android.app.Notification.Builder addKind(java.lang.String);
method public android.app.Notification getNotification();
method public android.app.Notification.Builder setAutoCancel(boolean);
method public android.app.Notification.Builder setContent(android.widget.RemoteViews);
@@ -3676,6 +3689,7 @@ package android.app {
method public android.app.Notification.Builder setNumber(int);
method public android.app.Notification.Builder setOngoing(boolean);
method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
+ method public android.app.Notification.Builder setPriority(int);
method public android.app.Notification.Builder setProgress(int, int, boolean);
method public android.app.Notification.Builder setSmallIcon(int);
method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -6181,6 +6195,8 @@ package android.content.pm {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
+ field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
field public android.content.pm.ActivityInfo[] activities;
field public android.content.pm.ApplicationInfo applicationInfo;
field public android.content.pm.ConfigurationInfo[] configPreferences;
@@ -6194,6 +6210,7 @@ package android.content.pm {
field public android.content.pm.ActivityInfo[] receivers;
field public android.content.pm.FeatureInfo[] reqFeatures;
field public java.lang.String[] requestedPermissions;
+ field public int[] requestedPermissionsFlags;
field public android.content.pm.ServiceInfo[] services;
field public java.lang.String sharedUserId;
field public int sharedUserLabel;
@@ -6416,6 +6433,10 @@ package android.content.pm {
method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int PROTECTION_DANGEROUS = 1; // 0x1
+ field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
+ field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
+ field public static final int PROTECTION_MASK_BASE = 15; // 0xf
+ field public static final int PROTECTION_MASK_FLAGS = 240; // 0xf0
field public static final int PROTECTION_NORMAL = 0; // 0x0
field public static final int PROTECTION_SIGNATURE = 2; // 0x2
field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
@@ -8615,14 +8636,14 @@ package android.graphics {
method public static void getPixelFormatInfo(int, android.graphics.PixelFormat);
field public static final int A_8 = 8; // 0x8
field public static final deprecated int JPEG = 256; // 0x100
- field public static final int LA_88 = 10; // 0xa
+ field public static final deprecated int LA_88 = 10; // 0xa
field public static final int L_8 = 9; // 0x9
field public static final int OPAQUE = -1; // 0xffffffff
- field public static final int RGBA_4444 = 7; // 0x7
- field public static final int RGBA_5551 = 6; // 0x6
+ field public static final deprecated int RGBA_4444 = 7; // 0x7
+ field public static final deprecated int RGBA_5551 = 6; // 0x6
field public static final int RGBA_8888 = 1; // 0x1
field public static final int RGBX_8888 = 2; // 0x2
- field public static final int RGB_332 = 11; // 0xb
+ field public static final deprecated int RGB_332 = 11; // 0xb
field public static final int RGB_565 = 4; // 0x4
field public static final int RGB_888 = 3; // 0x3
field public static final int TRANSLUCENT = -3; // 0xfffffffd
@@ -14884,7 +14905,7 @@ package android.os {
public class Looper {
method public void dump(android.util.Printer, java.lang.String);
- method public static synchronized android.os.Looper getMainLooper();
+ method public static android.os.Looper getMainLooper();
method public java.lang.Thread getThread();
method public static void loop();
method public static android.os.Looper myLooper();
@@ -16059,6 +16080,7 @@ package android.provider {
protected static abstract interface CalendarContract.RemindersColumns {
field public static final java.lang.String EVENT_ID = "event_id";
field public static final java.lang.String METHOD = "method";
+ field public static final int METHOD_ALARM = 4; // 0x4
field public static final int METHOD_ALERT = 1; // 0x1
field public static final int METHOD_DEFAULT = 0; // 0x0
field public static final int METHOD_EMAIL = 2; // 0x2
@@ -21921,12 +21943,14 @@ package android.view {
method public java.lang.Object getTag();
method public abstract java.lang.CharSequence getTitle();
method public abstract void invalidate();
+ method public boolean isTitleOptional();
method public abstract void setCustomView(android.view.View);
method public abstract void setSubtitle(java.lang.CharSequence);
method public abstract void setSubtitle(int);
method public void setTag(java.lang.Object);
method public abstract void setTitle(java.lang.CharSequence);
method public abstract void setTitle(int);
+ method public void setTitleOptionalHint(boolean);
}
public static abstract interface ActionMode.Callback {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 3545ace49179..0ab6aa38a47f 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -38,8 +38,8 @@
#include <ui/DisplayInfo.h>
#include <ui/FramebufferNativeWindow.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <core/SkBitmap.h>
#include <core/SkStream.h>
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index c85d72c1a998..62da82f134ba 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -23,9 +23,6 @@
#include <androidfw/AssetManager.h>
#include <utils/threads.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
#include <EGL/egl.h>
#include <GLES/gl.h>
@@ -33,7 +30,9 @@ class SkBitmap;
namespace android {
-class AssetManager;
+class Surface;
+class SurfaceComposerClient;
+class SurfaceControl;
// ---------------------------------------------------------------------------
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index ff809d369fb3..417e138b7041 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -25,8 +25,6 @@
#include <utils/Log.h>
#include <utils/threads.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-
#if defined(HAVE_PTHREADS)
# include <pthread.h>
# include <sys/resource.h>
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 16dc5178504a..ebe28db61191 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -88,11 +88,11 @@ static void dumpstate() {
if (screenshot_path[0]) {
ALOGI("taking screenshot\n");
- run_command(NULL, 5, "su", "root", "screenshot", screenshot_path, NULL);
+ run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL);
ALOGI("wrote screenshot: %s\n", screenshot_path);
}
- run_command("SYSTEM SETTINGS", 20, "su", "root", "sqlite3",
+ run_command("SYSTEM SETTINGS", 20, SU_PATH, "root", "sqlite3",
"/data/data/com.android.providers.settings/databases/settings.db",
"pragma user_version; select * from system; select * from secure;", NULL);
run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
@@ -118,7 +118,7 @@ static void dumpstate() {
run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
- run_command("NETWORK INTERFACES", 10, "su", "root", "netcfg", NULL);
+ run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
dump_file("NETWORK DEV INFO", "/proc/net/dev");
dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
@@ -133,28 +133,28 @@ static void dumpstate() {
run_command("ROUTE TABLE 61", 10, "ip", "route", "show", "table", "61", NULL);
run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "61", NULL);
dump_file("ARP CACHE", "/proc/net/arp");
- run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-nvx", NULL);
- run_command("IP6TABLES", 10, "su", "root", "ip6tables", "-L", "-nvx", NULL);
- run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", "-n", NULL);
- run_command("IPT6ABLE NAT", 10, "su", "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
+ run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
+ run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
+ run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-n", NULL);
+ run_command("IPT6ABLE NAT", 10, SU_PATH, "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
run_command("WIFI NETWORKS", 20,
- "su", "root", "wpa_cli", "list_networks", NULL);
+ SU_PATH, "root", "wpa_cli", "list_networks", NULL);
property_get("dhcp.wlan0.gateway", network, "");
if (network[0])
- run_command("PING GATEWAY", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+ run_command("PING GATEWAY", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
property_get("dhcp.wlan0.dns1", network, "");
if (network[0])
- run_command("PING DNS1", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+ run_command("PING DNS1", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
property_get("dhcp.wlan0.dns2", network, "");
if (network[0])
- run_command("PING DNS2", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+ run_command("PING DNS2", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
#ifdef FWDUMP_bcm4329
run_command("DUMP WIFI STATUS", 20,
- "su", "root", "dhdutil", "-i", "wlan0", "dump", NULL);
+ SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
run_command("DUMP WIFI INTERNAL COUNTERS", 20,
- "su", "root", "wlutil", "counters", NULL);
+ SU_PATH, "root", "wlutil", "counters", NULL);
#endif
char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
@@ -168,7 +168,7 @@ static void dumpstate() {
"vril-dump", NULL);
} else {
run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
- "su", "root", "vril-dump", NULL);
+ SU_PATH, "root", "vril-dump", NULL);
}
}
@@ -192,7 +192,7 @@ static void dumpstate() {
dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
- run_command("FILESYSTEMS & FREE SPACE", 10, "su", "root", "df", NULL);
+ run_command("FILESYSTEMS & FREE SPACE", 10, SU_PATH, "root", "df", NULL);
dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
@@ -218,7 +218,7 @@ static void dumpstate() {
dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
printf("\n");
- run_command("LIST OF OPEN FILES", 10, "su", "root", "lsof", NULL);
+ run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index b02db0b96e30..c1c2ad8a2207 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -21,6 +21,8 @@
#include <unistd.h>
#include <stdio.h>
+#define SU_PATH "/system/xbin/su"
+
/* prints the contents of a file */
int dump_file(const char *title, const char* path);
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 21526f9c1b61..0d5ab9019405 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -127,7 +127,7 @@ void do_showmap(int pid, const char *name) {
sprintf(title, "SHOW MAP %d (%s)", pid, name);
sprintf(arg, "%d", pid);
- run_command(title, 10, "su", "root", "showmap", arg, NULL);
+ run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
}
/* prints the contents of a file */
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f4578429bc61..ac5bffe85a48 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -126,6 +126,16 @@ public final class Pm {
return;
}
+ if ("grant".equals(op)) {
+ runGrantRevokePermission(true);
+ return;
+ }
+
+ if ("revoke".equals(op)) {
+ runGrantRevokePermission(false);
+ return;
+ }
+
if ("set-install-location".equals(op)) {
runSetInstallLocation();
return;
@@ -596,8 +606,9 @@ public final class Pm {
if (groups && groupName == null && pi.group != null) {
continue;
}
- if (pi.protectionLevel < startProtectionLevel
- || pi.protectionLevel > endProtectionLevel) {
+ final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+ if (base < startProtectionLevel
+ || base > endProtectionLevel) {
continue;
}
if (summary) {
@@ -627,22 +638,8 @@ public final class Pm {
+ loadText(pi, pi.descriptionRes,
pi.nonLocalizedDescription));
}
- String protLevel = "unknown";
- switch(pi.protectionLevel) {
- case PermissionInfo.PROTECTION_DANGEROUS:
- protLevel = "dangerous";
- break;
- case PermissionInfo.PROTECTION_NORMAL:
- protLevel = "normal";
- break;
- case PermissionInfo.PROTECTION_SIGNATURE:
- protLevel = "signature";
- break;
- case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
- protLevel = "signatureOrSystem";
- break;
- }
- System.out.println(prefix + " protectionLevel:" + protLevel);
+ System.out.println(prefix + " protectionLevel:"
+ + PermissionInfo.protectionToString(pi.protectionLevel));
}
}
}
@@ -1063,6 +1060,36 @@ public final class Pm {
}
}
+ private void runGrantRevokePermission(boolean grant) {
+ String pkg = nextArg();
+ if (pkg == null) {
+ System.err.println("Error: no package specified");
+ showUsage();
+ return;
+ }
+ String perm = nextArg();
+ if (perm == null) {
+ System.err.println("Error: no permission specified");
+ showUsage();
+ return;
+ }
+ try {
+ if (grant) {
+ mPm.grantPermission(pkg, perm);
+ } else {
+ mPm.revokePermission(pkg, perm);
+ }
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(PM_NOT_RUNNING_ERR);
+ } catch (IllegalArgumentException e) {
+ System.err.println("Bad argument: " + e.toString());
+ showUsage();
+ } catch (SecurityException e) {
+ System.err.println("Operation not allowed: " + e.toString());
+ }
+ }
+
/**
* Displays the package file for a package.
* @param pckg
@@ -1158,6 +1185,8 @@ public final class Pm {
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
System.err.println(" pm disable PACKAGE_OR_COMPONENT");
System.err.println(" pm disable-user PACKAGE_OR_COMPONENT");
+ System.err.println(" pm grant PACKAGE PERMISSION");
+ System.err.println(" pm revoke PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm create-profile USER_NAME");
@@ -1208,6 +1237,10 @@ public final class Pm {
System.err.println("pm enable, disable, disable-user: these commands change the enabled state");
System.err.println(" of a given package or component (written as \"package/class\").");
System.err.println("");
+ System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
+ System.err.println(" to applications. Only optional permissions the application has");
+ System.err.println(" declared can be granted or revoked.");
+ System.err.println("");
System.err.println("pm get-install-location: returns the current install location.");
System.err.println(" 0 [auto]: Let system decide the best location");
System.err.println(" 1 [internal]: Install on internal device storage");
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 90dfe76f7fa3..46e41e3d476e 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -24,7 +24,7 @@
#include <sys/mman.h>
#include <binder/IMemory.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
#include <SkImageEncoder.h>
#include <SkBitmap.h>
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 11e94e83796b..f26747b6ead4 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -147,4 +147,28 @@ LOCAL_MODULE:= sf2
include $(BUILD_EXECUTABLE)
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ codec.cpp \
+ SimplePlayer.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright liblog libutils libbinder libstagefright_foundation \
+ libmedia libgui libcutils libui
+
+LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
+ frameworks/base/media/libstagefright \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax
+
+LOCAL_CFLAGS += -Wno-multichar
+
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_MODULE:= codec
+
+include $(BUILD_EXECUTABLE)
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
new file mode 100644
index 000000000000..f269e8099a14
--- /dev/null
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -0,0 +1,646 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SimplePlayer"
+#include <utils/Log.h>
+
+#include "SimplePlayer.h"
+
+#include <gui/SurfaceTextureClient.h>
+#include <media/AudioTrack.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/NativeWindowWrapper.h>
+#include <media/stagefright/NuMediaExtractor.h>
+
+namespace android {
+
+SimplePlayer::SimplePlayer()
+ : mState(UNINITIALIZED),
+ mDoMoreStuffGeneration(0),
+ mStartTimeRealUs(-1ll) {
+}
+
+SimplePlayer::~SimplePlayer() {
+}
+
+// static
+status_t PostAndAwaitResponse(
+ const sp<AMessage> &msg, sp<AMessage> *response) {
+ status_t err = msg->postAndAwaitResponse(response);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (!(*response)->findInt32("err", &err)) {
+ err = OK;
+ }
+
+ return err;
+}
+status_t SimplePlayer::setDataSource(const char *path) {
+ sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
+ msg->setString("path", path);
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t SimplePlayer::setSurface(const sp<ISurfaceTexture> &surfaceTexture) {
+ sp<AMessage> msg = new AMessage(kWhatSetSurface, id());
+
+ sp<SurfaceTextureClient> surfaceTextureClient;
+ if (surfaceTexture != NULL) {
+ surfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
+ }
+
+ msg->setObject(
+ "native-window", new NativeWindowWrapper(surfaceTextureClient));
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t SimplePlayer::prepare() {
+ sp<AMessage> msg = new AMessage(kWhatPrepare, id());
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t SimplePlayer::start() {
+ sp<AMessage> msg = new AMessage(kWhatStart, id());
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t SimplePlayer::stop() {
+ sp<AMessage> msg = new AMessage(kWhatStop, id());
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t SimplePlayer::reset() {
+ sp<AMessage> msg = new AMessage(kWhatReset, id());
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+void SimplePlayer::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatSetDataSource:
+ {
+ status_t err;
+ if (mState != UNINITIALIZED) {
+ err = INVALID_OPERATION;
+ } else {
+ CHECK(msg->findString("path", &mPath));
+ mState = UNPREPARED;
+ }
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatSetSurface:
+ {
+ status_t err;
+ if (mState != UNPREPARED) {
+ err = INVALID_OPERATION;
+ } else {
+ sp<RefBase> obj;
+ CHECK(msg->findObject("native-window", &obj));
+
+ mNativeWindow = static_cast<NativeWindowWrapper *>(obj.get());
+
+ err = OK;
+ }
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatPrepare:
+ {
+ status_t err;
+ if (mState != UNPREPARED) {
+ err = INVALID_OPERATION;
+ } else {
+ err = onPrepare();
+
+ if (err == OK) {
+ mState = STOPPED;
+ }
+ }
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatStart:
+ {
+ status_t err = OK;
+
+ if (mState == UNPREPARED) {
+ err = onPrepare();
+
+ if (err == OK) {
+ mState = STOPPED;
+ }
+ }
+
+ if (err == OK) {
+ if (mState != STOPPED) {
+ err = INVALID_OPERATION;
+ } else {
+ err = onStart();
+
+ if (err == OK) {
+ mState = STARTED;
+ }
+ }
+ }
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatStop:
+ {
+ status_t err;
+
+ if (mState != STARTED) {
+ err = INVALID_OPERATION;
+ } else {
+ err = onStop();
+
+ if (err == OK) {
+ mState = STOPPED;
+ }
+ }
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatReset:
+ {
+ status_t err = OK;
+
+ if (mState == STARTED) {
+ CHECK_EQ(onStop(), (status_t)OK);
+ mState = STOPPED;
+ }
+
+ if (mState == STOPPED) {
+ err = onReset();
+ mState = UNINITIALIZED;
+ }
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatDoMoreStuff:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != mDoMoreStuffGeneration) {
+ break;
+ }
+
+ status_t err = onDoMoreStuff();
+
+ if (err == OK) {
+ msg->post(10000ll);
+ }
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+}
+
+status_t SimplePlayer::onPrepare() {
+ CHECK_EQ(mState, UNPREPARED);
+
+ mExtractor = new NuMediaExtractor;
+
+ status_t err = mExtractor->setDataSource(mPath.c_str());
+
+ if (err != OK) {
+ mExtractor.clear();
+ return err;
+ }
+
+ if (mCodecLooper == NULL) {
+ mCodecLooper = new ALooper;
+ mCodecLooper->start();
+ }
+
+ bool haveAudio = false;
+ bool haveVideo = false;
+ for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
+ sp<AMessage> format;
+ status_t err = mExtractor->getTrackFormat(i, &format);
+ CHECK_EQ(err, (status_t)OK);
+
+ AString mime;
+ CHECK(format->findString("mime", &mime));
+
+ if (!haveAudio && !strncasecmp(mime.c_str(), "audio/", 6)) {
+ haveAudio = true;
+ } else if (!haveVideo && !strncasecmp(mime.c_str(), "video/", 6)) {
+ haveVideo = true;
+ } else {
+ continue;
+ }
+
+ err = mExtractor->selectTrack(i);
+ CHECK_EQ(err, (status_t)OK);
+
+ CodecState *state =
+ &mStateByTrackIndex.editValueAt(
+ mStateByTrackIndex.add(i, CodecState()));
+
+ state->mNumFramesWritten = 0;
+ state->mCodec = MediaCodec::CreateByType(
+ mCodecLooper, mime.c_str(), false /* encoder */);
+
+ CHECK(state->mCodec != NULL);
+
+ err = state->mCodec->configure(
+ format, mNativeWindow->getSurfaceTextureClient(),
+ 0 /* flags */);
+
+ CHECK_EQ(err, (status_t)OK);
+
+ size_t j = 0;
+ sp<ABuffer> buffer;
+ while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
+ state->mCSD.push_back(buffer);
+
+ ++j;
+ }
+ }
+
+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
+
+ status_t err = state->mCodec->start();
+ CHECK_EQ(err, (status_t)OK);
+
+ err = state->mCodec->getInputBuffers(&state->mBuffers[0]);
+ CHECK_EQ(err, (status_t)OK);
+
+ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
+ CHECK_EQ(err, (status_t)OK);
+
+ for (size_t j = 0; j < state->mCSD.size(); ++j) {
+ const sp<ABuffer> &srcBuffer = state->mCSD.itemAt(j);
+
+ size_t index;
+ err = state->mCodec->dequeueInputBuffer(&index, -1ll);
+ CHECK_EQ(err, (status_t)OK);
+
+ const sp<ABuffer> &dstBuffer = state->mBuffers[0].itemAt(index);
+
+ CHECK_LE(srcBuffer->size(), dstBuffer->capacity());
+ dstBuffer->setRange(0, srcBuffer->size());
+ memcpy(dstBuffer->data(), srcBuffer->data(), srcBuffer->size());
+
+ err = state->mCodec->queueInputBuffer(
+ index,
+ 0,
+ dstBuffer->size(),
+ 0ll,
+ MediaCodec::BUFFER_FLAG_CODECCONFIG);
+ CHECK_EQ(err, (status_t)OK);
+ }
+ }
+
+ return OK;
+}
+
+status_t SimplePlayer::onStart() {
+ CHECK_EQ(mState, STOPPED);
+
+ mStartTimeRealUs = -1ll;
+
+ sp<AMessage> msg = new AMessage(kWhatDoMoreStuff, id());
+ msg->setInt32("generation", ++mDoMoreStuffGeneration);
+ msg->post();
+
+ return OK;
+}
+
+status_t SimplePlayer::onStop() {
+ CHECK_EQ(mState, STARTED);
+
+ ++mDoMoreStuffGeneration;
+
+ return OK;
+}
+
+status_t SimplePlayer::onReset() {
+ CHECK_EQ(mState, STOPPED);
+
+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
+
+ CHECK_EQ(state->mCodec->stop(), (status_t)OK);
+ }
+
+ mStartTimeRealUs = -1ll;
+
+ mStateByTrackIndex.clear();
+ mCodecLooper.clear();
+ mExtractor.clear();
+ mNativeWindow.clear();
+ mPath.clear();
+
+ return OK;
+}
+
+status_t SimplePlayer::onDoMoreStuff() {
+ ALOGV("onDoMoreStuff");
+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
+
+ status_t err;
+ do {
+ size_t index;
+ err = state->mCodec->dequeueInputBuffer(&index);
+
+ if (err == OK) {
+ ALOGV("dequeued input buffer on track %d",
+ mStateByTrackIndex.keyAt(i));
+
+ state->mAvailInputBufferIndices.push_back(index);
+ } else {
+ ALOGV("dequeueInputBuffer on track %d returned %d",
+ mStateByTrackIndex.keyAt(i), err);
+ }
+ } while (err == OK);
+
+ do {
+ BufferInfo info;
+ err = state->mCodec->dequeueOutputBuffer(
+ &info.mIndex,
+ &info.mOffset,
+ &info.mSize,
+ &info.mPresentationTimeUs,
+ &info.mFlags);
+
+ if (err == OK) {
+ ALOGV("dequeued output buffer on track %d",
+ mStateByTrackIndex.keyAt(i));
+
+ state->mAvailOutputBufferInfos.push_back(info);
+ } else if (err == INFO_FORMAT_CHANGED) {
+ err = onOutputFormatChanged(mStateByTrackIndex.keyAt(i), state);
+ CHECK_EQ(err, (status_t)OK);
+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
+ err = state->mCodec->getOutputBuffers(&state->mBuffers[1]);
+ CHECK_EQ(err, (status_t)OK);
+ } else {
+ ALOGV("dequeueOutputBuffer on track %d returned %d",
+ mStateByTrackIndex.keyAt(i), err);
+ }
+ } while (err == OK
+ || err == INFO_FORMAT_CHANGED
+ || err == INFO_OUTPUT_BUFFERS_CHANGED);
+ }
+
+ for (;;) {
+ size_t trackIndex;
+ status_t err = mExtractor->getSampleTrackIndex(&trackIndex);
+
+ if (err != OK) {
+ ALOGI("encountered input EOS.");
+ break;
+ } else {
+ CodecState *state = &mStateByTrackIndex.editValueFor(trackIndex);
+
+ if (state->mAvailInputBufferIndices.empty()) {
+ break;
+ }
+
+ size_t index = *state->mAvailInputBufferIndices.begin();
+ state->mAvailInputBufferIndices.erase(
+ state->mAvailInputBufferIndices.begin());
+
+ const sp<ABuffer> &dstBuffer =
+ state->mBuffers[0].itemAt(index);
+
+ err = mExtractor->readSampleData(dstBuffer);
+ CHECK_EQ(err, (status_t)OK);
+
+ int64_t timeUs;
+ CHECK_EQ(mExtractor->getSampleTime(&timeUs), (status_t)OK);
+
+ err = state->mCodec->queueInputBuffer(
+ index,
+ dstBuffer->offset(),
+ dstBuffer->size(),
+ timeUs,
+ 0);
+ CHECK_EQ(err, (status_t)OK);
+
+ ALOGV("enqueued input data on track %d", trackIndex);
+
+ err = mExtractor->advance();
+ CHECK_EQ(err, (status_t)OK);
+ }
+ }
+
+ int64_t nowUs = ALooper::GetNowUs();
+
+ if (mStartTimeRealUs < 0ll) {
+ mStartTimeRealUs = nowUs + 1000000ll;
+ }
+
+ for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
+ CodecState *state = &mStateByTrackIndex.editValueAt(i);
+
+ while (!state->mAvailOutputBufferInfos.empty()) {
+ BufferInfo *info = &*state->mAvailOutputBufferInfos.begin();
+
+ int64_t whenRealUs = info->mPresentationTimeUs + mStartTimeRealUs;
+ int64_t lateByUs = nowUs - whenRealUs;
+
+ if (lateByUs > -10000ll) {
+ bool release = true;
+
+ if (lateByUs > 30000ll) {
+ ALOGI("track %d buffer late by %lld us, dropping.",
+ mStateByTrackIndex.keyAt(i), lateByUs);
+ state->mCodec->releaseOutputBuffer(info->mIndex);
+ } else {
+ if (state->mAudioTrack != NULL) {
+ const sp<ABuffer> &srcBuffer =
+ state->mBuffers[1].itemAt(info->mIndex);
+
+ renderAudio(state, info, srcBuffer);
+
+ if (info->mSize > 0) {
+ release = false;
+ }
+ }
+
+ if (release) {
+ state->mCodec->renderOutputBufferAndRelease(
+ info->mIndex);
+ }
+ }
+
+ if (release) {
+ state->mAvailOutputBufferInfos.erase(
+ state->mAvailOutputBufferInfos.begin());
+
+ info = NULL;
+ } else {
+ break;
+ }
+ } else {
+ ALOGV("track %d buffer early by %lld us.",
+ mStateByTrackIndex.keyAt(i), -lateByUs);
+ break;
+ }
+ }
+ }
+
+ return OK;
+}
+
+status_t SimplePlayer::onOutputFormatChanged(
+ size_t trackIndex, CodecState *state) {
+ sp<AMessage> format;
+ status_t err = state->mCodec->getOutputFormat(&format);
+
+ if (err != OK) {
+ return err;
+ }
+
+ AString mime;
+ CHECK(format->findString("mime", &mime));
+
+ if (!strncasecmp(mime.c_str(), "audio/", 6)) {
+ int32_t channelCount;
+ int32_t sampleRate;
+ CHECK(format->findInt32("channel-count", &channelCount));
+ CHECK(format->findInt32("sample-rate", &sampleRate));
+
+ state->mAudioTrack = new AudioTrack(
+ AUDIO_STREAM_MUSIC,
+ sampleRate,
+ AUDIO_FORMAT_PCM_16_BIT,
+ (channelCount == 1)
+ ? AUDIO_CHANNEL_OUT_MONO : AUDIO_CHANNEL_OUT_STEREO,
+ 0);
+
+ state->mNumFramesWritten = 0;
+ }
+
+ return OK;
+}
+
+void SimplePlayer::renderAudio(
+ CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer) {
+ CHECK(state->mAudioTrack != NULL);
+
+ if (state->mAudioTrack->stopped()) {
+ state->mAudioTrack->start();
+ }
+
+ uint32_t numFramesPlayed;
+ CHECK_EQ(state->mAudioTrack->getPosition(&numFramesPlayed), (status_t)OK);
+
+ uint32_t numFramesAvailableToWrite =
+ state->mAudioTrack->frameCount()
+ - (state->mNumFramesWritten - numFramesPlayed);
+
+ size_t numBytesAvailableToWrite =
+ numFramesAvailableToWrite * state->mAudioTrack->frameSize();
+
+ size_t copy = info->mSize;
+ if (copy > numBytesAvailableToWrite) {
+ copy = numBytesAvailableToWrite;
+ }
+
+ if (copy == 0) {
+ return;
+ }
+
+ int64_t startTimeUs = ALooper::GetNowUs();
+
+ ssize_t nbytes = state->mAudioTrack->write(
+ buffer->base() + info->mOffset, copy);
+
+ CHECK_EQ(nbytes, (ssize_t)copy);
+
+ int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+ uint32_t numFramesWritten = nbytes / state->mAudioTrack->frameSize();
+
+ if (delayUs > 2000ll) {
+ ALOGW("AudioTrack::write took %lld us, numFramesAvailableToWrite=%u, "
+ "numFramesWritten=%u",
+ delayUs, numFramesAvailableToWrite, numFramesWritten);
+ }
+
+ info->mOffset += nbytes;
+ info->mSize -= nbytes;
+
+ state->mNumFramesWritten += numFramesWritten;
+}
+
+} // namespace android
diff --git a/cmds/stagefright/SimplePlayer.h b/cmds/stagefright/SimplePlayer.h
new file mode 100644
index 000000000000..2548252304c2
--- /dev/null
+++ b/cmds/stagefright/SimplePlayer.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+
+struct ABuffer;
+struct ALooper;
+struct AudioTrack;
+struct ISurfaceTexture;
+struct MediaCodec;
+struct NativeWindowWrapper;
+struct NuMediaExtractor;
+
+struct SimplePlayer : public AHandler {
+ SimplePlayer();
+
+ status_t setDataSource(const char *path);
+ status_t setSurface(const sp<ISurfaceTexture> &surfaceTexture);
+ status_t prepare();
+ status_t start();
+ status_t stop();
+ status_t reset();
+
+protected:
+ virtual ~SimplePlayer();
+
+ virtual void onMessageReceived(const sp<AMessage> &msg);
+
+private:
+ enum State {
+ UNINITIALIZED,
+ UNPREPARED,
+ STOPPED,
+ STARTED
+ };
+
+ enum {
+ kWhatSetDataSource,
+ kWhatSetSurface,
+ kWhatPrepare,
+ kWhatStart,
+ kWhatStop,
+ kWhatReset,
+ kWhatDoMoreStuff,
+ };
+
+ struct BufferInfo {
+ size_t mIndex;
+ size_t mOffset;
+ size_t mSize;
+ int64_t mPresentationTimeUs;
+ uint32_t mFlags;
+ };
+
+ struct CodecState
+ {
+ sp<MediaCodec> mCodec;
+ Vector<sp<ABuffer> > mCSD;
+ Vector<sp<ABuffer> > mBuffers[2];
+
+ List<size_t> mAvailInputBufferIndices;
+ List<BufferInfo> mAvailOutputBufferInfos;
+
+ sp<AudioTrack> mAudioTrack;
+ uint32_t mNumFramesWritten;
+ };
+
+ State mState;
+ AString mPath;
+ sp<NativeWindowWrapper> mNativeWindow;
+
+ sp<NuMediaExtractor> mExtractor;
+ sp<ALooper> mCodecLooper;
+ KeyedVector<size_t, CodecState> mStateByTrackIndex;
+ int32_t mDoMoreStuffGeneration;
+
+ int64_t mStartTimeRealUs;
+
+ status_t onPrepare();
+ status_t onStart();
+ status_t onStop();
+ status_t onReset();
+ status_t onDoMoreStuff();
+ status_t onOutputFormatChanged(size_t trackIndex, CodecState *state);
+
+ void renderAudio(
+ CodecState *state, BufferInfo *info, const sp<ABuffer> &buffer);
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimplePlayer);
+};
+
+} // namespace android
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
new file mode 100644
index 000000000000..b8501907e3b7
--- /dev/null
+++ b/cmds/stagefright/codec.cpp
@@ -0,0 +1,408 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "codec"
+#include <utils/Log.h>
+
+#include "SimplePlayer.h"
+
+#include <binder/ProcessState.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/NuMediaExtractor.h>
+#include <gui/SurfaceComposerClient.h>
+
+static void usage(const char *me) {
+ fprintf(stderr, "usage: %s [-a] use audio\n"
+ "\t\t[-v] use video\n"
+ "\t\t[-p] playback\n", me);
+
+ exit(1);
+}
+
+namespace android {
+
+struct CodecState {
+ sp<MediaCodec> mCodec;
+ Vector<sp<ABuffer> > mCSD;
+ size_t mCSDIndex;
+ Vector<sp<ABuffer> > mInBuffers;
+ Vector<sp<ABuffer> > mOutBuffers;
+ bool mSawOutputEOS;
+};
+
+} // namespace android
+
+static int decode(
+ const android::sp<android::ALooper> &looper,
+ const char *path,
+ bool useAudio,
+ bool useVideo) {
+ using namespace android;
+
+ sp<NuMediaExtractor> extractor = new NuMediaExtractor;
+ if (extractor->setDataSource(path) != OK) {
+ fprintf(stderr, "unable to instantiate extractor.\n");
+ return 1;
+ }
+
+ KeyedVector<size_t, CodecState> stateByTrack;
+
+ bool haveAudio = false;
+ bool haveVideo = false;
+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ sp<AMessage> format;
+ status_t err = extractor->getTrackFormat(i, &format);
+ CHECK_EQ(err, (status_t)OK);
+
+ AString mime;
+ CHECK(format->findString("mime", &mime));
+
+ if (useAudio && !haveAudio
+ && !strncasecmp(mime.c_str(), "audio/", 6)) {
+ haveAudio = true;
+ } else if (useVideo && !haveVideo
+ && !strncasecmp(mime.c_str(), "video/", 6)) {
+ haveVideo = true;
+ } else {
+ continue;
+ }
+
+ ALOGV("selecting track %d", i);
+
+ err = extractor->selectTrack(i);
+ CHECK_EQ(err, (status_t)OK);
+
+ CodecState *state =
+ &stateByTrack.editValueAt(stateByTrack.add(i, CodecState()));
+
+ state->mCodec = MediaCodec::CreateByType(
+ looper, mime.c_str(), false /* encoder */);
+
+ CHECK(state->mCodec != NULL);
+
+ err = state->mCodec->configure(
+ format, NULL /* surfaceTexture */, 0 /* flags */);
+
+ CHECK_EQ(err, (status_t)OK);
+
+ size_t j = 0;
+ sp<ABuffer> buffer;
+ while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
+ state->mCSD.push_back(buffer);
+
+ ++j;
+ }
+
+ state->mCSDIndex = 0;
+ state->mSawOutputEOS = false;
+
+ ALOGV("got %d pieces of codec specific data.", state->mCSD.size());
+ }
+
+ CHECK(!stateByTrack.isEmpty());
+
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+
+ sp<MediaCodec> codec = state->mCodec;
+
+ CHECK_EQ((status_t)OK, codec->start());
+
+ CHECK_EQ((status_t)OK, codec->getInputBuffers(&state->mInBuffers));
+ CHECK_EQ((status_t)OK, codec->getOutputBuffers(&state->mOutBuffers));
+
+ ALOGV("got %d input and %d output buffers",
+ state->mInBuffers.size(), state->mOutBuffers.size());
+
+ while (state->mCSDIndex < state->mCSD.size()) {
+ size_t index;
+ status_t err = codec->dequeueInputBuffer(&index);
+
+ if (err == -EAGAIN) {
+ usleep(10000);
+ continue;
+ }
+
+ CHECK_EQ(err, (status_t)OK);
+
+ const sp<ABuffer> &srcBuffer =
+ state->mCSD.itemAt(state->mCSDIndex++);
+
+ const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
+
+ memcpy(buffer->data(), srcBuffer->data(), srcBuffer->size());
+
+ err = codec->queueInputBuffer(
+ index,
+ 0 /* offset */,
+ srcBuffer->size(),
+ 0ll /* timeUs */,
+ MediaCodec::BUFFER_FLAG_CODECCONFIG);
+
+ CHECK_EQ(err, (status_t)OK);
+ }
+ }
+
+ bool sawInputEOS = false;
+
+ for (;;) {
+ if (!sawInputEOS) {
+ size_t trackIndex;
+ status_t err = extractor->getSampleTrackIndex(&trackIndex);
+
+ if (err != OK) {
+ ALOGV("signalling EOS.");
+
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+
+ for (;;) {
+ size_t index;
+ err = state->mCodec->dequeueInputBuffer(&index);
+
+ if (err == -EAGAIN) {
+ continue;
+ }
+
+ CHECK_EQ(err, (status_t)OK);
+
+ err = state->mCodec->queueInputBuffer(
+ index,
+ 0 /* offset */,
+ 0 /* size */,
+ 0ll /* timeUs */,
+ MediaCodec::BUFFER_FLAG_EOS);
+
+ CHECK_EQ(err, (status_t)OK);
+ break;
+ }
+ }
+
+ sawInputEOS = true;
+ } else {
+ CodecState *state = &stateByTrack.editValueFor(trackIndex);
+
+ size_t index;
+ err = state->mCodec->dequeueInputBuffer(&index);
+
+ if (err == OK) {
+ ALOGV("filling input buffer %d", index);
+
+ const sp<ABuffer> &buffer = state->mInBuffers.itemAt(index);
+
+ err = extractor->readSampleData(buffer);
+ CHECK_EQ(err, (status_t)OK);
+
+ int64_t timeUs;
+ err = extractor->getSampleTime(&timeUs);
+ CHECK_EQ(err, (status_t)OK);
+
+ err = state->mCodec->queueInputBuffer(
+ index,
+ 0 /* offset */,
+ buffer->size(),
+ timeUs,
+ 0 /* flags */);
+
+ CHECK_EQ(err, (status_t)OK);
+
+ extractor->advance();
+ } else {
+ CHECK_EQ(err, -EAGAIN);
+ }
+ }
+ }
+
+ bool sawOutputEOSOnAllTracks = true;
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+ if (!state->mSawOutputEOS) {
+ sawOutputEOSOnAllTracks = false;
+ break;
+ }
+ }
+
+ if (sawOutputEOSOnAllTracks) {
+ break;
+ }
+
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+
+ if (state->mSawOutputEOS) {
+ continue;
+ }
+
+ size_t index;
+ size_t offset;
+ size_t size;
+ int64_t presentationTimeUs;
+ uint32_t flags;
+ status_t err = state->mCodec->dequeueOutputBuffer(
+ &index, &offset, &size, &presentationTimeUs, &flags,
+ 10000ll);
+
+ if (err == OK) {
+ ALOGV("draining output buffer %d, time = %lld us",
+ index, presentationTimeUs);
+
+ err = state->mCodec->releaseOutputBuffer(index);
+ CHECK_EQ(err, (status_t)OK);
+
+ if (flags & MediaCodec::BUFFER_FLAG_EOS) {
+ ALOGV("reached EOS on output.");
+
+ state->mSawOutputEOS = true;
+ }
+ } else if (err == INFO_OUTPUT_BUFFERS_CHANGED) {
+ ALOGV("INFO_OUTPUT_BUFFERS_CHANGED");
+ CHECK_EQ((status_t)OK,
+ state->mCodec->getOutputBuffers(&state->mOutBuffers));
+
+ ALOGV("got %d output buffers", state->mOutBuffers.size());
+ } else if (err == INFO_FORMAT_CHANGED) {
+ sp<AMessage> format;
+ CHECK_EQ((status_t)OK, state->mCodec->getOutputFormat(&format));
+
+ ALOGV("INFO_FORMAT_CHANGED: %s", format->debugString().c_str());
+ } else {
+ CHECK_EQ(err, -EAGAIN);
+ }
+ }
+ }
+
+ for (size_t i = 0; i < stateByTrack.size(); ++i) {
+ CodecState *state = &stateByTrack.editValueAt(i);
+
+ CHECK_EQ((status_t)OK, state->mCodec->stop());
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ using namespace android;
+
+ const char *me = argv[0];
+
+ bool useAudio = false;
+ bool useVideo = false;
+ bool playback = false;
+
+ int res;
+ while ((res = getopt(argc, argv, "havp")) >= 0) {
+ switch (res) {
+ case 'a':
+ {
+ useAudio = true;
+ break;
+ }
+
+ case 'v':
+ {
+ useVideo = true;
+ break;
+ }
+
+ case 'p':
+ {
+ playback = true;
+ break;
+ }
+
+ case '?':
+ case 'h':
+ default:
+ {
+ usage(me);
+ }
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ usage(me);
+ }
+
+ if (!useAudio && !useVideo) {
+ useAudio = useVideo = true;
+ }
+
+ ProcessState::self()->startThreadPool();
+
+ DataSource::RegisterDefaultSniffers();
+
+ sp<ALooper> looper = new ALooper;
+ looper->start();
+
+ if (playback) {
+ sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
+ CHECK_EQ(composerClient->initCheck(), (status_t)OK);
+
+ ssize_t displayWidth = composerClient->getDisplayWidth(0);
+ ssize_t displayHeight = composerClient->getDisplayHeight(0);
+
+ ALOGV("display is %ld x %ld\n", displayWidth, displayHeight);
+
+ sp<SurfaceControl> control =
+ composerClient->createSurface(
+ String8("A Surface"),
+ 0,
+ displayWidth,
+ displayHeight,
+ PIXEL_FORMAT_RGB_565,
+ 0);
+
+ CHECK(control != NULL);
+ CHECK(control->isValid());
+
+ SurfaceComposerClient::openGlobalTransaction();
+ CHECK_EQ(control->setLayer(INT_MAX), (status_t)OK);
+ CHECK_EQ(control->show(), (status_t)OK);
+ SurfaceComposerClient::closeGlobalTransaction();
+
+ sp<Surface> surface = control->getSurface();
+ CHECK(surface != NULL);
+
+ sp<SimplePlayer> player = new SimplePlayer;
+ looper->registerHandler(player);
+
+ player->setDataSource(argv[0]);
+ player->setSurface(surface->getSurfaceTexture());
+ player->start();
+ sleep(60);
+ player->stop();
+ player->reset();
+
+ composerClient->dispose();
+ } else {
+ decode(looper, argv[0], useAudio, useVideo);
+ }
+
+ looper->stop();
+
+ return 0;
+}
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index ae80f8804992..1d28793474bd 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -32,8 +32,7 @@
#include <media/stagefright/NativeWindowWrapper.h>
#include <media/stagefright/Utils.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
#include "include/ESDS.h"
@@ -198,9 +197,7 @@ protected:
(new AMessage(kWhatSeek, id()))->post(5000000ll);
} else if (what == ACodec::kWhatOutputFormatChanged) {
- } else {
- CHECK_EQ(what, (int32_t)ACodec::kWhatShutdownCompleted);
-
+ } else if (what == ACodec::kWhatShutdownCompleted) {
mDecodeLooper->unregisterHandler(mCodec->id());
if (mDecodeLooper != looper()) {
@@ -360,7 +357,7 @@ private:
buffer->meta()->setInt32("csd", true);
mCSD.push(buffer);
- msg->setObject("csd", buffer);
+ msg->setBuffer("csd", buffer);
} else if (meta->findData(kKeyESDS, &type, &data, &size)) {
ESDS esds((const char *)data, size);
CHECK_EQ(esds.InitCheck(), (status_t)OK);
@@ -410,9 +407,8 @@ private:
return;
}
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
- sp<ABuffer> outBuffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> outBuffer;
+ CHECK(msg->findBuffer("buffer", &outBuffer));
if (mCSDIndex < mCSD.size()) {
outBuffer = mCSD.editItemAt(mCSDIndex++);
@@ -511,15 +507,14 @@ private:
}
}
- reply->setObject("buffer", outBuffer);
+ reply->setBuffer("buffer", outBuffer);
reply->post();
}
void onDrainThisBuffer(const sp<AMessage> &msg) {
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
mTotalBytesReceived += buffer->size();
sp<AMessage> reply;
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 7cb8f62e62f3..dab2e0f2d880 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -55,9 +55,7 @@
#include <fcntl.h>
#include <gui/SurfaceTextureClient.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
using namespace android;
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 0d6c738292da..efa14455cade 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -32,8 +32,7 @@
#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
#include <fcntl.h>
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 882dd6bd5503..8d17325fe065 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -42,11 +42,12 @@ interface IAccessibilityServiceConnection {
* @param interactionId The id of the interaction for matching with the callback result.
* @param callback Callback which to receive the result.
* @param threadId The id of the calling thread.
+ * @param prefetchFlags flags to guide prefetching.
* @return The current window scale, where zero means a failure.
*/
float findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
long accessibilityNodeId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback, long threadId);
+ IAccessibilityInteractionConnectionCallback callback, long threadId, int prefetchFlags);
/**
* Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by View text.
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index 334981a10d19..a898c3f6ae55 100644
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
@@ -57,6 +57,11 @@ public class UiTestAutomationBridge {
public static final int UNDEFINED = -1;
+ private static final int FIND_ACCESSIBILITY_NODE_INFO_PREFETCH_FLAGS =
+ AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS
+ | AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS
+ | AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS;
+
private final Object mLock = new Object();
private volatile int mConnectionId = AccessibilityInteractionClient.NO_ID;
@@ -69,6 +74,8 @@ public class UiTestAutomationBridge {
private volatile boolean mUnprocessedEventAvailable;
+ private HandlerThread mHandlerThread;
+
/**
* Gets the last received {@link AccessibilityEvent}.
*
@@ -121,9 +128,10 @@ public class UiTestAutomationBridge {
// is needed for making sure the binder calls are interleaved
// with check for the expected event and also to make sure the
// binder threads are allowed to proceed in the received order.
- HandlerThread handlerThread = new HandlerThread("UiTestAutomationBridge");
- handlerThread.start();
- Looper looper = handlerThread.getLooper();
+ mHandlerThread = new HandlerThread("UiTestAutomationBridge");
+ mHandlerThread.setDaemon(true);
+ mHandlerThread.start();
+ Looper looper = mHandlerThread.getLooper();
mListener = new IEventListenerWrapper(null, looper, new Callbacks() {
@Override
@@ -212,6 +220,8 @@ public class UiTestAutomationBridge {
throw new IllegalStateException("Already disconnected.");
}
+ mHandlerThread.quit();
+
IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
@@ -351,13 +361,15 @@ public class UiTestAutomationBridge {
ensureValidConnection(connectionId);
return AccessibilityInteractionClient.getInstance()
.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
- accessibilityWindowId, accessibilityNodeId);
+ accessibilityWindowId, accessibilityNodeId,
+ FIND_ACCESSIBILITY_NODE_INFO_PREFETCH_FLAGS);
}
/**
* Finds an {@link AccessibilityNodeInfo} by View id in the active
* window. The search is performed from the root node.
*
+ * @param viewId The id of a View.
* @return The current window scale, where zero means a failure.
*/
public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int viewId) {
@@ -373,6 +385,7 @@ public class UiTestAutomationBridge {
* {@link #ACTIVE_WINDOW_ID} to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
* where to start the search. Use {@link #ROOT_NODE_ID} to start from the root.
+ * @param viewId The id of a View.
* @return The current window scale, where zero means a failure.
*/
public AccessibilityNodeInfo findAccessibilityNodeInfoByViewId(int accessibilityWindowId,
@@ -460,7 +473,7 @@ public class UiTestAutomationBridge {
ensureValidConnection(connectionId);
return AccessibilityInteractionClient.getInstance()
.findAccessibilityNodeInfoByAccessibilityId(connectionId, ACTIVE_WINDOW_ID,
- ROOT_NODE_ID);
+ ROOT_NODE_ID, AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
}
private void ensureValidConnection(int connectionId) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index bf632a9b0caa..5d1d4618e32c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -78,6 +78,7 @@ import android.view.ViewRootImpl;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
+import android.renderscript.RenderScript;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
@@ -3779,6 +3780,7 @@ public final class ActivityThread {
appContext.init(info, null, this);
HardwareRenderer.setupDiskCache(appContext.getCacheDir());
+ RenderScript.setupDiskCache(appContext.getCacheDir());
}
} catch (RemoteException e) {
// Ignore
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index fee2beb779ac..758ce094cf6c 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -332,6 +332,24 @@ final class ApplicationPackageManager extends PackageManager {
}
@Override
+ public void grantPermission(String packageName, String permissionName) {
+ try {
+ mPM.grantPermission(packageName, permissionName);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Package manager has died", e);
+ }
+ }
+
+ @Override
+ public void revokePermission(String packageName, String permissionName) {
+ try {
+ mPM.revokePermission(packageName, permissionName);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Package manager has died", e);
+ }
+ }
+
+ @Override
public int checkSignatures(String pkg1, String pkg2) {
try {
return mPM.checkSignatures(pkg1, pkg2);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index f427e78db96a..492fcc73540c 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -149,7 +149,7 @@ final class FragmentState implements Parcelable {
* {@link Fragment#getFragmentManager() Fragment.getFragmentManager()}.
*
* <p>The Fragment class can be used many ways to achieve a wide variety of
- * results. It is core, it represents a particular operation or interface
+ * results. In its core, it represents a particular operation or interface
* that is running within a larger {@link Activity}. A Fragment is closely
* tied to the Activity it is in, and can not be used apart from one. Though
* Fragment defines its own lifecycle, that lifecycle is dependent on its
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 2420b846514b..4d5238c582f7 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -33,7 +33,6 @@ interface INotificationManager
void enqueueToast(String pkg, ITransientNotification callback, int duration);
void cancelToast(String pkg, ITransientNotification callback);
void enqueueNotificationWithTag(String pkg, String tag, int id, in Notification notification, inout int[] idReceived);
- void enqueueNotificationWithTagPriority(String pkg, String tag, int id, int priority, in Notification notification, inout int[] idReceived);
void cancelNotificationWithTag(String pkg, String tag, int id);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d569e2071463..5325af044083 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -30,6 +31,7 @@ import android.widget.ProgressBar;
import android.widget.RemoteViews;
import java.text.NumberFormat;
+import java.util.ArrayList;
/**
* A class that represents how a persistent notification is to be presented to
@@ -51,36 +53,58 @@ public class Notification implements Parcelable
* Use all default values (where applicable).
*/
public static final int DEFAULT_ALL = ~0;
-
+
/**
* Use the default notification sound. This will ignore any given
* {@link #sound}.
- *
+ *
+
* @see #defaults
- */
+ */
+
public static final int DEFAULT_SOUND = 1;
/**
* Use the default notification vibrate. This will ignore any given
- * {@link #vibrate}. Using phone vibration requires the
+ * {@link #vibrate}. Using phone vibration requires the
* {@link android.Manifest.permission#VIBRATE VIBRATE} permission.
- *
+ *
* @see #defaults
- */
+ */
+
public static final int DEFAULT_VIBRATE = 2;
-
+
/**
* Use the default notification lights. This will ignore the
* {@link #FLAG_SHOW_LIGHTS} bit, and {@link #ledARGB}, {@link #ledOffMS}, or
* {@link #ledOnMS}.
- *
+ *
* @see #defaults
- */
+ */
+
public static final int DEFAULT_LIGHTS = 4;
-
+
/**
- * The timestamp for the notification. The icons and expanded views
- * are sorted by this key.
+ * A timestamp related to this notification, in milliseconds since the epoch.
+ *
+ * Default value: {@link System#currentTimeMillis() Now}.
+ *
+ * Choose a timestamp that will be most relevant to the user. For most finite events, this
+ * corresponds to the time the event happened (or will happen, in the case of events that have
+ * yet to occur but about which the user is being informed). Indefinite events should be
+ * timestamped according to when the activity began.
+ *
+ * Some examples:
+ *
+ * <ul>
+ * <li>Notification of a new chat message should be stamped when the message was received.</li>
+ * <li>Notification of an ongoing file download (with a progress bar, for example) should be stamped when the download started.</li>
+ * <li>Notification of a completed file download should be stamped when the download finished.</li>
+ * <li>Notification of an upcoming meeting should be stamped with the time the meeting will begin (that is, in the future).</li>
+ * <li>Notification of an ongoing stopwatch (increasing timer) should be stamped with the watch's start time.
+ * <li>Notification of an ongoing countdown timer should be stamped with the timer's end time.
+ * </ul>
+ *
*/
public long when;
@@ -100,10 +124,16 @@ public class Notification implements Parcelable
public int iconLevel;
/**
- * The number of events that this notification represents. For example, in a new mail
- * notification, this could be the number of unread messages. This number is superimposed over
- * the icon in the status bar. If the number is 0 or negative, it is not shown in the status
- * bar.
+ * The number of events that this notification represents. For example, in a new mail
+ * notification, this could be the number of unread messages.
+ *
+ * The system may or may not use this field to modify the appearance of the notification. For
+ * example, before {@link android.os.Build.VERSION_CODES#HONEYCOMB}, this number was
+ * superimposed over the icon in the status bar. Starting with
+ * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, the template used by
+ * {@link Notification.Builder} has displayed the number in the expanded notification view.
+ *
+ * If the number is 0 or negative, it is never shown.
*/
public int number;
@@ -121,10 +151,11 @@ public class Notification implements Parcelable
public PendingIntent contentIntent;
/**
- * The intent to execute when the status entry is deleted by the user
- * with the "Clear All Notifications" button. This probably shouldn't
- * be launching an activity since several of those will be sent at the
- * same time.
+ * The intent to execute when the notification is explicitly dismissed by the user, either with
+ * the "Clear All" button or by swiping it away individually.
+ *
+ * This probably shouldn't be launching an activity since several of those will be sent
+ * at the same time.
*/
public PendingIntent deleteIntent;
@@ -139,11 +170,6 @@ public class Notification implements Parcelable
* Text to scroll across the screen when this item is added to
* the status bar on large and smaller devices.
*
- * <p>This field is provided separately from the other ticker fields
- * both for compatibility and to allow an application to choose different
- * text for when the text scrolls in and when it is displayed all at once
- * in conjunction with one or more icons.
- *
* @see #tickerView
*/
public CharSequence tickerText;
@@ -166,9 +192,9 @@ public class Notification implements Parcelable
/**
* The sound to play.
- *
+ *
* <p>
- * To play the default notification sound, see {@link #defaults}.
+ * To play the default notification sound, see {@link #defaults}.
* </p>
*/
public Uri sound;
@@ -187,14 +213,13 @@ public class Notification implements Parcelable
*/
public int audioStreamType = STREAM_DEFAULT;
-
/**
- * The pattern with which to vibrate.
- *
+ * The pattern with which to vibrate.
+ *
* <p>
* To vibrate the default pattern, see {@link #defaults}.
* </p>
- *
+ *
* @see android.os.Vibrator#vibrate(long[],int)
*/
public long[] vibrate;
@@ -235,7 +260,6 @@ public class Notification implements Parcelable
*/
public int defaults;
-
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if you want the LED on for this notification.
@@ -252,7 +276,7 @@ public class Notification implements Parcelable
* because they will be set to values that work on any given hardware.
* <p>
* The alpha channel must be set for forward compatibility.
- *
+ *
*/
public static final int FLAG_SHOW_LIGHTS = 0x00000001;
@@ -282,7 +306,8 @@ public class Notification implements Parcelable
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if the notification should be canceled when it is clicked by the
- * user. On tablets, the
+ * user. On tablets, the
+
*/
public static final int FLAG_AUTO_CANCEL = 0x00000010;
@@ -301,22 +326,105 @@ public class Notification implements Parcelable
public static final int FLAG_FOREGROUND_SERVICE = 0x00000040;
/**
- * Bit to be bitwise-ored into the {@link #flags} field that should be set if this notification
- * represents a high-priority event that may be shown to the user even if notifications are
- * otherwise unavailable (that is, when the status bar is hidden). This flag is ideally used
- * in conjunction with {@link #fullScreenIntent}.
+ * Obsolete flag indicating high-priority notifications; use the priority field instead.
+ *
+ * @deprecated Use {@link #priority} with a positive value.
*/
- public static final int FLAG_HIGH_PRIORITY = 0x00000080;
+ public static final int FLAG_HIGH_PRIORITY = 0x00000080;
public int flags;
/**
- * Constructs a Notification object with everything set to 0.
+ * Default notification {@link #priority}. If your application does not prioritize its own
+ * notifications, use this value for all notifications.
+ */
+ public static final int PRIORITY_DEFAULT = 0;
+
+ /**
+ * Lower {@link #priority}, for items that are less important. The UI may choose to show these
+ * items smaller, or at a different position in the list, compared with your app's
+ * {@link #PRIORITY_DEFAULT} items.
+ */
+ public static final int PRIORITY_LOW = -1;
+
+ /**
+ * Lowest {@link #priority}; these items might not be shown to the user except under special
+ * circumstances, such as detailed notification logs.
+ */
+ public static final int PRIORITY_MIN = -2;
+
+ /**
+ * Higher {@link #priority}, for more important notifications or alerts. The UI may choose to
+ * show these items larger, or at a different position in notification lists, compared with
+ * your app's {@link #PRIORITY_DEFAULT} items.
+ */
+ public static final int PRIORITY_HIGH = 1;
+
+ /**
+ * Highest {@link #priority}, for your application's most important items that require the
+ * user's prompt attention or input.
+ */
+ public static final int PRIORITY_MAX = 2;
+
+ /**
+ * Relative priority for this notification.
+ *
+ * Priority is an indication of how much of the user's valuable attention should be consumed by
+ * this notification. Low-priority notifications may be hidden from the user in certain
+ * situations, while the user might be interrupted for a higher-priority notification. The
+ * system will make a determination about how to interpret notification priority as described in
+ * MUMBLE MUMBLE.
+ */
+ public int priority;
+
+ /**
+ * Notification type: incoming call (voice or video) or similar synchronous communication request.
+ */
+ public static final String KIND_CALL = "android.call";
+
+ /**
+ * Notification type: incoming direct message (SMS, instant message, etc.).
+ */
+ public static final String KIND_MESSAGE = "android.message";
+
+ /**
+ * Notification type: asynchronous bulk message (email).
+ */
+ public static final String KIND_EMAIL = "android.email";
+
+ /**
+ * Notification type: calendar event.
+ */
+ public static final String KIND_EVENT = "android.event";
+
+ /**
+ * Notification type: promotion or advertisement.
+ */
+ public static final String KIND_PROMO = "android.promo";
+
+ /**
+ * If this notification matches of one or more special types (see the <code>KIND_*</code>
+ * constants), add them here, best match first.
+ */
+ public String[] kind;
+
+ /**
+ * Extra key for people values (type TBD).
+ *
+ * @hide
+ */
+ public static final String EXTRA_PEOPLE = "android.people";
+
+ private Bundle extras;
+
+ /**
+ * Constructs a Notification object with default values.
* You might want to consider using {@link Builder} instead.
*/
public Notification()
{
this.when = System.currentTimeMillis();
+ this.priority = PRIORITY_DEFAULT;
}
/**
@@ -396,6 +504,14 @@ public class Notification implements Parcelable
if (parcel.readInt() != 0) {
fullScreenIntent = PendingIntent.CREATOR.createFromParcel(parcel);
}
+
+ priority = parcel.readInt();
+
+ kind = parcel.createStringArray(); // may set kind to null
+
+ if (parcel.readInt() != 0) {
+ extras = parcel.readBundle();
+ }
}
@Override
@@ -438,9 +554,23 @@ public class Notification implements Parcelable
that.ledOnMS = this.ledOnMS;
that.ledOffMS = this.ledOffMS;
that.defaults = this.defaults;
-
+
that.flags = this.flags;
+ that.priority = this.priority;
+
+ final String[] thiskind = this.kind;
+ if (thiskind != null) {
+ final int N = thiskind.length;
+ final String[] thatkind = that.kind = new String[N];
+ System.arraycopy(thiskind, 0, thatkind, 0, N);
+ }
+
+ if (this.extras != null) {
+ that.extras = new Bundle(this.extras);
+
+ }
+
return that;
}
@@ -517,6 +647,17 @@ public class Notification implements Parcelable
} else {
parcel.writeInt(0);
}
+
+ parcel.writeInt(priority);
+
+ parcel.writeStringArray(kind); // ok for null
+
+ if (extras != null) {
+ parcel.writeInt(1);
+ extras.writeToParcel(parcel, 0);
+ } else {
+ parcel.writeInt(0);
+ }
}
/**
@@ -551,7 +692,7 @@ public class Notification implements Parcelable
* that you take care of task management as described in the
* <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
* Stack</a> document.
- *
+ *
* @deprecated Use {@link Builder} instead.
*/
@Deprecated
@@ -579,7 +720,9 @@ public class Notification implements Parcelable
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("Notification(contentView=");
+ sb.append("Notification(pri=");
+ sb.append(priority);
+ sb.append(" contentView=");
if (contentView != null) {
sb.append(contentView.getPackage());
sb.append("/0x");
@@ -587,6 +730,7 @@ public class Notification implements Parcelable
} else {
sb.append("null");
}
+ // TODO(dsandler): defaults take precedence over local values, so reorder the branches below
sb.append(" vibrate=");
if (this.vibrate != null) {
int N = this.vibrate.length-1;
@@ -604,7 +748,7 @@ public class Notification implements Parcelable
} else {
sb.append("null");
}
- sb.append(",sound=");
+ sb.append(" sound=");
if (this.sound != null) {
sb.append(this.sound.toString());
} else if ((this.defaults & DEFAULT_SOUND) != 0) {
@@ -612,20 +756,39 @@ public class Notification implements Parcelable
} else {
sb.append("null");
}
- sb.append(",defaults=0x");
+ sb.append(" defaults=0x");
sb.append(Integer.toHexString(this.defaults));
- sb.append(",flags=0x");
+ sb.append(" flags=0x");
sb.append(Integer.toHexString(this.flags));
- if ((this.flags & FLAG_HIGH_PRIORITY) != 0) {
- sb.append("!!!1!one!");
+ sb.append(" kind=[");
+ if (this.kind == null) {
+ sb.append("null");
+ } else {
+ for (int i=0; i<this.kind.length; i++) {
+ if (i>0) sb.append(",");
+ sb.append(this.kind[i]);
+ }
}
- sb.append(")");
+ sb.append("])");
return sb.toString();
}
/**
- * Builder class for {@link Notification} objects. Allows easier control over
- * all the flags, as well as help constructing the typical notification layouts.
+ * Builder class for {@link Notification} objects.
+ *
+ * Provides a convenient way to set the various fields of a {@link Notification} and generate
+ * content views using the platform's notification layout template.
+ *
+ * Example:
+ *
+ * <pre class="prettyprint">
+ * Notification noti = new Notification.Builder()
+ * .setContentTitle(&quot;New mail from &quot; + sender.toString())
+ * .setContentText(subject)
+ * .setSmallIcon(R.drawable.new_mail)
+ * .setLargeIcon(aBitmap)
+ * .getNotification();
+ * </pre>
*/
public static class Builder {
private Context mContext;
@@ -655,16 +818,28 @@ public class Notification implements Parcelable
private int mProgressMax;
private int mProgress;
private boolean mProgressIndeterminate;
+ private ArrayList<String> mKindList = new ArrayList<String>(1);
+ private Bundle mExtras;
+ private int mPriority;
/**
- * Constructor.
+ * Constructs a new Builder with the defaults:
*
- * Automatically sets the when field to {@link System#currentTimeMillis()
- * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
+
+ * <table>
+ * <tr><th align=right>priority</th>
+ * <td>{@link #PRIORITY_DEFAULT}</td></tr>
+ * <tr><th align=right>when</th>
+ * <td>now ({@link System#currentTimeMillis()})</td></tr>
+ * <tr><th align=right>audio stream</th>
+ * <td>{@link #STREAM_DEFAULT}</td></tr>
+ * </table>
*
- * @param context A {@link Context} that will be used to construct the
- * RemoteViews. The Context will not be held past the lifetime of this
- * Builder object.
+
+ * @param context
+ * A {@link Context} that will be used by the Builder to construct the
+ * RemoteViews. The Context will not be held past the lifetime of this Builder
+ * object.
*/
public Builder(Context context) {
mContext = context;
@@ -672,11 +847,14 @@ public class Notification implements Parcelable
// Set defaults to match the defaults of a Notification
mWhen = System.currentTimeMillis();
mAudioStreamType = STREAM_DEFAULT;
+ mPriority = PRIORITY_DEFAULT;
}
/**
- * Set the time that the event occurred. Notifications in the panel are
- * sorted by this time.
+ * Add a timestamp pertaining to the notification (usually the time the event occurred).
+ *
+
+ * @see Notification#when
*/
public Builder setWhen(long when) {
mWhen = when;
@@ -684,11 +862,18 @@ public class Notification implements Parcelable
}
/**
- * Set the small icon to use in the notification layouts. Different classes of devices
- * may return different sizes. See the UX guidelines for more information on how to
- * design these icons.
+ * Set the small icon resource, which will be used to represent the notification in the
+ * status bar.
*
- * @param icon A resource ID in the application's package of the drawble to use.
+
+ * The platform template for the expanded view will draw this icon in the left, unless a
+ * {@link #setLargeIcon(Bitmap) large icon} has also been specified, in which case the small
+ * icon will be moved to the right-hand side.
+ *
+
+ * @param icon
+ * A resource ID in the application's package of the drawable to use.
+ * @see Notification#icon
*/
public Builder setSmallIcon(int icon) {
mSmallIcon = icon;
@@ -700,10 +885,11 @@ public class Notification implements Parcelable
* level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
* LevelListDrawable}.
*
- * @param icon A resource ID in the application's package of the drawble to use.
+ * @param icon A resource ID in the application's package of the drawable to use.
* @param level The level to use for the icon.
*
- * @see android.graphics.drawable.LevelListDrawable
+ * @see Notification#icon
+ * @see Notification#iconLevel
*/
public Builder setSmallIcon(int icon, int level) {
mSmallIcon = icon;
@@ -712,7 +898,7 @@ public class Notification implements Parcelable
}
/**
- * Set the title (first row) of the notification, in a standard notification.
+ * Set the first line of text in the platform notification template.
*/
public Builder setContentTitle(CharSequence title) {
mContentTitle = title;
@@ -720,7 +906,7 @@ public class Notification implements Parcelable
}
/**
- * Set the text (second row) of the notification, in a standard notification.
+ * Set the second line of text in the platform notification template.
*/
public Builder setContentText(CharSequence text) {
mContentText = text;
@@ -738,7 +924,11 @@ public class Notification implements Parcelable
}
/**
- * Set the large text at the right-hand side of the notification.
+ * A small piece of additional information pertaining to this notification.
+ *
+
+ * The platform template will draw this on the last line of the notification, at the far
+ * right (to the right of a smallIcon if it has been placed there).
*/
public Builder setContentInfo(CharSequence info) {
mContentInfo = info;
@@ -746,8 +936,10 @@ public class Notification implements Parcelable
}
/**
- * Set the progress this notification represents, which may be
- * represented as a {@link ProgressBar}.
+ * Set the progress this notification represents.
+ *
+
+ * The platform template will represent this using a {@link ProgressBar}.
*/
public Builder setProgress(int max, int progress, boolean indeterminate) {
mProgressMax = max;
@@ -757,7 +949,10 @@ public class Notification implements Parcelable
}
/**
- * Supply a custom RemoteViews to use instead of the standard one.
+ * Supply a custom RemoteViews to use instead of the platform template.
+ *
+
+ * @see Notification#contentView
*/
public Builder setContent(RemoteViews views) {
mContentView = views;
@@ -765,12 +960,20 @@ public class Notification implements Parcelable
}
/**
- * Supply a {@link PendingIntent} to send when the notification is clicked.
- * If you do not supply an intent, you can now add PendingIntents to individual
- * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
- * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to
- * read {@link Notification#contentIntent Notification.contentIntent} for
- * how to correctly use this.
+ * Supply a {@link PendingIntent} to be sent when the notification is clicked.
+ *
+
+ * As of {@link android.os.Build.VERSION_CODES#HONEYCOMB}, if this field is unset and you
+ * have specified a custom RemoteViews with {@link #setContent(RemoteViews)}, you can use
+ * {@link RemoteViews#setOnClickPendingIntent RemoteViews.setOnClickPendingIntent(int,PendingIntent)}
+
+ * to assign PendingIntents to individual views in that custom layout (i.e., to create
+
+ * clickable buttons inside the
+ * notification view).
+ *
+
+ * @see Notification#contentIntent Notification.contentIntent
*/
public Builder setContentIntent(PendingIntent intent) {
mContentIntent = intent;
@@ -778,11 +981,10 @@ public class Notification implements Parcelable
}
/**
- * Supply a {@link PendingIntent} to send when the notification is cleared by the user
- * directly from the notification panel. For example, this intent is sent when the user
- * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
- * intent is not sent when the application calls {@link NotificationManager#cancel
- * NotificationManager.cancel(int)}.
+ * Supply a {@link PendingIntent} to send when the notification is cleared explicitly by the user.
+ *
+
+ * @see Notification#deleteIntent
*/
public Builder setDeleteIntent(PendingIntent intent) {
mDeleteIntent = intent;
@@ -801,6 +1003,8 @@ public class Notification implements Parcelable
* @param intent The pending intent to launch.
* @param highPriority Passing true will cause this notification to be sent
* even if other notifications are suppressed.
+ *
+ * @see Notification#fullScreenIntent
*/
public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
mFullScreenIntent = intent;
@@ -809,8 +1013,11 @@ public class Notification implements Parcelable
}
/**
- * Set the text that is displayed in the status bar when the notification first
+ * Set the "ticker" text which is displayed in the status bar when the notification first
* arrives.
+ *
+
+ * @see Notification#tickerText
*/
public Builder setTicker(CharSequence tickerText) {
mTickerText = tickerText;
@@ -821,6 +1028,9 @@ public class Notification implements Parcelable
* Set the text that is displayed in the status bar when the notification first
* arrives, and also a RemoteViews object that may be displayed instead on some
* devices.
+ *
+ * @see Notification#tickerText
+ * @see Notification#tickerView
*/
public Builder setTicker(CharSequence tickerText, RemoteViews views) {
mTickerText = tickerText;
@@ -829,7 +1039,12 @@ public class Notification implements Parcelable
}
/**
- * Set the large icon that is shown in the ticker and notification.
+ * Add a large icon to the notification (and the ticker on some devices).
+ *
+ * In the platform template, this image will be shown on the left of the notification view
+ * in place of the {@link #setSmallIcon(int) small icon} (which will move to the right side).
+ *
+ * @see Notification#largeIcon
*/
public Builder setLargeIcon(Bitmap icon) {
mLargeIcon = icon;
@@ -837,7 +1052,11 @@ public class Notification implements Parcelable
}
/**
- * Set the sound to play. It will play on the default stream.
+ * Set the sound to play.
+ *
+ * It will be played on the {@link #STREAM_DEFAULT default stream} for notifications.
+ *
+ * @see Notification#sound
*/
public Builder setSound(Uri sound) {
mSound = sound;
@@ -846,10 +1065,11 @@ public class Notification implements Parcelable
}
/**
- * Set the sound to play. It will play on the stream you supply.
+ * Set the sound to play, along with a specific stream on which to play it.
*
- * @see #STREAM_DEFAULT
- * @see AudioManager for the <code>STREAM_</code> constants.
+ * See {@link android.media.AudioManager} for the <code>STREAM_</code> constants.
+ *
+ * @see Notification#sound
*/
public Builder setSound(Uri sound, int streamType) {
mSound = sound;
@@ -860,8 +1080,12 @@ public class Notification implements Parcelable
/**
* Set the vibration pattern to use.
*
- * @see android.os.Vibrator for a discussion of the <code>pattern</code>
- * parameter.
+
+ * See {@link android.os.Vibrator#vibrate(long[], int)} for a discussion of the
+ * <code>pattern</code> parameter.
+ *
+
+ * @see Notification#vibrate
*/
public Builder setVibrate(long[] pattern) {
mVibrate = pattern;
@@ -869,9 +1093,16 @@ public class Notification implements Parcelable
}
/**
- * Set the argb value that you would like the LED on the device to blnk, as well as the
- * rate. The rate is specified in terms of the number of milliseconds to be on
- * and then the number of milliseconds to be off.
+ * Set the desired color for the indicator LED on the device, as well as the
+ * blink duty cycle (specified in milliseconds).
+ *
+
+ * Not all devices will honor all (or even any) of these values.
+ *
+
+ * @see Notification#ledARGB
+ * @see Notification#ledOnMS
+ * @see Notification#ledOffMS
*/
public Builder setLights(int argb, int onMs, int offMs) {
mLedArgb = argb;
@@ -881,15 +1112,20 @@ public class Notification implements Parcelable
}
/**
- * Set whether this is an ongoing notification.
+ * Set whether this is an "ongoing" notification.
*
- * <p>Ongoing notifications differ from regular notifications in the following ways:
- * <ul>
- * <li>Ongoing notifications are sorted above the regular notifications in the
- * notification panel.</li>
- * <li>Ongoing notifications do not have an 'X' close button, and are not affected
- * by the "Clear all" button.
- * </ul>
+
+ * Ongoing notifications cannot be dismissed by the user, so your application or service
+ * must take care of canceling them.
+ *
+
+ * They are typically used to indicate a background task that the user is actively engaged
+ * with (e.g., playing music) or is pending in some way and therefore occupying the device
+ * (e.g., a file download, sync operation, active network connection).
+ *
+
+ * @see Notification#FLAG_ONGOING_EVENT
+ * @see Service#setForeground(boolean)
*/
public Builder setOngoing(boolean ongoing) {
setFlag(FLAG_ONGOING_EVENT, ongoing);
@@ -899,6 +1135,8 @@ public class Notification implements Parcelable
/**
* Set this flag if you would only like the sound, vibrate
* and ticker to be played if the notification is not already showing.
+ *
+ * @see Notification#FLAG_ONLY_ALERT_ONCE
*/
public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
@@ -906,10 +1144,10 @@ public class Notification implements Parcelable
}
/**
- * Setting this flag will make it so the notification is automatically
- * canceled when the user clicks it in the panel. The PendingIntent
- * set with {@link #setDeleteIntent} will be broadcast when the notification
- * is canceled.
+ * Make this notification automatically dismissed when the user touches it. The
+ * PendingIntent set with {@link #setDeleteIntent} will be sent when this happens.
+ *
+ * @see Notification#FLAG_AUTO_CANCEL
*/
public Builder setAutoCancel(boolean autoCancel) {
setFlag(FLAG_AUTO_CANCEL, autoCancel);
@@ -917,7 +1155,7 @@ public class Notification implements Parcelable
}
/**
- * Set the default notification options that will be used.
+ * Set which notification properties will be inherited from system defaults.
* <p>
* The value should be one or more of the following fields combined with
* bitwise-or:
@@ -930,6 +1168,41 @@ public class Notification implements Parcelable
return this;
}
+ /**
+ * Set the priority of this notification.
+ *
+ * @see Notification#priority
+ */
+ public Builder setPriority(int pri) {
+ mPriority = pri;
+ return this;
+ }
+
+ /**
+ * Add a kind (category) to this notification. Optional.
+ *
+ * @see Notification#kind
+ */
+ public Builder addKind(String k) {
+ mKindList.add(k);
+ return this;
+ }
+
+ /**
+ * Add metadata to this notification.
+ *
+ * A reference to the Bundle is held for the lifetime of this Builder, and the Bundle's
+ * current contents are copied into the Notification each time {@link #getNotification()} is
+ * called.
+ *
+ * @see Notification#extras
+ * @hide
+ */
+ public Builder setExtras(Bundle bag) {
+ mExtras = bag;
+ return this;
+ }
+
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
@@ -1042,6 +1315,14 @@ public class Notification implements Parcelable
if ((mDefaults & DEFAULT_LIGHTS) != 0) {
n.flags |= FLAG_SHOW_LIGHTS;
}
+ if (mKindList.size() > 0) {
+ n.kind = new String[mKindList.size()];
+ mKindList.toArray(n.kind);
+ } else {
+ n.kind = null;
+ }
+ n.priority = mPriority;
+ n.extras = mExtras != null ? new Bundle(mExtras) : null;
return n;
}
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index bb35c291ace2..95b6feebd93e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -81,7 +81,11 @@ interface IPackageManager {
boolean addPermission(in PermissionInfo info);
void removePermission(String name);
-
+
+ void grantPermission(String packageName, String permissionName);
+
+ void revokePermission(String packageName, String permissionName);
+
boolean isProtectedBroadcast(String actionName);
int checkSignatures(String pkg1, String pkg2);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index eb05d7638c7f..415d58aa7fba 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -141,6 +141,30 @@ public class PackageInfo implements Parcelable {
public String[] requestedPermissions;
/**
+ * Array of flags of all {@link android.R.styleable#AndroidManifestUsesPermission
+ * &lt;uses-permission&gt;} tags included under &lt;manifest&gt;,
+ * or null if there were none. This is only filled in if the flag
+ * {@link PackageManager#GET_PERMISSIONS} was set. Each value matches
+ * the corresponding entry in {@link #requestedPermissions}, and will have
+ * the flags {@link #REQUESTED_PERMISSION_REQUIRED} and
+ * {@link #REQUESTED_PERMISSION_GRANTED} set as appropriate.
+ */
+ public int[] requestedPermissionsFlags;
+
+ /**
+ * Flag for {@link #requestedPermissionsFlags}: the requested permission
+ * is required for the application to run; the user can not optionally
+ * disable it.
+ */
+ public static final int REQUESTED_PERMISSION_REQUIRED = 1<<0;
+
+ /**
+ * Flag for {@link #requestedPermissionsFlags}: the requested permission
+ * is currently granted to the application.
+ */
+ public static final int REQUESTED_PERMISSION_GRANTED = 1<<1;
+
+ /**
* Array of all signatures read from the package file. This is only filled
* in if the flag {@link PackageManager#GET_SIGNATURES} was set.
*/
@@ -229,6 +253,7 @@ public class PackageInfo implements Parcelable {
dest.writeTypedArray(instrumentation, parcelableFlags);
dest.writeTypedArray(permissions, parcelableFlags);
dest.writeStringArray(requestedPermissions);
+ dest.writeIntArray(requestedPermissionsFlags);
dest.writeTypedArray(signatures, parcelableFlags);
dest.writeTypedArray(configPreferences, parcelableFlags);
dest.writeTypedArray(reqFeatures, parcelableFlags);
@@ -266,6 +291,7 @@ public class PackageInfo implements Parcelable {
instrumentation = source.createTypedArray(InstrumentationInfo.CREATOR);
permissions = source.createTypedArray(PermissionInfo.CREATOR);
requestedPermissions = source.createStringArray();
+ requestedPermissionsFlags = source.createIntArray();
signatures = source.createTypedArray(Signature.CREATOR);
configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 26a9181c2f0d..f2133d8387b2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1475,6 +1475,29 @@ public abstract class PackageManager {
public abstract void removePermission(String name);
/**
+ * Grant a permission to an application which the application does not
+ * already have. The permission must have been requested by the application,
+ * but as an optional permission. If the application is not allowed to
+ * hold the permission, a SecurityException is thrown.
+ * @hide
+ *
+ * @param packageName The name of the package that the permission will be
+ * granted to.
+ * @param permissionName The name of the permission.
+ */
+ public abstract void grantPermission(String packageName, String permissionName);
+
+ /**
+ * Revoke a permission that was previously granted by {@link #grantPermission}.
+ * @hide
+ *
+ * @param packageName The name of the package that the permission will be
+ * granted to.
+ * @param permissionName The name of the permission.
+ */
+ public abstract void revokePermission(String packageName, String permissionName);
+
+ /**
* Compare the signatures of two packages to determine if the same
* signature appears in both of them. If they do contain the same
* signature, then they are allowed special privileges when working
@@ -2125,7 +2148,7 @@ public abstract class PackageManager {
if ((flags & GET_SIGNATURES) != 0) {
packageParser.collectCertificates(pkg, 0);
}
- return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0);
+ return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0, null);
}
/**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 8029bd51c8d1..7b4a0ad1cecf 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -51,6 +51,7 @@ import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.jar.Attributes;
@@ -211,7 +212,8 @@ public class PackageParser {
* @param flags indicating which optional information is included.
*/
public static PackageInfo generatePackageInfo(PackageParser.Package p,
- int gids[], int flags, long firstInstallTime, long lastUpdateTime) {
+ int gids[], int flags, long firstInstallTime, long lastUpdateTime,
+ HashSet<String> grantedPermissions) {
final int userId = Binder.getOrigCallingUser();
@@ -346,8 +348,16 @@ public class PackageParser {
N = p.requestedPermissions.size();
if (N > 0) {
pi.requestedPermissions = new String[N];
+ pi.requestedPermissionsFlags = new int[N];
for (int i=0; i<N; i++) {
- pi.requestedPermissions[i] = p.requestedPermissions.get(i);
+ final String perm = p.requestedPermissions.get(i);
+ pi.requestedPermissions[i] = perm;
+ if (p.requestedPermissionsRequired.get(i)) {
+ pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
+ }
+ if (grantedPermissions != null && grantedPermissions.contains(perm)) {
+ pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
+ }
}
}
}
@@ -927,11 +937,14 @@ public class PackageParser {
// that may change.
String name = sa.getNonResourceString(
com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
+ boolean required = sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestUsesPermission_required, true);
sa.recycle();
if (name != null && !pkg.requestedPermissions.contains(name)) {
pkg.requestedPermissions.add(name.intern());
+ pkg.requestedPermissionsRequired.add(required);
}
XmlUtils.skipCurrentTag(parser);
@@ -1419,12 +1432,24 @@ public class PackageParser {
PermissionInfo.PROTECTION_NORMAL);
sa.recycle();
-
+
if (perm.info.protectionLevel == -1) {
outError[0] = "<permission> does not specify protectionLevel";
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
}
+
+ perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel);
+
+ if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_FLAGS) != 0) {
+ if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) !=
+ PermissionInfo.PROTECTION_SIGNATURE) {
+ outError[0] = "<permission> protectionLevel specifies a flag but is "
+ + "not based on signature type";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+ }
if (!parseAllMetaData(res, parser, attrs, "<permission>", perm,
outError)) {
@@ -2951,6 +2976,7 @@ public class PackageParser {
public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
public final ArrayList<String> requestedPermissions = new ArrayList<String>();
+ public final ArrayList<Boolean> requestedPermissionsRequired = new ArrayList<Boolean>();
public ArrayList<String> protectedBroadcasts;
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 3cc884b1098a..69b812ca89aa 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -55,6 +55,30 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
/**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the <code>system</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_FLAG_SYSTEM = 0x10;
+
+ /**
+ * Additional flag for {@link #protectionLevel}, corresponding
+ * to the <code>development</code> value of
+ * {@link android.R.attr#protectionLevel}.
+ */
+ public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
+
+ /**
+ * Mask for {@link #protectionLevel}: the basic protection type.
+ */
+ public static final int PROTECTION_MASK_BASE = 0xf;
+
+ /**
+ * Mask for {@link #protectionLevel}: additional flag bits.
+ */
+ public static final int PROTECTION_MASK_FLAGS = 0xf0;
+
+ /**
* The group this permission is a part of, as per
* {@link android.R.attr#permissionGroup}.
*/
@@ -79,10 +103,47 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
* The level of access this permission is protecting, as per
* {@link android.R.attr#protectionLevel}. Values may be
* {@link #PROTECTION_NORMAL}, {@link #PROTECTION_DANGEROUS}, or
+ * {@link #PROTECTION_SIGNATURE}. May also include the additional
+ * flags {@link #PROTECTION_FLAG_SYSTEM} or {@link #PROTECTION_FLAG_DEVELOPMENT}
+ * (which only make sense in combination with the base
* {@link #PROTECTION_SIGNATURE}.
*/
public int protectionLevel;
+ /** @hide */
+ public static int fixProtectionLevel(int level) {
+ if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
+ level = PROTECTION_SIGNATURE | PROTECTION_FLAG_SYSTEM;
+ }
+ return level;
+ }
+
+ /** @hide */
+ public static String protectionToString(int level) {
+ String protLevel = "????";
+ switch (level&PROTECTION_MASK_BASE) {
+ case PermissionInfo.PROTECTION_DANGEROUS:
+ protLevel = "dangerous";
+ break;
+ case PermissionInfo.PROTECTION_NORMAL:
+ protLevel = "normal";
+ break;
+ case PermissionInfo.PROTECTION_SIGNATURE:
+ protLevel = "signature";
+ break;
+ case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
+ protLevel = "signatureOrSystem";
+ break;
+ }
+ if ((level&PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
+ protLevel += "|system";
+ }
+ if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
+ protLevel += "|development";
+ }
+ return protLevel;
+ }
+
public PermissionInfo() {
}
diff --git a/core/java/android/inputmethodservice/ExtractEditLayout.java b/core/java/android/inputmethodservice/ExtractEditLayout.java
index 220214bb894b..56968398871f 100644
--- a/core/java/android/inputmethodservice/ExtractEditLayout.java
+++ b/core/java/android/inputmethodservice/ExtractEditLayout.java
@@ -124,6 +124,12 @@ public class ExtractEditLayout extends LinearLayout {
}
@Override
+ public boolean isTitleOptional() {
+ // Not only is it optional, it will *never* be shown.
+ return true;
+ }
+
+ @Override
public void setCustomView(View view) {
// Custom view is not supported here.
}
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 413150b69a4f..fa59b32fddfc 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -402,8 +402,8 @@ public final class CalendarContract {
* A comma separated list of reminder methods supported for this
* calendar in the format "#,#,#". Valid types are
* {@link Reminders#METHOD_DEFAULT}, {@link Reminders#METHOD_ALERT},
- * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS}. Column
- * name.
+ * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS},
+ * {@link Reminders#METHOD_ALARM}. Column name.
* <P>Type: TEXT</P>
*/
public static final String ALLOWED_REMINDERS = "allowedReminders";
@@ -1930,11 +1930,11 @@ public final class CalendarContract {
/**
* The alarm method, as set on the server. {@link #METHOD_DEFAULT},
- * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, and {@link #METHOD_SMS}
- * are possible values; the device will only process
- * {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders (the
- * other types are simply stored so we can send the same reminder info
- * back to the server when we make changes).
+ * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, {@link #METHOD_SMS} and
+ * {@link #METHOD_ALARM} are possible values; the device will only
+ * process {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders
+ * (the other types are simply stored so we can send the same reminder
+ * info back to the server when we make changes).
*/
public static final String METHOD = "method";
@@ -1942,6 +1942,7 @@ public final class CalendarContract {
public static final int METHOD_ALERT = 1;
public static final int METHOD_EMAIL = 2;
public static final int METHOD_SMS = 3;
+ public static final int METHOD_ALARM = 4;
}
/**
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index 0349a2be3fbf..0ba5fdbc4f1a 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -24,7 +24,7 @@ package android.view;
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For information about how to provide contextual actions with {@code ActionMode},
- * read the <a href="{@docRoot}guide/topics/ui/menu.html#context-menu">Menus</a>
+ * read the <a href="{@docRoot}guide/topics/ui/menus.html#context-menu">Menus</a>
* developer guide.</p>
* </div>
*/
@@ -104,6 +104,32 @@ public abstract class ActionMode {
public abstract void setSubtitle(int resId);
/**
+ * Set whether or not the title/subtitle display for this action mode
+ * is optional.
+ *
+ * <p>In many cases the supplied title for an action mode is merely
+ * meant to add context and is not strictly required for the action
+ * mode to be useful. If the title is optional, the system may choose
+ * to hide the title entirely rather than truncate it due to a lack
+ * of available space.</p>
+ *
+ * <p>Note that this is merely a hint; the underlying implementation
+ * may choose to ignore this setting under some circumstances.</p>
+ *
+ * @param titleOptional true if the title only presents optional information.
+ */
+ public void setTitleOptionalHint(boolean titleOptional) {
+ }
+
+ /**
+ * @return true if this action mode considers the title and subtitle fields
+ * as optional. Optional titles may not be displayed to the user.
+ */
+ public boolean isTitleOptional() {
+ return false;
+ }
+
+ /**
* Set a custom view for this action mode. The custom view will take the place of
* the title and subtitle. Useful for things like search boxes.
*
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f5fc708c0c9c..ee0fa86642e5 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -718,7 +718,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
Paint paint) {
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom,
startAngle, sweepAngle, useCenter, paint.mNativePaint);
@@ -902,7 +902,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
} finally {
@@ -939,7 +939,7 @@ class GLES20Canvas extends HardwareCanvas {
if ((offset | count) < 0 || offset + count > pts.length) {
throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
}
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
} finally {
@@ -957,7 +957,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawOval(RectF oval, Paint paint) {
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
} finally {
@@ -977,7 +977,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawPath(Path path, Paint paint) {
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
if (path.isSimplePath) {
if (path.rects != null) {
@@ -1048,7 +1048,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawPoints(float[] pts, int offset, int count, Paint paint) {
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
} finally {
@@ -1097,7 +1097,8 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawRect(float left, float top, float right, float bottom, Paint paint) {
- int modifiers = setupModifiers(paint);
+ if (left == right || top == bottom) return;
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
} finally {
@@ -1125,7 +1126,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
- int modifiers = setupModifiers(paint);
+ int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
try {
nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
rx, ry, paint.mNativePaint);
@@ -1208,14 +1209,38 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
float vOffset, Paint paint) {
- // TODO: Implement
+ if (index < 0 || index + count > text.length) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ int modifiers = setupModifiers(paint);
+ try {
+ nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
+ paint.mBidiFlags, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
+ private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count,
+ int path, float hOffset, float vOffset, int bidiFlags, int nativePaint);
+
@Override
public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
- // TODO: Implement
+ if (text.length() == 0) return;
+
+ int modifiers = setupModifiers(paint);
+ try {
+ nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
+ paint.mBidiFlags, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
+ private static native void nDrawTextOnPath(int renderer, String text, int start, int end,
+ int path, float hOffset, float vOffset, int bidiFlags, int nativePaint);
+
@Override
public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
float x, float y, int dir, Paint paint) {
@@ -1317,6 +1342,30 @@ class GLES20Canvas extends HardwareCanvas {
return modifiers;
}
+ private int setupModifiers(Paint paint, int flags) {
+ int modifiers = MODIFIER_NONE;
+
+ if (paint.hasShadow && (flags & MODIFIER_SHADOW) != 0) {
+ nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
+ paint.shadowColor);
+ modifiers |= MODIFIER_SHADOW;
+ }
+
+ final Shader shader = paint.getShader();
+ if (shader != null && (flags & MODIFIER_SHADER) != 0) {
+ nSetupShader(mRenderer, shader.native_shader);
+ modifiers |= MODIFIER_SHADER;
+ }
+
+ final ColorFilter filter = paint.getColorFilter();
+ if (filter != null && (flags & MODIFIER_COLOR_FILTER) != 0) {
+ nSetupColorFilter(mRenderer, filter.nativeColorFilter);
+ modifiers |= MODIFIER_COLOR_FILTER;
+ }
+
+ return modifiers;
+ }
+
private int setupColorFilter(Paint paint) {
final ColorFilter filter = paint.getColorFilter();
if (filter != null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 384e39a4d2e2..e6b41da2ba85 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5048,16 +5048,17 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* the View's internal state from a previously set "pressed" state.
*/
public void setPressed(boolean pressed) {
- if (pressed == ((mPrivateFlags & PRESSED) == PRESSED)) {
- return;
- }
+ final boolean needsRefresh = pressed != ((mPrivateFlags & PRESSED) == PRESSED);
if (pressed) {
mPrivateFlags |= PRESSED;
} else {
mPrivateFlags &= ~PRESSED;
}
- refreshDrawableState();
+
+ if (needsRefresh) {
+ refreshDrawableState();
+ }
dispatchSetPressed(pressed);
}
@@ -13055,11 +13056,6 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.REQUEST_LAYOUT);
}
- if (getAccessibilityNodeProvider() != null) {
- throw new IllegalStateException("Views with AccessibilityNodeProvider"
- + " can't have children.");
- }
-
mPrivateFlags |= FORCE_LAYOUT;
mPrivateFlags |= INVALIDATED;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c68d77d6d3ac..05c2b576024c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2669,6 +2669,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return child.draw(canvas, this, drawingTime);
}
+ @Override
+ public void requestLayout() {
+ if (mChildrenCount > 0 && getAccessibilityNodeProvider() != null) {
+ throw new IllegalStateException("Views with AccessibilityNodeProvider"
+ + " can't have children.");
+ }
+ super.requestLayout();
+ }
+
/**
*
* @param enabled True if children should be drawn with layers, false otherwise.
@@ -2761,7 +2770,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View[] children = mChildren;
final int count = mChildrenCount;
for (int i = 0; i < count; i++) {
- children[i].setPressed(pressed);
+ final View child = children[i];
+ // Children that are clickable on their own should not
+ // show a pressed state when their parent view does.
+ // Clearing a pressed state always propagates.
+ if (!pressed || (!child.isClickable() && !child.isLongClickable())) {
+ child.setPressed(pressed);
+ }
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 28737fcaa091..e0d07635c1e8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -54,12 +54,12 @@ import android.util.AndroidRuntimeException;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
-import android.util.LongSparseArray;
import android.util.Pool;
import android.util.Poolable;
import android.util.PoolableManager;
import android.util.Pools;
import android.util.Slog;
+import android.util.SparseLongArray;
import android.util.TypedValue;
import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
@@ -87,7 +87,9 @@ import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* The top of a view hierarchy, implementing the needed protocol between View
@@ -309,7 +311,7 @@ public final class ViewRootImpl implements ViewParent,
SendWindowContentChangedAccessibilityEvent mSendWindowContentChangedAccessibilityEvent;
- AccessibilityPrefetchStrategy mAccessibilityPrefetchStrategy;
+ AccessibilityNodePrefetcher mAccessibilityNodePrefetcher;
private final int mDensity;
@@ -771,19 +773,29 @@ public final class ViewRootImpl implements ViewParent,
return mLayoutRequested;
}
+ void invalidate() {
+ mDirty.set(0, 0, mWidth, mHeight);
+ scheduleTraversals();
+ }
+
public void invalidateChild(View child, Rect dirty) {
+ invalidateChildInParent(null, dirty);
+ }
+
+ public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
checkThread();
if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
+
if (dirty == null) {
- // Fast invalidation for GL-enabled applications; GL must redraw everything
invalidate();
- return;
+ return null;
}
+
if (mCurScrollY != 0 || mTranslator != null) {
mTempRect.set(dirty);
dirty = mTempRect;
if (mCurScrollY != 0) {
- dirty.offset(0, -mCurScrollY);
+ dirty.offset(0, -mCurScrollY);
}
if (mTranslator != null) {
mTranslator.translateRectInAppWindowToScreen(dirty);
@@ -792,19 +804,24 @@ public final class ViewRootImpl implements ViewParent,
dirty.inset(-1, -1);
}
}
- if (!mDirty.isEmpty() && !mDirty.contains(dirty)) {
+
+ final Rect localDirty = mDirty;
+ if (!localDirty.isEmpty() && !localDirty.contains(dirty)) {
mAttachInfo.mSetIgnoreDirtyState = true;
mAttachInfo.mIgnoreDirtyState = true;
}
- mDirty.union(dirty);
+
+ // Add the new dirty rect to the current one
+ localDirty.union(dirty.left, dirty.top, dirty.right, dirty.bottom);
+ // Intersect with the bounds of the window to skip
+ // updates that lie outside of the visible region
+ localDirty.intersect(0, 0, mWidth, mHeight);
+
if (!mWillDrawSoon) {
scheduleTraversals();
}
- }
-
- void invalidate() {
- mDirty.set(0, 0, mWidth, mHeight);
- scheduleTraversals();
+
+ return null;
}
void setStopped(boolean stopped) {
@@ -815,13 +832,8 @@ public final class ViewRootImpl implements ViewParent,
}
}
}
-
- public ViewParent getParent() {
- return null;
- }
- public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
- invalidateChild(null, dirty);
+ public ViewParent getParent() {
return null;
}
@@ -3554,15 +3566,15 @@ public final class ViewRootImpl implements ViewParent,
return mAccessibilityInteractionController;
}
- public AccessibilityPrefetchStrategy getAccessibilityPrefetchStrategy() {
+ public AccessibilityNodePrefetcher getAccessibilityNodePrefetcher() {
if (mView == null) {
- throw new IllegalStateException("getAccessibilityPrefetchStrategy"
+ throw new IllegalStateException("getAccessibilityNodePrefetcher"
+ " called when there is no mView");
}
- if (mAccessibilityPrefetchStrategy == null) {
- mAccessibilityPrefetchStrategy = new AccessibilityPrefetchStrategy();
+ if (mAccessibilityNodePrefetcher == null) {
+ mAccessibilityNodePrefetcher = new AccessibilityNodePrefetcher();
}
- return mAccessibilityPrefetchStrategy;
+ return mAccessibilityNodePrefetcher;
}
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
@@ -4108,7 +4120,6 @@ public final class ViewRootImpl implements ViewParent,
if (mView == null) {
return false;
}
- getAccessibilityPrefetchStrategy().onAccessibilityEvent(event);
mAccessibilityManager.sendAccessibilityEvent(event);
return true;
}
@@ -4680,12 +4691,12 @@ public final class ViewRootImpl implements ViewParent,
public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
int interactionId, IAccessibilityInteractionConnectionCallback callback,
- int interrogatingPid, long interrogatingTid) {
+ int prefetchFlags, int interrogatingPid, long interrogatingTid) {
ViewRootImpl viewRootImpl = mViewRootImpl.get();
if (viewRootImpl != null && viewRootImpl.mView != null) {
viewRootImpl.getAccessibilityInteractionController()
.findAccessibilityNodeInfoByAccessibilityIdClientThread(accessibilityNodeId,
- interactionId, callback, interrogatingPid, interrogatingTid);
+ interactionId, callback, prefetchFlags, interrogatingPid, interrogatingTid);
} else {
// We cannot make the call and notify the caller so it does not wait.
try {
@@ -4820,11 +4831,11 @@ public final class ViewRootImpl implements ViewParent,
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
long accessibilityNodeId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
- long interrogatingTid) {
+ IAccessibilityInteractionConnectionCallback callback, int prefetchFlags,
+ int interrogatingPid, long interrogatingTid) {
Message message = mHandler.obtainMessage();
message.what = MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
- message.arg1 = interrogatingPid;
+ message.arg1 = prefetchFlags;
SomeArgs args = mPool.acquire();
args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
@@ -4845,8 +4856,8 @@ public final class ViewRootImpl implements ViewParent,
}
public void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) {
+ final int prefetchFlags = message.arg1;
SomeArgs args = (SomeArgs) message.obj;
- final int interrogatingPid = message.arg1;
final int accessibilityViewId = args.argi1;
final int virtualDescendantId = args.argi2;
final int interactionId = args.argi3;
@@ -4856,22 +4867,15 @@ public final class ViewRootImpl implements ViewParent,
List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
infos.clear();
try {
+ View target = null;
if (accessibilityViewId == AccessibilityNodeInfo.UNDEFINED) {
- View target = ViewRootImpl.this.mView;
- if (target != null && target.getVisibility() == View.VISIBLE) {
- infos.add(target.createAccessibilityNodeInfo());
- }
+ target = ViewRootImpl.this.mView;
} else {
- View target = findViewByAccessibilityId(accessibilityViewId);
- if (target != null && target.getVisibility() == View.VISIBLE) {
- AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
- if (provider != null) {
- infos.add(provider.createAccessibilityNodeInfo(virtualDescendantId));
- } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
- getAccessibilityPrefetchStrategy().prefetchAccessibilityNodeInfos(
- interrogatingPid, target, infos);
- }
- }
+ target = findViewByAccessibilityId(accessibilityViewId);
+ }
+ if (target != null && target.getVisibility() == View.VISIBLE) {
+ getAccessibilityNodePrefetcher().prefetchAccessibilityNodeInfos(target,
+ virtualDescendantId, prefetchFlags, infos);
}
} finally {
try {
@@ -5132,83 +5136,216 @@ public final class ViewRootImpl implements ViewParent,
/**
* This class encapsulates a prefetching strategy for the accessibility APIs for
- * querying window content.It is responsible to prefetch a batch of
- * AccessibilityNodeInfos in addition to the one for a requested node. It caches
- * the ids of the prefeteched nodes such that they are fetched only once.
+ * querying window content. It is responsible to prefetch a batch of
+ * AccessibilityNodeInfos in addition to the one for a requested node.
*/
- class AccessibilityPrefetchStrategy {
- private static final int MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE = 100;
+ class AccessibilityNodePrefetcher {
- // We need to keep track of what we have sent for each interrogating
- // process. Usually there will be only one such process but we
- // should support the general case. Note that the accessibility event
- // stream will take care of clearing caches of querying processes that
- // are not longer alive, so we do not waste memory.
- private final LongSparseArray<AccessibilityNodeInfoCache> mAccessibilityNodeInfoCaches =
- new LongSparseArray<AccessibilityNodeInfoCache>();
+ private static final int MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE = 50;
- private AccessibilityNodeInfoCache getCacheForInterrogatingPid(long interrogatingPid) {
- AccessibilityNodeInfoCache cache = mAccessibilityNodeInfoCaches.get(interrogatingPid);
- if (cache == null) {
- cache = AccessibilityNodeInfoCache.newAccessibilityNodeInfoCache();
- mAccessibilityNodeInfoCaches.put(interrogatingPid, cache);
+ public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int prefetchFlags,
+ List<AccessibilityNodeInfo> outInfos) {
+ AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
+ if (provider == null) {
+ AccessibilityNodeInfo root = view.createAccessibilityNodeInfo();
+ if (root != null) {
+ outInfos.add(root);
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
+ prefetchPredecessorsOfRealNode(view, outInfos);
+ }
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
+ prefetchSiblingsOfRealNode(view, outInfos);
+ }
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
+ prefetchDescendantsOfRealNode(view, outInfos);
+ }
+ }
+ } else {
+ AccessibilityNodeInfo root = provider.createAccessibilityNodeInfo(virtualViewId);
+ if (root != null) {
+ outInfos.add(root);
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
+ prefetchPredecessorsOfVirtualNode(root, view, provider, outInfos);
+ }
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
+ prefetchSiblingsOfVirtualNode(root, view, provider, outInfos);
+ }
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
+ prefetchDescendantsOfVirtualNode(root, provider, outInfos);
+ }
+ }
}
- return cache;
}
- public void onAccessibilityEvent(AccessibilityEvent event) {
- final int cacheCount = mAccessibilityNodeInfoCaches.size();
- for (int i = 0; i < cacheCount; i++) {
- AccessibilityNodeInfoCache cache = mAccessibilityNodeInfoCaches.valueAt(i);
- cache.onAccessibilityEvent(event);
+ private void prefetchPredecessorsOfRealNode(View view,
+ List<AccessibilityNodeInfo> outInfos) {
+ ViewParent parent = view.getParent();
+ while (parent instanceof View
+ && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ View parentView = (View) parent;
+ final long parentNodeId = AccessibilityNodeInfo.makeNodeId(
+ parentView.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
+ AccessibilityNodeInfo info = parentView.createAccessibilityNodeInfo();
+ if (info != null) {
+ outInfos.add(info);
+ }
+ parent = parent.getParent();
}
}
- public void prefetchAccessibilityNodeInfos(long interrogatingPid, View root,
+ private void prefetchSiblingsOfRealNode(View current,
List<AccessibilityNodeInfo> outInfos) {
- addAndCacheNotCachedNodeInfo(interrogatingPid, root, outInfos);
- addAndCacheNotCachedPredecessorInfos(interrogatingPid, root, outInfos);
- addAndCacheNotCachedDescendantInfos(interrogatingPid, root, outInfos);
+ ViewParent parent = current.getParent();
+ if (parent instanceof ViewGroup) {
+ ViewGroup parentGroup = (ViewGroup) parent;
+ final int childCount = parentGroup.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = parentGroup.getChildAt(i);
+ if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE
+ && child.getAccessibilityViewId() != current.getAccessibilityViewId()
+ && child.getVisibility() == View.VISIBLE) {
+ final long childNodeId = AccessibilityNodeInfo.makeNodeId(
+ child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
+ AccessibilityNodeInfo info = null;
+ AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
+ if (provider == null) {
+ info = child.createAccessibilityNodeInfo();
+ } else {
+ info = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeInfo.UNDEFINED);
+ }
+ if (info != null) {
+ outInfos.add(info);
+ }
+ }
+ }
+ }
}
- private void addAndCacheNotCachedNodeInfo(long interrogatingPid,
- View view, List<AccessibilityNodeInfo> outInfos) {
- final long accessibilityNodeId = AccessibilityNodeInfo.makeNodeId(
- view.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
- AccessibilityNodeInfoCache cache = getCacheForInterrogatingPid(interrogatingPid);
- if (!cache.containsKey(accessibilityNodeId)) {
- // Account for the ids of the fetched infos. The infos will be
- // cached in the window querying process. We just need to know
- // which infos are cached to avoid fetching a cached one again.
- cache.put(accessibilityNodeId, null);
- outInfos.add(view.createAccessibilityNodeInfo());
+ private void prefetchDescendantsOfRealNode(View root,
+ List<AccessibilityNodeInfo> outInfos) {
+ if (root instanceof ViewGroup) {
+ ViewGroup rootGroup = (ViewGroup) root;
+ HashMap<View, AccessibilityNodeInfo> addedChildren =
+ new HashMap<View, AccessibilityNodeInfo>();
+ final int childCount = rootGroup.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = rootGroup.getChildAt(i);
+ if (child.getVisibility() == View.VISIBLE
+ && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ final long childNodeId = AccessibilityNodeInfo.makeNodeId(
+ child.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
+ AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
+ if (provider == null) {
+ AccessibilityNodeInfo info = child.createAccessibilityNodeInfo();
+ if (info != null) {
+ outInfos.add(info);
+ addedChildren.put(child, null);
+ }
+ } else {
+ AccessibilityNodeInfo info = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeInfo.UNDEFINED);
+ if (info != null) {
+ outInfos.add(info);
+ addedChildren.put(child, info);
+ }
+ }
+ }
+ }
+ if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) {
+ View addedChild = entry.getKey();
+ AccessibilityNodeInfo virtualRoot = entry.getValue();
+ if (virtualRoot == null) {
+ prefetchDescendantsOfRealNode(addedChild, outInfos);
+ } else {
+ AccessibilityNodeProvider provider =
+ addedChild.getAccessibilityNodeProvider();
+ prefetchDescendantsOfVirtualNode(virtualRoot, provider, outInfos);
+ }
+ }
+ }
}
}
- private void addAndCacheNotCachedPredecessorInfos(long interrogatingPid, View view,
+ private void prefetchPredecessorsOfVirtualNode(AccessibilityNodeInfo root,
+ View providerHost, AccessibilityNodeProvider provider,
List<AccessibilityNodeInfo> outInfos) {
- ViewParent predecessor = view.getParent();
- while (predecessor instanceof View
- && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
- View predecessorView = (View) predecessor;
- addAndCacheNotCachedNodeInfo(interrogatingPid, predecessorView, outInfos);
- predecessor = predecessor.getParent();
+ long parentNodeId = root.getParentNodeId();
+ int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
+ while (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+ final int virtualDescendantId =
+ AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
+ if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED
+ || accessibilityViewId == providerHost.getAccessibilityViewId()) {
+ AccessibilityNodeInfo parent = provider.createAccessibilityNodeInfo(
+ virtualDescendantId);
+ if (parent != null) {
+ outInfos.add(parent);
+ }
+ parentNodeId = parent.getParentNodeId();
+ accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+ parentNodeId);
+ } else {
+ prefetchPredecessorsOfRealNode(providerHost, outInfos);
+ return;
+ }
}
}
- private void addAndCacheNotCachedDescendantInfos(long interrogatingPid, View view,
- List<AccessibilityNodeInfo> outInfos) {
- if (outInfos.size() > MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE
- || view.getAccessibilityNodeProvider() != null) {
- return;
+ private void prefetchSiblingsOfVirtualNode(AccessibilityNodeInfo current, View providerHost,
+ AccessibilityNodeProvider provider, List<AccessibilityNodeInfo> outInfos) {
+ final long parentNodeId = current.getParentNodeId();
+ final int parentAccessibilityViewId =
+ AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
+ final int parentVirtualDescendantId =
+ AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
+ if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED
+ || parentAccessibilityViewId == providerHost.getAccessibilityViewId()) {
+ AccessibilityNodeInfo parent =
+ provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
+ if (parent != null) {
+ SparseLongArray childNodeIds = parent.getChildNodeIds();
+ final int childCount = childNodeIds.size();
+ for (int i = 0; i < childCount; i++) {
+ final long childNodeId = childNodeIds.get(i);
+ if (childNodeId != current.getSourceNodeId()
+ && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ final int childVirtualDescendantId =
+ AccessibilityNodeInfo.getVirtualDescendantId(childNodeId);
+ AccessibilityNodeInfo child = provider.createAccessibilityNodeInfo(
+ childVirtualDescendantId);
+ if (child != null) {
+ outInfos.add(child);
+ }
+ }
+ }
+ }
+ } else {
+ prefetchSiblingsOfRealNode(providerHost, outInfos);
+ }
+ }
+
+ private void prefetchDescendantsOfVirtualNode(AccessibilityNodeInfo root,
+ AccessibilityNodeProvider provider, List<AccessibilityNodeInfo> outInfos) {
+ SparseLongArray childNodeIds = root.getChildNodeIds();
+ final int initialOutInfosSize = outInfos.size();
+ final int childCount = childNodeIds.size();
+ for (int i = 0; i < childCount; i++) {
+ if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ final long childNodeId = childNodeIds.get(i);
+ AccessibilityNodeInfo child = provider.createAccessibilityNodeInfo(
+ AccessibilityNodeInfo.getVirtualDescendantId(childNodeId));
+ if (child != null) {
+ outInfos.add(child);
+ }
+ }
}
- addAndCacheNotCachedNodeInfo(interrogatingPid, view, outInfos);
- if (view instanceof ViewGroup) {
- ViewGroup rootGroup = (ViewGroup) view;
- final int childCount = rootGroup.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = rootGroup.getChildAt(i);
- addAndCacheNotCachedDescendantInfos(interrogatingPid, child, outInfos);
+ if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ final int addedChildCount = outInfos.size() - initialOutInfosSize;
+ for (int i = 0; i < addedChildCount; i++) {
+ AccessibilityNodeInfo child = outInfos.get(initialOutInfosSize + i);
+ prefetchDescendantsOfVirtualNode(child, provider, outInfos);
}
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 105c010d4be9..be74b312c1ea 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -24,7 +24,6 @@ import android.os.SystemClock;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
-import android.view.AccessibilityNodeInfoCache;
import java.util.ArrayList;
import java.util.Collections;
@@ -102,7 +101,7 @@ public final class AccessibilityInteractionClient
// The connection cache is shared between all interrogating threads since
// at any given time there is only one window allowing querying.
private static final AccessibilityNodeInfoCache sAccessibilityNodeInfoCache =
- AccessibilityNodeInfoCache.newSynchronizedAccessibilityNodeInfoCache();
+ new AccessibilityNodeInfoCache();
/**
* @return The client for the current thread.
@@ -159,10 +158,11 @@ public final class AccessibilityInteractionClient
* where to start the search. Use
* {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
+ * @param prefetchFlags flags to guide prefetching.
* @return An {@link AccessibilityNodeInfo} if found, null otherwise.
*/
public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int connectionId,
- int accessibilityWindowId, long accessibilityNodeId) {
+ int accessibilityWindowId, long accessibilityNodeId, int prefetchFlags) {
try {
IAccessibilityServiceConnection connection = getConnection(connectionId);
if (connection != null) {
@@ -174,7 +174,7 @@ public final class AccessibilityInteractionClient
final int interactionId = mInteractionIdCounter.getAndIncrement();
final float windowScale = connection.findAccessibilityNodeInfoByAccessibilityId(
accessibilityWindowId, accessibilityNodeId, interactionId, this,
- Thread.currentThread().getId());
+ Thread.currentThread().getId(), prefetchFlags);
// If the scale is zero the call has failed.
if (windowScale > 0) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 84ad268f59e1..c094fda58a46 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -61,6 +61,15 @@ public class AccessibilityNodeInfo implements Parcelable {
/** @hide */
public static final int ACTIVE_WINDOW_ID = UNDEFINED;
+ /** @hide */
+ public static final int FLAG_PREFETCH_PREDECESSORS = 0x00000001;
+
+ /** @hide */
+ public static final int FLAG_PREFETCH_SIBLINGS = 0x00000002;
+
+ /** @hide */
+ public static final int FLAG_PREFETCH_DESCENDANTS = 0x00000003;
+
// Actions.
/**
@@ -181,7 +190,7 @@ public class AccessibilityNodeInfo implements Parcelable {
private CharSequence mText;
private CharSequence mContentDescription;
- private SparseLongArray mChildIds = new SparseLongArray();
+ private SparseLongArray mChildNodeIds = new SparseLongArray();
private int mActions;
private int mConnectionId = UNDEFINED;
@@ -244,12 +253,21 @@ public class AccessibilityNodeInfo implements Parcelable {
}
/**
+ * @return The ids of the children.
+ *
+ * @hide
+ */
+ public SparseLongArray getChildNodeIds() {
+ return mChildNodeIds;
+ }
+
+ /**
* Gets the number of children.
*
* @return The child count.
*/
public int getChildCount() {
- return mChildIds.size();
+ return mChildNodeIds.size();
}
/**
@@ -271,9 +289,10 @@ public class AccessibilityNodeInfo implements Parcelable {
if (!canPerformRequestOverConnection(mSourceNodeId)) {
return null;
}
- final long childId = mChildIds.get(index);
+ final long childId = mChildNodeIds.get(index);
AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
- return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mWindowId, childId);
+ return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mWindowId,
+ childId, FLAG_PREFETCH_DESCENDANTS);
}
/**
@@ -308,11 +327,11 @@ public class AccessibilityNodeInfo implements Parcelable {
*/
public void addChild(View root, int virtualDescendantId) {
enforceNotSealed();
- final int index = mChildIds.size();
+ final int index = mChildNodeIds.size();
final int rootAccessibilityViewId =
(root != null) ? root.getAccessibilityViewId() : UNDEFINED;
final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
- mChildIds.put(index, childNodeId);
+ mChildNodeIds.put(index, childNodeId);
}
/**
@@ -408,7 +427,16 @@ public class AccessibilityNodeInfo implements Parcelable {
}
AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
- mWindowId, mParentNodeId);
+ mWindowId, mParentNodeId, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+ }
+
+ /**
+ * @return The parent node id.
+ *
+ * @hide
+ */
+ public long getParentNodeId() {
+ return mParentNodeId;
}
/**
@@ -1070,7 +1098,7 @@ public class AccessibilityNodeInfo implements Parcelable {
parcel.writeLong(mParentNodeId);
parcel.writeInt(mConnectionId);
- SparseLongArray childIds = mChildIds;
+ SparseLongArray childIds = mChildNodeIds;
final int childIdsSize = childIds.size();
parcel.writeInt(childIdsSize);
for (int i = 0; i < childIdsSize; i++) {
@@ -1120,7 +1148,7 @@ public class AccessibilityNodeInfo implements Parcelable {
mContentDescription = other.mContentDescription;
mActions= other.mActions;
mBooleanProperties = other.mBooleanProperties;
- mChildIds = other.mChildIds.clone();
+ mChildNodeIds = other.mChildNodeIds.clone();
}
/**
@@ -1135,7 +1163,7 @@ public class AccessibilityNodeInfo implements Parcelable {
mParentNodeId = parcel.readLong();
mConnectionId = parcel.readInt();
- SparseLongArray childIds = mChildIds;
+ SparseLongArray childIds = mChildNodeIds;
final int childrenSize = parcel.readInt();
for (int i = 0; i < childrenSize; i++) {
final long childId = parcel.readLong();
@@ -1171,7 +1199,7 @@ public class AccessibilityNodeInfo implements Parcelable {
mParentNodeId = ROOT_NODE_ID;
mWindowId = UNDEFINED;
mConnectionId = UNDEFINED;
- mChildIds.clear();
+ mChildNodeIds.clear();
mBoundsInParent.set(0, 0, 0, 0);
mBoundsInScreen.set(0, 0, 0, 0);
mBooleanProperties = 0;
@@ -1249,7 +1277,7 @@ public class AccessibilityNodeInfo implements Parcelable {
builder.append("; accessibilityViewId: " + getAccessibilityViewId(mSourceNodeId));
builder.append("; virtualDescendantId: " + getVirtualDescendantId(mSourceNodeId));
builder.append("; mParentNodeId: " + mParentNodeId);
- SparseLongArray childIds = mChildIds;
+ SparseLongArray childIds = mChildNodeIds;
builder.append("; childAccessibilityIds: [");
for (int i = 0, count = childIds.size(); i < count; i++) {
builder.append(childIds.valueAt(i));
diff --git a/core/java/android/view/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
index 84b510d8c7ef..dfbfc7091acf 100644
--- a/core/java/android/view/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
@@ -14,13 +14,10 @@
* limitations under the License.
*/
-package android.view;
+package android.view.accessibility;
-import android.os.Process;
import android.util.Log;
import android.util.LongSparseArray;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
/**
* Simple cache for AccessibilityNodeInfos. The cache is mapping an
@@ -38,53 +35,11 @@ public class AccessibilityNodeInfoCache {
private static final boolean DEBUG = false;
- /**
- * @return A new <strong>not synchronized</strong> AccessibilityNodeInfoCache.
- */
- public static AccessibilityNodeInfoCache newAccessibilityNodeInfoCache() {
- return new AccessibilityNodeInfoCache();
- }
-
- /**
- * @return A new <strong>synchronized</strong> AccessibilityNodeInfoCache.
- */
- public static AccessibilityNodeInfoCache newSynchronizedAccessibilityNodeInfoCache() {
- return new AccessibilityNodeInfoCache() {
- private final Object mLock = new Object();
-
- @Override
- public void clear() {
- synchronized(mLock) {
- super.clear();
- }
- }
-
- @Override
- public AccessibilityNodeInfo get(long accessibilityNodeId) {
- synchronized(mLock) {
- return super.get(accessibilityNodeId);
- }
- }
-
- @Override
- public void put(long accessibilityNodeId, AccessibilityNodeInfo info) {
- synchronized(mLock) {
- super.put(accessibilityNodeId, info);
- }
- }
-
- @Override
- public void remove(long accessibilityNodeId) {
- synchronized(mLock) {
- super.remove(accessibilityNodeId);
- }
- }
- };
- }
+ private final Object mLock = new Object();
private final LongSparseArray<AccessibilityNodeInfo> mCacheImpl;
- private AccessibilityNodeInfoCache() {
+ public AccessibilityNodeInfoCache() {
if (ENABLED) {
mCacheImpl = new LongSparseArray<AccessibilityNodeInfo>();
} else {
@@ -124,13 +79,17 @@ public class AccessibilityNodeInfoCache {
*/
public AccessibilityNodeInfo get(long accessibilityNodeId) {
if (ENABLED) {
- if (DEBUG) {
+ synchronized(mLock) {
AccessibilityNodeInfo info = mCacheImpl.get(accessibilityNodeId);
- Log.i(LOG_TAG, "Process: " + Process.myPid() +
- " get(" + accessibilityNodeId + ") = " + info);
+ if (info != null) {
+ // Return a copy since the client calls to AccessibilityNodeInfo#recycle()
+ // will wipe the data of the cached info.
+ info = AccessibilityNodeInfo.obtain(info);
+ }
+ if (DEBUG) {
+ Log.i(LOG_TAG, "get(" + accessibilityNodeId + ") = " + info);
+ }
return info;
- } else {
- return mCacheImpl.get(accessibilityNodeId);
}
} else {
return null;
@@ -145,11 +104,15 @@ public class AccessibilityNodeInfoCache {
*/
public void put(long accessibilityNodeId, AccessibilityNodeInfo info) {
if (ENABLED) {
- if (DEBUG) {
- Log.i(LOG_TAG, "Process: " + Process.myPid()
- + " put(" + accessibilityNodeId + ", " + info + ")");
+ synchronized(mLock) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "put(" + accessibilityNodeId + ", " + info + ")");
+ }
+ // Cache a copy since the client calls to AccessibilityNodeInfo#recycle()
+ // will wipe the data of the cached info.
+ AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
+ mCacheImpl.put(accessibilityNodeId, clone);
}
- mCacheImpl.put(accessibilityNodeId, info);
}
}
@@ -161,7 +124,9 @@ public class AccessibilityNodeInfoCache {
*/
public boolean containsKey(long accessibilityNodeId) {
if (ENABLED) {
- return (mCacheImpl.indexOfKey(accessibilityNodeId) >= 0);
+ synchronized(mLock) {
+ return (mCacheImpl.indexOfKey(accessibilityNodeId) >= 0);
+ }
} else {
return false;
}
@@ -174,11 +139,12 @@ public class AccessibilityNodeInfoCache {
*/
public void remove(long accessibilityNodeId) {
if (ENABLED) {
- if (DEBUG) {
- Log.i(LOG_TAG, "Process: " + Process.myPid()
- + " remove(" + accessibilityNodeId + ")");
+ synchronized(mLock) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "remove(" + accessibilityNodeId + ")");
+ }
+ mCacheImpl.remove(accessibilityNodeId);
}
- mCacheImpl.remove(accessibilityNodeId);
}
}
@@ -187,10 +153,18 @@ public class AccessibilityNodeInfoCache {
*/
public void clear() {
if (ENABLED) {
- if (DEBUG) {
- Log.i(LOG_TAG, "Process: " + Process.myPid() + "clear()");
+ synchronized(mLock) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "clear()");
+ }
+ // Recycle the nodes before clearing the cache.
+ final int nodeCount = mCacheImpl.size();
+ for (int i = 0; i < nodeCount; i++) {
+ AccessibilityNodeInfo info = mCacheImpl.valueAt(i);
+ info.recycle();
+ }
+ mCacheImpl.clear();
}
- mCacheImpl.clear();
}
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index b60f50eb5d9d..23b235cbe395 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -56,6 +56,11 @@ public class AccessibilityRecord {
private static final int PROPERTY_FULL_SCREEN = 0x00000080;
private static final int PROPERTY_SCROLLABLE = 0x00000100;
+ private static final int GET_SOURCE_PREFETCH_FLAGS =
+ AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS
+ | AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS
+ | AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS;
+
// Housekeeping
private static final int MAX_POOL_SIZE = 10;
private static final Object sPoolLock = new Object();
@@ -144,7 +149,7 @@ public class AccessibilityRecord {
}
AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
- mSourceNodeId);
+ mSourceNodeId, GET_SOURCE_PREFETCH_FLAGS);
}
/**
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
index ae6869cad9f5..fc3651c6451f 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl
@@ -28,7 +28,7 @@ import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
oneway interface IAccessibilityInteractionConnection {
void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback,
+ IAccessibilityInteractionConnectionCallback callback, int prefetchFlags,
int interrogatingPid, long interrogatingTid);
void findAccessibilityNodeInfoByViewId(long accessibilityNodeId, int id, int interactionId,
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index c51d2440f893..b6b27c126dc5 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -26,7 +26,6 @@ import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -198,7 +197,31 @@ public final class InputMethodManager {
static final Object mInstanceSync = new Object();
static InputMethodManager mInstance;
-
+
+ /**
+ * @hide Flag for IInputMethodManager.windowGainedFocus: a view in
+ * the window has input focus.
+ */
+ public static final int CONTROL_WINDOW_VIEW_HAS_FOCUS = 1<<0;
+
+ /**
+ * @hide Flag for IInputMethodManager.windowGainedFocus: the focus
+ * is a text editor.
+ */
+ public static final int CONTROL_WINDOW_IS_TEXT_EDITOR = 1<<1;
+
+ /**
+ * @hide Flag for IInputMethodManager.windowGainedFocus: this is the first
+ * time the window has gotten focus.
+ */
+ public static final int CONTROL_WINDOW_FIRST = 1<<2;
+
+ /**
+ * @hide Flag for IInputMethodManager.startInput: this is the first
+ * time the window has gotten focus.
+ */
+ public static final int CONTROL_START_INITIAL = 1<<8;
+
final IInputMethodManager mService;
final Looper mMainLooper;
@@ -216,7 +239,7 @@ public final class InputMethodManager {
/**
* Set whenever this client becomes inactive, to know we need to reset
- * state with the IME then next time we receive focus.
+ * state with the IME the next time we receive focus.
*/
boolean mHasBeenInactive = true;
@@ -243,11 +266,6 @@ public final class InputMethodManager {
*/
View mNextServedView;
/**
- * True if we should restart input in the next served view, even if the
- * view hasn't actually changed from the current serve view.
- */
- boolean mNextServedNeedsStart;
- /**
* This is set when we are in the process of connecting, to determine
* when we have actually finished.
*/
@@ -331,7 +349,7 @@ public final class InputMethodManager {
mCurId = res.id;
mBindSequence = res.sequence;
}
- startInputInner();
+ startInputInner(null, 0, 0, 0);
return;
}
case MSG_UNBIND: {
@@ -362,7 +380,7 @@ public final class InputMethodManager {
}
}
if (startInput) {
- startInputInner();
+ startInputInner(null, 0, 0, 0);
}
return;
}
@@ -957,10 +975,11 @@ public final class InputMethodManager {
mServedConnecting = true;
}
- startInputInner();
+ startInputInner(null, 0, 0, 0);
}
- void startInputInner() {
+ boolean startInputInner(IBinder windowGainingFocus, int controlFlags, int softInputMode,
+ int windowFlags) {
final View view;
synchronized (mH) {
view = mServedView;
@@ -969,7 +988,7 @@ public final class InputMethodManager {
if (DEBUG) Log.v(TAG, "Starting input: view=" + view);
if (view == null) {
if (DEBUG) Log.v(TAG, "ABORT input: no served view!");
- return;
+ return false;
}
}
@@ -982,7 +1001,7 @@ public final class InputMethodManager {
// If the view doesn't have a handler, something has changed out
// from under us, so just bail.
if (DEBUG) Log.v(TAG, "ABORT input: no handler for view!");
- return;
+ return false;
}
if (vh.getLooper() != Looper.myLooper()) {
// The view is running on a different thread than our own, so
@@ -990,10 +1009,10 @@ public final class InputMethodManager {
if (DEBUG) Log.v(TAG, "Starting input: reschedule to view thread");
vh.post(new Runnable() {
public void run() {
- startInputInner();
+ startInputInner(null, 0, 0, 0);
}
});
- return;
+ return false;
}
// Okay we are now ready to call into the served view and have it
@@ -1013,12 +1032,14 @@ public final class InputMethodManager {
if (DEBUG) Log.v(TAG,
"Starting input: finished by someone else (view="
+ mServedView + " conn=" + mServedConnecting + ")");
- return;
+ return false;
}
-
+
// If we already have a text box, then this view is already
// connected so we want to restart it.
- final boolean initial = mCurrentTextBoxAttribute == null;
+ if (mCurrentTextBoxAttribute == null) {
+ controlFlags |= CONTROL_START_INITIAL;
+ }
// Hook 'em up and let 'er rip.
mCurrentTextBoxAttribute = tba;
@@ -1040,9 +1061,17 @@ public final class InputMethodManager {
try {
if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic="
- + ic + " tba=" + tba + " initial=" + initial);
- InputBindResult res = mService.startInput(mClient,
- servedContext, tba, initial, true);
+ + ic + " tba=" + tba + " controlFlags=#"
+ + Integer.toHexString(controlFlags));
+ InputBindResult res;
+ if (windowGainingFocus != null) {
+ res = mService.windowGainedFocus(mClient, windowGainingFocus,
+ controlFlags, softInputMode, windowFlags,
+ tba, servedContext);
+ } else {
+ res = mService.startInput(mClient,
+ servedContext, tba, controlFlags);
+ }
if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
if (res != null) {
if (res.id != null) {
@@ -1051,7 +1080,7 @@ public final class InputMethodManager {
} else if (mCurMethod == null) {
// This means there is no input method available.
if (DEBUG) Log.v(TAG, "ABORT input: no input method!");
- return;
+ return true;
}
}
if (mCurMethod != null && mCompletions != null) {
@@ -1064,6 +1093,8 @@ public final class InputMethodManager {
Log.w(TAG, "IME died: " + mCurId, e);
}
}
+
+ return true;
}
/**
@@ -1139,27 +1170,26 @@ public final class InputMethodManager {
* @hide
*/
public void checkFocus() {
- if (checkFocusNoStartInput()) {
- startInputInner();
+ if (checkFocusNoStartInput(false)) {
+ startInputInner(null, 0, 0, 0);
}
}
- private boolean checkFocusNoStartInput() {
+ private boolean checkFocusNoStartInput(boolean forceNewFocus) {
// This is called a lot, so short-circuit before locking.
- if (mServedView == mNextServedView && !mNextServedNeedsStart) {
+ if (mServedView == mNextServedView && !forceNewFocus) {
return false;
}
InputConnection ic = null;
synchronized (mH) {
- if (mServedView == mNextServedView && !mNextServedNeedsStart) {
+ if (mServedView == mNextServedView && !forceNewFocus) {
return false;
}
if (DEBUG) Log.v(TAG, "checkFocus: view=" + mServedView
+ " next=" + mNextServedView
- + " restart=" + mNextServedNeedsStart);
+ + " forceNewFocus=" + forceNewFocus);
- mNextServedNeedsStart = false;
if (mNextServedView == null) {
finishInputLocked();
// In this case, we used to have a focused view on the window,
@@ -1190,13 +1220,14 @@ public final class InputMethodManager {
} catch (RemoteException e) {
}
}
-
+
/**
* Called by ViewAncestor when its window gets input focus.
* @hide
*/
public void onWindowFocus(View rootView, View focusedView, int softInputMode,
boolean first, int windowFlags) {
+ boolean forceNewFocus = false;
synchronized (mH) {
if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView
+ " softInputMode=" + softInputMode
@@ -1205,27 +1236,42 @@ public final class InputMethodManager {
if (mHasBeenInactive) {
if (DEBUG) Log.v(TAG, "Has been inactive! Starting fresh");
mHasBeenInactive = false;
- mNextServedNeedsStart = true;
+ forceNewFocus = true;
}
focusInLocked(focusedView != null ? focusedView : rootView);
}
+
+ int controlFlags = 0;
+ if (focusedView != null) {
+ controlFlags |= CONTROL_WINDOW_VIEW_HAS_FOCUS;
+ if (focusedView.onCheckIsTextEditor()) {
+ controlFlags |= CONTROL_WINDOW_IS_TEXT_EDITOR;
+ }
+ }
+ if (first) {
+ controlFlags |= CONTROL_WINDOW_FIRST;
+ }
- boolean startInput = checkFocusNoStartInput();
+ if (checkFocusNoStartInput(forceNewFocus)) {
+ // We need to restart input on the current focus view. This
+ // should be done in conjunction with telling the system service
+ // about the window gaining focus, to help make the transition
+ // smooth.
+ if (startInputInner(rootView.getWindowToken(),
+ controlFlags, softInputMode, windowFlags)) {
+ return;
+ }
+ }
+ // For some reason we didn't do a startInput + windowFocusGain, so
+ // we'll just do a window focus gain and call it a day.
synchronized (mH) {
try {
- final boolean isTextEditor = focusedView != null &&
- focusedView.onCheckIsTextEditor();
mService.windowGainedFocus(mClient, rootView.getWindowToken(),
- focusedView != null, isTextEditor, softInputMode, first,
- windowFlags);
+ controlFlags, softInputMode, windowFlags, null, null);
} catch (RemoteException e) {
}
}
-
- if (startInput) {
- startInputInner();
- }
}
/** @hide */
@@ -1676,8 +1722,7 @@ public final class InputMethodManager {
p.println(" mCurMethod=" + mCurMethod);
p.println(" mCurRootView=" + mCurRootView);
p.println(" mServedView=" + mServedView);
- p.println(" mNextServedNeedsStart=" + mNextServedNeedsStart
- + " mNextServedView=" + mNextServedView);
+ p.println(" mNextServedView=" + mNextServedView);
p.println(" mServedConnecting=" + mServedConnecting);
if (mCurrentTextBoxAttribute != null) {
p.println(" mCurrentTextBoxAttribute:");
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 3613ec964d8f..8ccc59c78a9c 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -471,18 +471,6 @@ class BrowserFrame extends Handler {
}
/**
- * We have received an SSL certificate for the main top-level page.
- * Used by the Android HTTP stack only.
- */
- void certificate(SslCertificate certificate) {
- if (mIsMainFrame) {
- // we want to make this call even if the certificate is null
- // (ie, the site is not secure)
- mCallbackProxy.onReceivedCertificate(certificate);
- }
- }
-
- /**
* Destroy all native components of the BrowserFrame.
*/
public void destroy() {
@@ -515,10 +503,6 @@ class BrowserFrame extends Handler {
}
}
}
- if (!JniUtil.useChromiumHttpStack()) {
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_TRIM_CACHE);
- }
break;
}
@@ -767,10 +751,9 @@ class BrowserFrame extends Handler {
} else if (mSettings.getAllowContentAccess() &&
url.startsWith(ANDROID_CONTENT)) {
try {
- // Strip off mimetype, for compatibility with ContentLoader.java
- // If we don't do this, we can fail to load Gmail attachments,
- // because the URL being loaded doesn't exactly match the URL we
- // have permission to read.
+ // Strip off MIME type. If we don't do this, we can fail to
+ // load Gmail attachments, because the URL being loaded doesn't
+ // exactly match the URL we have permission to read.
int mimeIndex = url.lastIndexOf('?');
if (mimeIndex != -1) {
url = url.substring(0, mimeIndex);
@@ -787,101 +770,11 @@ class BrowserFrame extends Handler {
}
/**
- * Start loading a resource.
- * @param loaderHandle The native ResourceLoader that is the target of the
- * data.
- * @param url The url to load.
- * @param method The http method.
- * @param headers The http headers.
- * @param postData If the method is "POST" postData is sent as the request
- * body. Is null when empty.
- * @param postDataIdentifier If the post data contained form this is the form identifier, otherwise it is 0.
- * @param cacheMode The cache mode to use when loading this resource. See WebSettings.setCacheMode
- * @param mainResource True if the this resource is the main request, not a supporting resource
- * @param userGesture
- * @param synchronous True if the load is synchronous.
- * @return A newly created LoadListener object.
- */
- private LoadListener startLoadingResource(int loaderHandle,
- String url,
- String method,
- HashMap headers,
- byte[] postData,
- long postDataIdentifier,
- int cacheMode,
- boolean mainResource,
- boolean userGesture,
- boolean synchronous,
- String username,
- String password) {
- if (mSettings.getCacheMode() != WebSettings.LOAD_DEFAULT) {
- cacheMode = mSettings.getCacheMode();
- }
-
- if (method.equals("POST")) {
- // Don't use the cache on POSTs when issuing a normal POST
- // request.
- if (cacheMode == WebSettings.LOAD_NORMAL) {
- cacheMode = WebSettings.LOAD_NO_CACHE;
- }
- String[] ret = getUsernamePassword();
- if (ret != null) {
- String domUsername = ret[0];
- String domPassword = ret[1];
- maybeSavePassword(postData, domUsername, domPassword);
- }
- }
-
- // is this resource the main-frame top-level page?
- boolean isMainFramePage = mIsMainFrame;
-
- if (DebugFlags.BROWSER_FRAME) {
- Log.v(LOGTAG, "startLoadingResource: url=" + url + ", method="
- + method + ", postData=" + postData + ", isMainFramePage="
- + isMainFramePage + ", mainResource=" + mainResource
- + ", userGesture=" + userGesture);
- }
-
- // Create a LoadListener
- LoadListener loadListener = LoadListener.getLoadListener(mContext,
- this, url, loaderHandle, synchronous, isMainFramePage,
- mainResource, userGesture, postDataIdentifier, username, password);
-
- if (LoadListener.getNativeLoaderCount() > MAX_OUTSTANDING_REQUESTS) {
- // send an error message, so that loadListener can be deleted
- // after this is returned. This is important as LoadListener's
- // nativeError will remove the request from its DocLoader's request
- // list. But the set up is not done until this method is returned.
- loadListener.error(
- android.net.http.EventHandler.ERROR, mContext.getString(
- com.android.internal.R.string.httpErrorTooManyRequests));
- return loadListener;
- }
-
- // Note that we are intentionally skipping
- // inputStreamForAndroidResource. This is so that FrameLoader will use
- // the various StreamLoader classes to handle assets.
- FrameLoader loader = new FrameLoader(loadListener, mSettings, method,
- mCallbackProxy.shouldInterceptRequest(url));
- loader.setHeaders(headers);
- loader.setPostData(postData);
- // Set the load mode to the mode used for the current page.
- // If WebKit wants validation, go to network directly.
- loader.setCacheMode(headers.containsKey("If-Modified-Since")
- || headers.containsKey("If-None-Match") ?
- WebSettings.LOAD_NO_CACHE : cacheMode);
- loader.executeLoad();
- // Set referrer to current URL?
- return !synchronous ? loadListener : null;
- }
-
- /**
* If this looks like a POST request (form submission) containing a username
* and password, give the user the option of saving them. Will either do
* nothing, or block until the UI interaction is complete.
*
- * Called by startLoadingResource when using the Apache HTTP stack.
- * Called directly by WebKit when using the Chrome HTTP stack.
+ * Called directly by WebKit.
*
* @param postData The data about to be sent as the body of a POST request.
* @param username The username entered by the user (sniffed from the DOM).
diff --git a/core/java/android/webkit/CacheLoader.java b/core/java/android/webkit/CacheLoader.java
deleted file mode 100644
index 072104562f16..000000000000
--- a/core/java/android/webkit/CacheLoader.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.net.http.Headers;
-import android.text.TextUtils;
-import android.webkit.JniUtil;
-
-/**
- * This class is a concrete implementation of StreamLoader that uses a
- * CacheResult as the source for the stream. The CacheResult stored mimetype
- * and encoding is added to the HTTP response headers.
- */
-class CacheLoader extends StreamLoader {
-
- CacheManager.CacheResult mCacheResult; // Content source
-
- /**
- * Constructs a CacheLoader for use when loading content from the cache.
- *
- * @param loadListener LoadListener to pass the content to
- * @param result CacheResult used as the source for the content.
- */
- CacheLoader(LoadListener loadListener, CacheManager.CacheResult result) {
- super(loadListener);
-
- assert !JniUtil.useChromiumHttpStack();
-
- mCacheResult = result;
- }
-
- @Override
- protected boolean setupStreamAndSendStatus() {
- mDataStream = mCacheResult.inStream;
- mContentLength = mCacheResult.contentLength;
- mLoadListener.status(1, 1, mCacheResult.httpStatusCode, "OK");
- return true;
- }
-
- @Override
- protected void buildHeaders(Headers headers) {
- StringBuilder sb = new StringBuilder(mCacheResult.mimeType);
- if (!TextUtils.isEmpty(mCacheResult.encoding)) {
- sb.append(';');
- sb.append(mCacheResult.encoding);
- }
- headers.setContentType(sb.toString());
-
- if (!TextUtils.isEmpty(mCacheResult.location)) {
- headers.setLocation(mCacheResult.location);
- }
-
- if (!TextUtils.isEmpty(mCacheResult.expiresString)) {
- headers.setExpires(mCacheResult.expiresString);
- }
-
- if (!TextUtils.isEmpty(mCacheResult.contentdisposition)) {
- headers.setContentDisposition(mCacheResult.contentdisposition);
- }
-
- if (!TextUtils.isEmpty(mCacheResult.crossDomain)) {
- headers.setXPermittedCrossDomainPolicies(mCacheResult.crossDomain);
- }
- }
-}
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 36b4de16d36d..6a85e0026331 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -57,33 +57,8 @@ public final class CacheManager {
static final String HEADER_KEY_IFMODIFIEDSINCE = "if-modified-since";
static final String HEADER_KEY_IFNONEMATCH = "if-none-match";
- private static final String NO_STORE = "no-store";
- private static final String NO_CACHE = "no-cache";
- private static final String MAX_AGE = "max-age";
- private static final String MANIFEST_MIME = "text/cache-manifest";
-
- private static long CACHE_THRESHOLD = 6 * 1024 * 1024;
- private static long CACHE_TRIM_AMOUNT = 2 * 1024 * 1024;
-
- // Limit the maximum cache file size to half of the normal capacity
- static long CACHE_MAX_SIZE = (CACHE_THRESHOLD - CACHE_TRIM_AMOUNT) / 2;
-
- // Reference count the enable/disable transaction
- private static int mRefCount;
-
- // trimCacheIfNeeded() is called when a page is fully loaded. But JavaScript
- // can load the content, e.g. in a slideshow, continuously, so we need to
- // trim the cache on a timer base too. endCacheTransaction() is called on a
- // timer base. We share the same timer with less frequent update.
- private static int mTrimCacheCount = 0;
- private static final int TRIM_CACHE_INTERVAL = 5;
-
- private static WebViewDatabase mDataBase;
private static File mBaseDir;
- // Flag to clear the cache when the CacheManager is initialized
- private static boolean mClearCacheOnInit = false;
-
/**
* Represents a resource stored in the HTTP cache. Instances of this class
* can be obtained by calling
@@ -260,51 +235,12 @@ public final class CacheManager {
* @param context The application context
*/
static void init(Context context) {
- if (JniUtil.useChromiumHttpStack()) {
- // This isn't actually where the real cache lives, but where we put files for the
- // purpose of getCacheFile().
- mBaseDir = new File(context.getCacheDir(), "webviewCacheChromiumStaging");
- if (!mBaseDir.exists()) {
- mBaseDir.mkdirs();
- }
- return;
- }
-
- mDataBase = WebViewDatabase.getInstance(context.getApplicationContext());
- mBaseDir = new File(context.getCacheDir(), "webviewCache");
- if (createCacheDirectory() && mClearCacheOnInit) {
- removeAllCacheFiles();
- mClearCacheOnInit = false;
- }
- }
-
- /**
- * Create the cache directory if it does not already exist.
- *
- * @return true if the cache directory didn't exist and was created.
- */
- static private boolean createCacheDirectory() {
- assert !JniUtil.useChromiumHttpStack();
-
+ // This isn't actually where the real cache lives, but where we put files for the
+ // purpose of getCacheFile().
+ mBaseDir = new File(context.getCacheDir(), "webviewCacheChromiumStaging");
if (!mBaseDir.exists()) {
- if(!mBaseDir.mkdirs()) {
- Log.w(LOGTAG, "Unable to create webviewCache directory");
- return false;
- }
- FileUtils.setPermissions(
- mBaseDir.toString(),
- FileUtils.S_IRWXU | FileUtils.S_IRWXG,
- -1, -1);
- // If we did create the directory, we need to flush
- // the cache database. The directory could be recreated
- // because the system flushed all the data/cache directories
- // to free up disk space.
- // delete rows in the cache database
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_CLEAR_CACHE);
- return true;
+ mBaseDir.mkdirs();
}
- return false;
}
/**
@@ -329,51 +265,6 @@ public final class CacheManager {
return false;
}
- // only called from WebViewWorkerThread
- // make sure to call enableTransaction/disableTransaction in pair
- static boolean enableTransaction() {
- assert !JniUtil.useChromiumHttpStack();
-
- if (++mRefCount == 1) {
- mDataBase.startCacheTransaction();
- return true;
- }
- return false;
- }
-
- // only called from WebViewWorkerThread
- // make sure to call enableTransaction/disableTransaction in pair
- static boolean disableTransaction() {
- assert !JniUtil.useChromiumHttpStack();
-
- if (--mRefCount == 0) {
- mDataBase.endCacheTransaction();
- return true;
- }
- return false;
- }
-
- // only called from WebViewWorkerThread
- // make sure to call startTransaction/endTransaction in pair
- static boolean startTransaction() {
- assert !JniUtil.useChromiumHttpStack();
-
- return mDataBase.startCacheTransaction();
- }
-
- // only called from WebViewWorkerThread
- // make sure to call startTransaction/endTransaction in pair
- static boolean endTransaction() {
- assert !JniUtil.useChromiumHttpStack();
-
- boolean ret = mDataBase.endCacheTransaction();
- if (++mTrimCacheCount >= TRIM_CACHE_INTERVAL) {
- mTrimCacheCount = 0;
- trimCacheIfNeeded();
- }
- return ret;
- }
-
/**
* Starts a cache transaction. Returns true if this is the only running
* transaction. Otherwise, this transaction is nested inside currently
@@ -415,9 +306,8 @@ public final class CacheManager {
return getCacheFile(url, 0, headers);
}
- private static CacheResult getCacheFileChromiumHttpStack(String url) {
- assert JniUtil.useChromiumHttpStack();
-
+ static CacheResult getCacheFile(String url, long postIdentifier,
+ Map<String, String> headers) {
CacheResult result = nativeGetCacheResult(url);
if (result == null) {
return null;
@@ -435,49 +325,6 @@ public final class CacheManager {
// system. If it is gone, what should we do?
return null;
}
- return result;
- }
-
- private static CacheResult getCacheFileAndroidHttpStack(String url,
- long postIdentifier) {
- assert !JniUtil.useChromiumHttpStack();
-
- String databaseKey = getDatabaseKey(url, postIdentifier);
- CacheResult result = mDataBase.getCache(databaseKey);
- if (result == null) {
- return null;
- }
- if (result.contentLength == 0) {
- if (!isCachableRedirect(result.httpStatusCode)) {
- // This should not happen. If it does, remove it.
- mDataBase.removeCache(databaseKey);
- return null;
- }
- } else {
- File src = new File(mBaseDir, result.localPath);
- try {
- // Open the file here so that even if it is deleted, the content
- // is still readable by the caller until close() is called.
- result.inStream = new FileInputStream(src);
- } catch (FileNotFoundException e) {
- // The files in the cache directory can be removed by the
- // system. If it is gone, clean up the database.
- mDataBase.removeCache(databaseKey);
- return null;
- }
- }
- return result;
- }
-
- static CacheResult getCacheFile(String url, long postIdentifier,
- Map<String, String> headers) {
- CacheResult result = JniUtil.useChromiumHttpStack() ?
- getCacheFileChromiumHttpStack(url) :
- getCacheFileAndroidHttpStack(url, postIdentifier);
-
- if (result == null) {
- return null;
- }
// A null value for headers is used by CACHE_MODE_CACHE_ONLY to imply
// that we should provide the cache result even if it is expired.
@@ -516,66 +363,8 @@ public final class CacheManager {
*/
static CacheResult createCacheFile(String url, int statusCode,
Headers headers, String mimeType, boolean forceCache) {
- if (JniUtil.useChromiumHttpStack()) {
- // This method is public but hidden. We break functionality.
- return null;
- }
-
- return createCacheFile(url, statusCode, headers, mimeType, 0,
- forceCache);
- }
-
- static CacheResult createCacheFile(String url, int statusCode,
- Headers headers, String mimeType, long postIdentifier,
- boolean forceCache) {
- assert !JniUtil.useChromiumHttpStack();
-
- String databaseKey = getDatabaseKey(url, postIdentifier);
-
- // according to the rfc 2616, the 303 response MUST NOT be cached.
- if (statusCode == 303) {
- // remove the saved cache if there is any
- mDataBase.removeCache(databaseKey);
- return null;
- }
-
- // like the other browsers, do not cache redirects containing a cookie
- // header.
- if (isCachableRedirect(statusCode) && !headers.getSetCookie().isEmpty()) {
- // remove the saved cache if there is any
- mDataBase.removeCache(databaseKey);
- return null;
- }
-
- CacheResult ret = parseHeaders(statusCode, headers, mimeType);
- if (ret == null) {
- // this should only happen if the headers has "no-store" in the
- // cache-control. remove the saved cache if there is any
- mDataBase.removeCache(databaseKey);
- } else {
- setupFiles(databaseKey, ret);
- try {
- ret.outStream = new FileOutputStream(ret.outFile);
- } catch (FileNotFoundException e) {
- // This can happen with the system did a purge and our
- // subdirectory has gone, so lets try to create it again
- if (createCacheDirectory()) {
- try {
- ret.outStream = new FileOutputStream(ret.outFile);
- } catch (FileNotFoundException e2) {
- // We failed to create the file again, so there
- // is something else wrong. Return null.
- return null;
- }
- } else {
- // Failed to create cache directory
- return null;
- }
- }
- ret.mimeType = mimeType;
- }
-
- return ret;
+ // This method is public but hidden. We break functionality.
+ return null;
}
/**
@@ -598,64 +387,24 @@ public final class CacheManager {
return;
}
- if (JniUtil.useChromiumHttpStack()) {
- // This method is exposed in the public API but the API provides no
- // way to obtain a new CacheResult object with a non-null output
- // stream ...
- // - CacheResult objects returned by getCacheFile() have a null
- // output stream.
- // - new CacheResult objects have a null output stream and no
- // setter is provided.
- // Since this method throws a null pointer exception in this case,
- // it is effectively useless from the point of view of the public
- // API.
- //
- // With the Chromium HTTP stack we continue to throw the same
- // exception for 'backwards compatibility' with the Android HTTP
- // stack.
- //
- // This method is not used from within this package with the
- // Chromium HTTP stack, and for public API use, we should already
- // have thrown an exception above.
- assert false;
- return;
- }
-
- if (!cacheRet.outFile.exists()) {
- // the file in the cache directory can be removed by the system
- return;
- }
-
- boolean redirect = isCachableRedirect(cacheRet.httpStatusCode);
- if (redirect) {
- // location is in database, no need to keep the file
- cacheRet.contentLength = 0;
- cacheRet.localPath = "";
- }
- if ((redirect || cacheRet.contentLength == 0)
- && !cacheRet.outFile.delete()) {
- Log.e(LOGTAG, cacheRet.outFile.getPath() + " delete failed.");
- }
- if (cacheRet.contentLength == 0) {
- return;
- }
-
- mDataBase.addCache(getDatabaseKey(url, postIdentifier), cacheRet);
-
- if (DebugFlags.CACHE_MANAGER) {
- Log.v(LOGTAG, "saveCacheFile for url " + url);
- }
- }
-
- static boolean cleanupCacheFile(CacheResult cacheRet) {
- assert !JniUtil.useChromiumHttpStack();
-
- try {
- cacheRet.outStream.close();
- } catch (IOException e) {
- return false;
- }
- return cacheRet.outFile.delete();
+ // This method is exposed in the public API but the API provides no
+ // way to obtain a new CacheResult object with a non-null output
+ // stream ...
+ // - CacheResult objects returned by getCacheFile() have a null
+ // output stream.
+ // - new CacheResult objects have a null output stream and no
+ // setter is provided.
+ // Since this method throws a null pointer exception in this case,
+ // it is effectively useless from the point of view of the public
+ // API.
+ //
+ // With the Chromium HTTP stack we continue to throw the same
+ // exception for 'backwards compatibility' with the Android HTTP
+ // stack.
+ //
+ // This method is not used from within this package, and for public API
+ // use, we should already have thrown an exception above.
+ assert false;
}
/**
@@ -664,21 +413,6 @@ public final class CacheManager {
* @return Whether the removal succeeded.
*/
static boolean removeAllCacheFiles() {
- // Note, this is called before init() when the database is
- // created or upgraded.
- if (mBaseDir == null) {
- // This method should not be called before init() when using the
- // chrome http stack
- assert !JniUtil.useChromiumHttpStack();
- // Init() has not been called yet, so just flag that
- // we need to clear the cache when init() is called.
- mClearCacheOnInit = true;
- return true;
- }
- // delete rows in the cache database
- if (!JniUtil.useChromiumHttpStack())
- WebViewWorker.getHandler().sendEmptyMessage(WebViewWorker.MSG_CLEAR_CACHE);
-
// delete cache files in a separate thread to not block UI.
final Runnable clearCache = new Runnable() {
public void run() {
@@ -703,323 +437,5 @@ public final class CacheManager {
return true;
}
- static void trimCacheIfNeeded() {
- assert !JniUtil.useChromiumHttpStack();
-
- if (mDataBase.getCacheTotalSize() > CACHE_THRESHOLD) {
- List<String> pathList = mDataBase.trimCache(CACHE_TRIM_AMOUNT);
- int size = pathList.size();
- for (int i = 0; i < size; i++) {
- File f = new File(mBaseDir, pathList.get(i));
- if (!f.delete()) {
- Log.e(LOGTAG, f.getPath() + " delete failed.");
- }
- }
- // remove the unreferenced files in the cache directory
- final List<String> fileList = mDataBase.getAllCacheFileNames();
- if (fileList == null) return;
- String[] toDelete = mBaseDir.list(new FilenameFilter() {
- public boolean accept(File dir, String filename) {
- if (fileList.contains(filename)) {
- return false;
- } else {
- return true;
- }
- }
- });
- if (toDelete == null) return;
- size = toDelete.length;
- for (int i = 0; i < size; i++) {
- File f = new File(mBaseDir, toDelete[i]);
- if (!f.delete()) {
- Log.e(LOGTAG, f.getPath() + " delete failed.");
- }
- }
- }
- }
-
- static void clearCache() {
- assert !JniUtil.useChromiumHttpStack();
-
- // delete database
- mDataBase.clearCache();
- }
-
- private static boolean isCachableRedirect(int statusCode) {
- if (statusCode == 301 || statusCode == 302 || statusCode == 307) {
- // as 303 can't be cached, we do not return true
- return true;
- } else {
- return false;
- }
- }
-
- private static String getDatabaseKey(String url, long postIdentifier) {
- assert !JniUtil.useChromiumHttpStack();
-
- if (postIdentifier == 0) return url;
- return postIdentifier + url;
- }
-
- @SuppressWarnings("deprecation")
- private static void setupFiles(String url, CacheResult cacheRet) {
- assert !JniUtil.useChromiumHttpStack();
-
- if (true) {
- // Note: SHA1 is much stronger hash. But the cost of setupFiles() is
- // 3.2% cpu time for a fresh load of nytimes.com. While a simple
- // String.hashCode() is only 0.6%. If adding the collision resolving
- // to String.hashCode(), it makes the cpu time to be 1.6% for a
- // fresh load, but 5.3% for the worst case where all the files
- // already exist in the file system, but database is gone. So it
- // needs to resolve collision for every file at least once.
- int hashCode = url.hashCode();
- StringBuffer ret = new StringBuffer(8);
- appendAsHex(hashCode, ret);
- String path = ret.toString();
- File file = new File(mBaseDir, path);
- if (true) {
- boolean checkOldPath = true;
- // Check hash collision. If the hash file doesn't exist, just
- // continue. There is a chance that the old cache file is not
- // same as the hash file. As mDataBase.getCache() is more
- // expansive than "leak" a file until clear cache, don't bother.
- // If the hash file exists, make sure that it is same as the
- // cache file. If it is not, resolve the collision.
- while (file.exists()) {
- if (checkOldPath) {
- CacheResult oldResult = mDataBase.getCache(url);
- if (oldResult != null && oldResult.contentLength > 0) {
- if (path.equals(oldResult.localPath)) {
- path = oldResult.localPath;
- } else {
- path = oldResult.localPath;
- file = new File(mBaseDir, path);
- }
- break;
- }
- checkOldPath = false;
- }
- ret = new StringBuffer(8);
- appendAsHex(++hashCode, ret);
- path = ret.toString();
- file = new File(mBaseDir, path);
- }
- }
- cacheRet.localPath = path;
- cacheRet.outFile = file;
- } else {
- // get hash in byte[]
- Digest digest = new SHA1Digest();
- int digestLen = digest.getDigestSize();
- byte[] hash = new byte[digestLen];
- int urlLen = url.length();
- byte[] data = new byte[urlLen];
- url.getBytes(0, urlLen, data, 0);
- digest.update(data, 0, urlLen);
- digest.doFinal(hash, 0);
- // convert byte[] to hex String
- StringBuffer result = new StringBuffer(2 * digestLen);
- for (int i = 0; i < digestLen; i = i + 4) {
- int h = (0x00ff & hash[i]) << 24 | (0x00ff & hash[i + 1]) << 16
- | (0x00ff & hash[i + 2]) << 8 | (0x00ff & hash[i + 3]);
- appendAsHex(h, result);
- }
- cacheRet.localPath = result.toString();
- cacheRet.outFile = new File(mBaseDir, cacheRet.localPath);
- }
- }
-
- private static void appendAsHex(int i, StringBuffer ret) {
- assert !JniUtil.useChromiumHttpStack();
-
- String hex = Integer.toHexString(i);
- switch (hex.length()) {
- case 1:
- ret.append("0000000");
- break;
- case 2:
- ret.append("000000");
- break;
- case 3:
- ret.append("00000");
- break;
- case 4:
- ret.append("0000");
- break;
- case 5:
- ret.append("000");
- break;
- case 6:
- ret.append("00");
- break;
- case 7:
- ret.append("0");
- break;
- }
- ret.append(hex);
- }
-
- private static CacheResult parseHeaders(int statusCode, Headers headers,
- String mimeType) {
- assert !JniUtil.useChromiumHttpStack();
-
- // if the contentLength is already larger than CACHE_MAX_SIZE, skip it
- if (headers.getContentLength() > CACHE_MAX_SIZE) return null;
-
- // The HTML 5 spec, section 6.9.4, step 7.3 of the application cache
- // process states that HTTP caching rules are ignored for the
- // purposes of the application cache download process.
- // At this point we can't tell that if a file is part of this process,
- // except for the manifest, which has its own mimeType.
- // TODO: work out a way to distinguish all responses that are part of
- // the application download process and skip them.
- if (MANIFEST_MIME.equals(mimeType)) return null;
-
- // TODO: if authenticated or secure, return null
- CacheResult ret = new CacheResult();
- ret.httpStatusCode = statusCode;
-
- ret.location = headers.getLocation();
-
- ret.expires = -1;
- ret.expiresString = headers.getExpires();
- if (ret.expiresString != null) {
- try {
- ret.expires = AndroidHttpClient.parseDate(ret.expiresString);
- } catch (IllegalArgumentException ex) {
- // Take care of the special "-1" and "0" cases
- if ("-1".equals(ret.expiresString)
- || "0".equals(ret.expiresString)) {
- // make it expired, but can be used for history navigation
- ret.expires = 0;
- } else {
- Log.e(LOGTAG, "illegal expires: " + ret.expiresString);
- }
- }
- }
-
- ret.contentdisposition = headers.getContentDisposition();
-
- ret.crossDomain = headers.getXPermittedCrossDomainPolicies();
-
- // lastModified and etag may be set back to http header. So they can't
- // be empty string.
- String lastModified = headers.getLastModified();
- if (lastModified != null && lastModified.length() > 0) {
- ret.lastModified = lastModified;
- }
-
- String etag = headers.getEtag();
- if (etag != null && etag.length() > 0) {
- ret.etag = etag;
- }
-
- String cacheControl = headers.getCacheControl();
- if (cacheControl != null) {
- String[] controls = cacheControl.toLowerCase().split("[ ,;]");
- boolean noCache = false;
- for (int i = 0; i < controls.length; i++) {
- if (NO_STORE.equals(controls[i])) {
- return null;
- }
- // According to the spec, 'no-cache' means that the content
- // must be re-validated on every load. It does not mean that
- // the content can not be cached. set to expire 0 means it
- // can only be used in CACHE_MODE_CACHE_ONLY case
- if (NO_CACHE.equals(controls[i])) {
- ret.expires = 0;
- noCache = true;
- // if cache control = no-cache has been received, ignore max-age
- // header, according to http spec:
- // If a request includes the no-cache directive, it SHOULD NOT
- // include min-fresh, max-stale, or max-age.
- } else if (controls[i].startsWith(MAX_AGE) && !noCache) {
- int separator = controls[i].indexOf('=');
- if (separator < 0) {
- separator = controls[i].indexOf(':');
- }
- if (separator > 0) {
- String s = controls[i].substring(separator + 1);
- try {
- long sec = Long.parseLong(s);
- if (sec >= 0) {
- ret.expires = System.currentTimeMillis() + 1000
- * sec;
- }
- } catch (NumberFormatException ex) {
- if ("1d".equals(s)) {
- // Take care of the special "1d" case
- ret.expires = System.currentTimeMillis() + 86400000; // 24*60*60*1000
- } else {
- Log.e(LOGTAG, "exception in parseHeaders for "
- + "max-age:"
- + controls[i].substring(separator + 1));
- ret.expires = 0;
- }
- }
- }
- }
- }
- }
-
- // According to RFC 2616 section 14.32:
- // HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the
- // client had sent "Cache-Control: no-cache"
- if (NO_CACHE.equals(headers.getPragma())) {
- ret.expires = 0;
- }
-
- // According to RFC 2616 section 13.2.4, if an expiration has not been
- // explicitly defined a heuristic to set an expiration may be used.
- if (ret.expires == -1) {
- if (ret.httpStatusCode == 301) {
- // If it is a permanent redirect, and it did not have an
- // explicit cache directive, then it never expires
- ret.expires = Long.MAX_VALUE;
- } else if (ret.httpStatusCode == 302 || ret.httpStatusCode == 307) {
- // If it is temporary redirect, expires
- ret.expires = 0;
- } else if (ret.lastModified == null) {
- // When we have no last-modified, then expire the content with
- // in 24hrs as, according to the RFC, longer time requires a
- // warning 113 to be added to the response.
-
- // Only add the default expiration for non-html markup. Some
- // sites like news.google.com have no cache directives.
- if (!mimeType.startsWith("text/html")) {
- ret.expires = System.currentTimeMillis() + 86400000; // 24*60*60*1000
- } else {
- // Setting a expires as zero will cache the result for
- // forward/back nav.
- ret.expires = 0;
- }
- } else {
- // If we have a last-modified value, we could use it to set the
- // expiration. Suggestion from RFC is 10% of time since
- // last-modified. As we are on mobile, loads are expensive,
- // increasing this to 20%.
-
- // 24 * 60 * 60 * 1000
- long lastmod = System.currentTimeMillis() + 86400000;
- try {
- lastmod = AndroidHttpClient.parseDate(ret.lastModified);
- } catch (IllegalArgumentException ex) {
- Log.e(LOGTAG, "illegal lastModified: " + ret.lastModified);
- }
- long difference = System.currentTimeMillis() - lastmod;
- if (difference > 0) {
- ret.expires = System.currentTimeMillis() + difference / 5;
- } else {
- // last modified is in the future, expire the content
- // on the last modified
- ret.expires = lastmod;
- }
- }
- }
-
- return ret;
- }
-
private static native CacheResult nativeGetCacheResult(String url);
}
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 95d927593799..3a05bcab12e8 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -920,10 +920,6 @@ class CallbackProxy extends Handler {
if (PERF_PROBE) {
mWebCoreThreadTime = SystemClock.currentThreadTimeMillis();
mWebCoreIdleTime = 0;
- if (!JniUtil.useChromiumHttpStack()) {
- // Network is only used with the Android HTTP stack.
- Network.getInstance(mContext).startTiming();
- }
// un-comment this if PERF_PROBE is true
// Looper.myQueue().setWaitCallback(mIdleCallback);
}
@@ -941,10 +937,6 @@ class CallbackProxy extends Handler {
Log.d("WebCore", "WebCore thread used " +
(SystemClock.currentThreadTimeMillis() - mWebCoreThreadTime)
+ " ms and idled " + mWebCoreIdleTime + " ms");
- if (!JniUtil.useChromiumHttpStack()) {
- // Network is only used with the Android HTTP stack.
- Network.getInstance(mContext).stopTiming();
- }
}
Message msg = obtainMessage(PAGE_FINISHED, url);
sendMessage(msg);
diff --git a/core/java/android/webkit/ContentLoader.java b/core/java/android/webkit/ContentLoader.java
deleted file mode 100644
index d13210aa2a0b..000000000000
--- a/core/java/android/webkit/ContentLoader.java
+++ /dev/null
@@ -1,98 +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.webkit;
-
-import android.net.http.EventHandler;
-import android.net.http.Headers;
-import android.net.Uri;
-
-/**
- * This class is a concrete implementation of StreamLoader that loads
- * "content:" URIs
- */
-class ContentLoader extends StreamLoader {
-
- private String mUrl;
- private String mContentType;
-
- /**
- * Construct a ContentLoader with the specified content URI
- *
- * @param rawUrl "content:" url pointing to content to be loaded. This url
- * is the same url passed in to the WebView.
- * @param loadListener LoadListener to pass the content to
- */
- ContentLoader(String rawUrl, LoadListener loadListener) {
- super(loadListener);
-
- /* strip off mimetype */
- int mimeIndex = rawUrl.lastIndexOf('?');
- if (mimeIndex != -1) {
- mUrl = rawUrl.substring(0, mimeIndex);
- mContentType = rawUrl.substring(mimeIndex + 1);
- } else {
- mUrl = rawUrl;
- }
-
- }
-
- private String errString(Exception ex) {
- String exMessage = ex.getMessage();
- String errString = mContext.getString(
- com.android.internal.R.string.httpErrorFileNotFound);
- if (exMessage != null) {
- errString += " " + exMessage;
- }
- return errString;
- }
-
- @Override
- protected boolean setupStreamAndSendStatus() {
- Uri uri = Uri.parse(mUrl);
- if (uri == null) {
- mLoadListener.error(
- EventHandler.FILE_NOT_FOUND_ERROR,
- mContext.getString(
- com.android.internal.R.string.httpErrorBadUrl) +
- " " + mUrl);
- return false;
- }
-
- try {
- mDataStream = mContext.getContentResolver().openInputStream(uri);
- mLoadListener.status(1, 1, 200, "OK");
- } catch (java.io.FileNotFoundException ex) {
- mLoadListener.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
- return false;
- } catch (RuntimeException ex) {
- // readExceptionWithFileNotFoundExceptionFromParcel in DatabaseUtils
- // can throw a serial of RuntimeException. Catch them all here.
- mLoadListener.error(EventHandler.FILE_ERROR, errString(ex));
- return false;
- }
- return true;
- }
-
- @Override
- protected void buildHeaders(Headers headers) {
- if (mContentType != null) {
- headers.setContentType("text/html");
- }
- // content can change, we don't want WebKit to cache it
- headers.setCacheControl("no-store, no-cache");
- }
-}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index c500a7621fb3..497cab7d2392 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -95,11 +95,6 @@ public final class CookieManager {
// max domain count to limit RAM cookie takes less than 100k,
private static final int MAX_RAM_DOMAIN_COUNT = 15;
- private Map<String, ArrayList<Cookie>> mCookieMap = new LinkedHashMap
- <String, ArrayList<Cookie>>(MAX_DOMAIN_COUNT, 0.75f, true);
-
- private boolean mAcceptCookie = true;
-
private int mPendingCookieOperations = 0;
/**
@@ -268,12 +263,7 @@ public final class CookieManager {
* cookies
*/
public synchronized void setAcceptCookie(boolean accept) {
- if (JniUtil.useChromiumHttpStack()) {
- nativeSetAcceptCookie(accept);
- return;
- }
-
- mAcceptCookie = accept;
+ nativeSetAcceptCookie(accept);
}
/**
@@ -282,11 +272,7 @@ public final class CookieManager {
* @return True if {@link WebView} instances send and accept cookies
*/
public synchronized boolean acceptCookie() {
- if (JniUtil.useChromiumHttpStack()) {
- return nativeAcceptCookie();
- }
-
- return mAcceptCookie;
+ return nativeAcceptCookie();
}
/**
@@ -299,20 +285,7 @@ public final class CookieManager {
* 'Set-Cookie' HTTP response header
*/
public void setCookie(String url, String value) {
- if (JniUtil.useChromiumHttpStack()) {
- setCookie(url, value, false);
- return;
- }
-
- WebAddress uri;
- try {
- uri = new WebAddress(url);
- } catch (ParseException ex) {
- Log.e(LOGTAG, "Bad address: " + url);
- return;
- }
-
- setCookie(uri, value);
+ setCookie(url, value, false);
}
/**
@@ -323,11 +296,6 @@ public final class CookieManager {
* @param privateBrowsing Whether to use the private browsing cookie jar
*/
void setCookie(String url, String value, boolean privateBrowsing) {
- if (!JniUtil.useChromiumHttpStack()) {
- setCookie(url, value);
- return;
- }
-
WebAddress uri;
try {
uri = new WebAddress(url);
@@ -340,136 +308,13 @@ public final class CookieManager {
}
/**
- * See {@link setCookie(String, String)}
- * @param uri The WebAddress for which the cookie is set
- * @param value The value of the cookie, as a string, using the format of
- * the 'Set-Cookie' HTTP response header
- */
- synchronized void setCookie(WebAddress uri, String value) {
- if (JniUtil.useChromiumHttpStack()) {
- nativeSetCookie(uri.toString(), value, false);
- return;
- }
-
- if (value != null && value.length() > MAX_COOKIE_LENGTH) {
- return;
- }
- if (!mAcceptCookie || uri == null) {
- return;
- }
- if (DebugFlags.COOKIE_MANAGER) {
- Log.v(LOGTAG, "setCookie: uri: " + uri + " value: " + value);
- }
-
- String[] hostAndPath = getHostAndPath(uri);
- if (hostAndPath == null) {
- return;
- }
-
- // For default path, when setting a cookie, the spec says:
- //Path: Defaults to the path of the request URL that generated the
- // Set-Cookie response, up to, but not including, the
- // right-most /.
- if (hostAndPath[1].length() > 1) {
- int index = hostAndPath[1].lastIndexOf(PATH_DELIM);
- hostAndPath[1] = hostAndPath[1].substring(0,
- index > 0 ? index : index + 1);
- }
-
- ArrayList<Cookie> cookies = null;
- try {
- cookies = parseCookie(hostAndPath[0], hostAndPath[1], value);
- } catch (RuntimeException ex) {
- Log.e(LOGTAG, "parse cookie failed for: " + value);
- }
-
- if (cookies == null || cookies.size() == 0) {
- return;
- }
-
- String baseDomain = getBaseDomain(hostAndPath[0]);
- ArrayList<Cookie> cookieList = mCookieMap.get(baseDomain);
- if (cookieList == null) {
- cookieList = CookieSyncManager.getInstance()
- .getCookiesForDomain(baseDomain);
- mCookieMap.put(baseDomain, cookieList);
- }
-
- long now = System.currentTimeMillis();
- int size = cookies.size();
- for (int i = 0; i < size; i++) {
- Cookie cookie = cookies.get(i);
-
- boolean done = false;
- Iterator<Cookie> iter = cookieList.iterator();
- while (iter.hasNext()) {
- Cookie cookieEntry = iter.next();
- if (cookie.exactMatch(cookieEntry)) {
- // expires == -1 means no expires defined. Otherwise
- // negative means far future
- if (cookie.expires < 0 || cookie.expires > now) {
- // secure cookies can't be overwritten by non-HTTPS url
- if (!cookieEntry.secure || HTTPS.equals(uri.getScheme())) {
- cookieEntry.value = cookie.value;
- cookieEntry.expires = cookie.expires;
- cookieEntry.secure = cookie.secure;
- cookieEntry.lastAcessTime = now;
- cookieEntry.lastUpdateTime = now;
- cookieEntry.mode = Cookie.MODE_REPLACED;
- }
- } else {
- cookieEntry.lastUpdateTime = now;
- cookieEntry.mode = Cookie.MODE_DELETED;
- }
- done = true;
- break;
- }
- }
-
- // expires == -1 means no expires defined. Otherwise negative means
- // far future
- if (!done && (cookie.expires < 0 || cookie.expires > now)) {
- cookie.lastAcessTime = now;
- cookie.lastUpdateTime = now;
- cookie.mode = Cookie.MODE_NEW;
- if (cookieList.size() > MAX_COOKIE_COUNT_PER_BASE_DOMAIN) {
- Cookie toDelete = new Cookie();
- toDelete.lastAcessTime = now;
- Iterator<Cookie> iter2 = cookieList.iterator();
- while (iter2.hasNext()) {
- Cookie cookieEntry2 = iter2.next();
- if ((cookieEntry2.lastAcessTime < toDelete.lastAcessTime)
- && cookieEntry2.mode != Cookie.MODE_DELETED) {
- toDelete = cookieEntry2;
- }
- }
- toDelete.mode = Cookie.MODE_DELETED;
- }
- cookieList.add(cookie);
- }
- }
- }
-
- /**
* Gets the cookies for the given URL.
* @param url The URL for which the cookies are requested
* @return value The cookies as a string, using the format of the 'Cookie'
* HTTP request header
*/
public String getCookie(String url) {
- if (JniUtil.useChromiumHttpStack()) {
- return getCookie(url, false);
- }
-
- WebAddress uri;
- try {
- uri = new WebAddress(url);
- } catch (ParseException ex) {
- Log.e(LOGTAG, "Bad address: " + url);
- return null;
- }
-
- return getCookie(uri);
+ return getCookie(url, false);
}
/**
@@ -481,11 +326,6 @@ public final class CookieManager {
* @hide Used by Browser, no intention to publish.
*/
public String getCookie(String url, boolean privateBrowsing) {
- if (!JniUtil.useChromiumHttpStack()) {
- // Just redirect to regular get cookie for android stack
- return getCookie(url);
- }
-
WebAddress uri;
try {
uri = new WebAddress(url);
@@ -506,76 +346,7 @@ public final class CookieManager {
* @hide Used by RequestHandle, no intention to publish.
*/
public synchronized String getCookie(WebAddress uri) {
- if (JniUtil.useChromiumHttpStack()) {
- return nativeGetCookie(uri.toString(), false);
- }
-
- if (!mAcceptCookie || uri == null) {
- return null;
- }
-
- String[] hostAndPath = getHostAndPath(uri);
- if (hostAndPath == null) {
- return null;
- }
-
- String baseDomain = getBaseDomain(hostAndPath[0]);
- ArrayList<Cookie> cookieList = mCookieMap.get(baseDomain);
- if (cookieList == null) {
- cookieList = CookieSyncManager.getInstance()
- .getCookiesForDomain(baseDomain);
- mCookieMap.put(baseDomain, cookieList);
- }
-
- long now = System.currentTimeMillis();
- boolean secure = HTTPS.equals(uri.getScheme());
- Iterator<Cookie> iter = cookieList.iterator();
-
- SortedSet<Cookie> cookieSet = new TreeSet<Cookie>(COMPARATOR);
- while (iter.hasNext()) {
- Cookie cookie = iter.next();
- if (cookie.domainMatch(hostAndPath[0]) &&
- cookie.pathMatch(hostAndPath[1])
- // expires == -1 means no expires defined. Otherwise
- // negative means far future
- && (cookie.expires < 0 || cookie.expires > now)
- && (!cookie.secure || secure)
- && cookie.mode != Cookie.MODE_DELETED) {
- cookie.lastAcessTime = now;
- cookieSet.add(cookie);
- }
- }
-
- StringBuilder ret = new StringBuilder(256);
- Iterator<Cookie> setIter = cookieSet.iterator();
- while (setIter.hasNext()) {
- Cookie cookie = setIter.next();
- if (ret.length() > 0) {
- ret.append(SEMICOLON);
- // according to RC2109, SEMICOLON is official separator,
- // but when log in yahoo.com, it needs WHITE_SPACE too.
- ret.append(WHITE_SPACE);
- }
-
- ret.append(cookie.name);
- if (cookie.value != null) {
- ret.append(EQUAL);
- ret.append(cookie.value);
- }
- }
-
- if (ret.length() > 0) {
- if (DebugFlags.COOKIE_MANAGER) {
- Log.v(LOGTAG, "getCookie: uri: " + uri + " value: " + ret);
- }
- return ret.toString();
- } else {
- if (DebugFlags.COOKIE_MANAGER) {
- Log.v(LOGTAG, "getCookie: uri: " + uri
- + " But can't find cookie.");
- }
- return null;
- }
+ return nativeGetCookie(uri.toString(), false);
}
/**
@@ -609,59 +380,20 @@ public final class CookieManager {
*/
public void removeSessionCookie() {
signalCookieOperationsStart();
- if (JniUtil.useChromiumHttpStack()) {
- new AsyncTask<Void, Void, Void>() {
- protected Void doInBackground(Void... none) {
- nativeRemoveSessionCookie();
- signalCookieOperationsComplete();
- return null;
- }
- }.execute();
- return;
- }
-
- final Runnable clearCache = new Runnable() {
- public void run() {
- synchronized(CookieManager.this) {
- Collection<ArrayList<Cookie>> cookieList = mCookieMap.values();
- Iterator<ArrayList<Cookie>> listIter = cookieList.iterator();
- while (listIter.hasNext()) {
- ArrayList<Cookie> list = listIter.next();
- Iterator<Cookie> iter = list.iterator();
- while (iter.hasNext()) {
- Cookie cookie = iter.next();
- if (cookie.expires == -1) {
- iter.remove();
- }
- }
- }
- CookieSyncManager.getInstance().clearSessionCookies();
- signalCookieOperationsComplete();
- }
+ new AsyncTask<Void, Void, Void>() {
+ protected Void doInBackground(Void... none) {
+ nativeRemoveSessionCookie();
+ signalCookieOperationsComplete();
+ return null;
}
- };
- new Thread(clearCache).start();
+ }.execute();
}
/**
* Removes all cookies.
*/
public void removeAllCookie() {
- if (JniUtil.useChromiumHttpStack()) {
- nativeRemoveAllCookie();
- return;
- }
-
- final Runnable clearCache = new Runnable() {
- public void run() {
- synchronized(CookieManager.this) {
- mCookieMap = new LinkedHashMap<String, ArrayList<Cookie>>(
- MAX_DOMAIN_COUNT, 0.75f, true);
- CookieSyncManager.getInstance().clearAllCookies();
- }
- }
- };
- new Thread(clearCache).start();
+ nativeRemoveAllCookie();
}
/**
@@ -669,11 +401,7 @@ public final class CookieManager {
* @return True if there are stored cookies.
*/
public synchronized boolean hasCookies() {
- if (JniUtil.useChromiumHttpStack()) {
- return hasCookies(false);
- }
-
- return CookieSyncManager.getInstance().hasCookies();
+ return hasCookies(false);
}
/**
@@ -682,10 +410,6 @@ public final class CookieManager {
* @hide Used by Browser, no intention to publish.
*/
public synchronized boolean hasCookies(boolean privateBrowsing) {
- if (!JniUtil.useChromiumHttpStack()) {
- return hasCookies();
- }
-
return nativeHasCookies(privateBrowsing);
}
@@ -693,34 +417,7 @@ public final class CookieManager {
* Removes all expired cookies.
*/
public void removeExpiredCookie() {
- if (JniUtil.useChromiumHttpStack()) {
- nativeRemoveExpiredCookie();
- return;
- }
-
- final Runnable clearCache = new Runnable() {
- public void run() {
- synchronized(CookieManager.this) {
- long now = System.currentTimeMillis();
- Collection<ArrayList<Cookie>> cookieList = mCookieMap.values();
- Iterator<ArrayList<Cookie>> listIter = cookieList.iterator();
- while (listIter.hasNext()) {
- ArrayList<Cookie> list = listIter.next();
- Iterator<Cookie> iter = list.iterator();
- while (iter.hasNext()) {
- Cookie cookie = iter.next();
- // expires == -1 means no expires defined. Otherwise
- // negative means far future
- if (cookie.expires > 0 && cookie.expires < now) {
- iter.remove();
- }
- }
- }
- CookieSyncManager.getInstance().clearExpiredCookies(now);
- }
- }
- };
- new Thread(clearCache).start();
+ nativeRemoveExpiredCookie();
}
/**
@@ -729,9 +426,7 @@ public final class CookieManager {
* Flush all cookies managed by the Chrome HTTP stack to flash.
*/
void flushCookieStore() {
- if (JniUtil.useChromiumHttpStack()) {
- nativeFlushCookieStore();
- }
+ nativeFlushCookieStore();
}
/**
@@ -741,11 +436,7 @@ public final class CookieManager {
* file scheme URLs
*/
public static boolean allowFileSchemeCookies() {
- if (JniUtil.useChromiumHttpStack()) {
- return nativeAcceptFileSchemeCookies();
- } else {
- return true;
- }
+ return nativeAcceptFileSchemeCookies();
}
/**
@@ -759,457 +450,7 @@ public final class CookieManager {
* {@link WebView} or CookieManager instance has been created.
*/
public static void setAcceptFileSchemeCookies(boolean accept) {
- if (JniUtil.useChromiumHttpStack()) {
- nativeSetAcceptFileSchemeCookies(accept);
- }
- }
-
- /**
- * Package level api, called from CookieSyncManager
- *
- * Get a list of cookies which are updated since a given time.
- * @param last The given time in millisec
- * @return A list of cookies
- */
- synchronized ArrayList<Cookie> getUpdatedCookiesSince(long last) {
- ArrayList<Cookie> cookies = new ArrayList<Cookie>();
- Collection<ArrayList<Cookie>> cookieList = mCookieMap.values();
- Iterator<ArrayList<Cookie>> listIter = cookieList.iterator();
- while (listIter.hasNext()) {
- ArrayList<Cookie> list = listIter.next();
- Iterator<Cookie> iter = list.iterator();
- while (iter.hasNext()) {
- Cookie cookie = iter.next();
- if (cookie.lastUpdateTime > last) {
- cookies.add(cookie);
- }
- }
- }
- return cookies;
- }
-
- /**
- * Package level api, called from CookieSyncManager
- *
- * Delete a Cookie in the RAM
- * @param cookie Cookie to be deleted
- */
- synchronized void deleteACookie(Cookie cookie) {
- if (cookie.mode == Cookie.MODE_DELETED) {
- String baseDomain = getBaseDomain(cookie.domain);
- ArrayList<Cookie> cookieList = mCookieMap.get(baseDomain);
- if (cookieList != null) {
- cookieList.remove(cookie);
- if (cookieList.isEmpty()) {
- mCookieMap.remove(baseDomain);
- }
- }
- }
- }
-
- /**
- * Package level api, called from CookieSyncManager
- *
- * Called after a cookie is synced to FLASH
- * @param cookie Cookie to be synced
- */
- synchronized void syncedACookie(Cookie cookie) {
- cookie.mode = Cookie.MODE_NORMAL;
- }
-
- /**
- * Package level api, called from CookieSyncManager
- *
- * Delete the least recent used domains if the total cookie count in RAM
- * exceeds the limit
- * @return A list of cookies which are removed from RAM
- */
- synchronized ArrayList<Cookie> deleteLRUDomain() {
- int count = 0;
- int byteCount = 0;
- int mapSize = mCookieMap.size();
-
- if (mapSize < MAX_RAM_DOMAIN_COUNT) {
- Collection<ArrayList<Cookie>> cookieLists = mCookieMap.values();
- Iterator<ArrayList<Cookie>> listIter = cookieLists.iterator();
- while (listIter.hasNext() && count < MAX_RAM_COOKIES_COUNT) {
- ArrayList<Cookie> list = listIter.next();
- if (DebugFlags.COOKIE_MANAGER) {
- Iterator<Cookie> iter = list.iterator();
- while (iter.hasNext() && count < MAX_RAM_COOKIES_COUNT) {
- Cookie cookie = iter.next();
- // 14 is 3 * sizeof(long) + sizeof(boolean)
- // + sizeof(byte)
- byteCount += cookie.domain.length()
- + cookie.path.length()
- + cookie.name.length()
- + (cookie.value != null
- ? cookie.value.length()
- : 0)
- + 14;
- count++;
- }
- } else {
- count += list.size();
- }
- }
- }
-
- ArrayList<Cookie> retlist = new ArrayList<Cookie>();
- if (mapSize >= MAX_RAM_DOMAIN_COUNT || count >= MAX_RAM_COOKIES_COUNT) {
- if (DebugFlags.COOKIE_MANAGER) {
- Log.v(LOGTAG, count + " cookies used " + byteCount
- + " bytes with " + mapSize + " domains");
- }
- Object[] domains = mCookieMap.keySet().toArray();
- int toGo = mapSize / 10 + 1;
- while (toGo-- > 0){
- String domain = domains[toGo].toString();
- if (DebugFlags.COOKIE_MANAGER) {
- Log.v(LOGTAG, "delete domain: " + domain
- + " from RAM cache");
- }
- retlist.addAll(mCookieMap.get(domain));
- mCookieMap.remove(domain);
- }
- }
- return retlist;
- }
-
- /**
- * Extract the host and path out of a uri
- * @param uri The given WebAddress
- * @return The host and path in the format of String[], String[0] is host
- * which has at least two periods, String[1] is path which always
- * ended with "/"
- */
- private String[] getHostAndPath(WebAddress uri) {
- if (uri.getHost() != null && uri.getPath() != null) {
-
- /*
- * The domain (i.e. host) portion of the cookie is supposed to be
- * case-insensitive. We will consistently return the domain in lower
- * case, which allows us to do the more efficient equals comparison
- * instead of equalIgnoreCase.
- *
- * See: http://www.ieft.org/rfc/rfc2965.txt (Section 3.3.3)
- */
- String[] ret = new String[2];
- ret[0] = uri.getHost().toLowerCase();
- ret[1] = uri.getPath();
-
- int index = ret[0].indexOf(PERIOD);
- if (index == -1) {
- if (uri.getScheme().equalsIgnoreCase("file")) {
- // There is a potential bug where a local file path matches
- // another file in the local web server directory. Still
- // "localhost" is the best pseudo domain name.
- ret[0] = "localhost";
- }
- } else if (index == ret[0].lastIndexOf(PERIOD)) {
- // cookie host must have at least two periods
- ret[0] = PERIOD + ret[0];
- }
-
- if (ret[1].charAt(0) != PATH_DELIM) {
- return null;
- }
-
- /*
- * find cookie path, e.g. for http://www.google.com, the path is "/"
- * for http://www.google.com/lab/, the path is "/lab"
- * for http://www.google.com/lab/foo, the path is "/lab/foo"
- * for http://www.google.com/lab?hl=en, the path is "/lab"
- * for http://www.google.com/lab.asp?hl=en, the path is "/lab.asp"
- * Note: the path from URI has at least one "/"
- * See:
- * http://www.unix.com.ua/rfc/rfc2109.html
- */
- index = ret[1].indexOf(QUESTION_MARK);
- if (index != -1) {
- ret[1] = ret[1].substring(0, index);
- }
-
- return ret;
- } else
- return null;
- }
-
- /**
- * Get the base domain for a give host. E.g. mail.google.com will return
- * google.com
- * @param host The give host
- * @return the base domain
- */
- private String getBaseDomain(String host) {
- int startIndex = 0;
- int nextIndex = host.indexOf(PERIOD);
- int lastIndex = host.lastIndexOf(PERIOD);
- while (nextIndex < lastIndex) {
- startIndex = nextIndex + 1;
- nextIndex = host.indexOf(PERIOD, startIndex);
- }
- if (startIndex > 0) {
- return host.substring(startIndex);
- } else {
- return host;
- }
- }
-
- /**
- * parseCookie() parses the cookieString which is a comma-separated list of
- * one or more cookies in the format of "NAME=VALUE; expires=DATE;
- * path=PATH; domain=DOMAIN_NAME; secure httponly" to a list of Cookies.
- * Here is a sample: IGDND=1, IGPC=ET=UB8TSNwtDmQ:AF=0; expires=Sun,
- * 17-Jan-2038 19:14:07 GMT; path=/ig; domain=.google.com, =,
- * PREF=ID=408909b1b304593d:TM=1156459854:LM=1156459854:S=V-vCAU6Sh-gobCfO;
- * expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com which
- * contains 3 cookies IGDND, IGPC, PREF and an empty cookie
- * @param host The default host
- * @param path The default path
- * @param cookieString The string coming from "Set-Cookie:"
- * @return A list of Cookies
- */
- private ArrayList<Cookie> parseCookie(String host, String path,
- String cookieString) {
- ArrayList<Cookie> ret = new ArrayList<Cookie>();
-
- int index = 0;
- int length = cookieString.length();
- while (true) {
- Cookie cookie = null;
-
- // done
- if (index < 0 || index >= length) {
- break;
- }
-
- // skip white space
- if (cookieString.charAt(index) == WHITE_SPACE) {
- index++;
- continue;
- }
-
- /*
- * get NAME=VALUE; pair. detecting the end of a pair is tricky, it
- * can be the end of a string, like "foo=bluh", it can be semicolon
- * like "foo=bluh;path=/"; or it can be enclosed by \", like
- * "foo=\"bluh bluh\";path=/"
- *
- * Note: in the case of "foo=bluh, bar=bluh;path=/", we interpret
- * it as one cookie instead of two cookies.
- */
- int semicolonIndex = cookieString.indexOf(SEMICOLON, index);
- int equalIndex = cookieString.indexOf(EQUAL, index);
- cookie = new Cookie(host, path);
-
- // Cookies like "testcookie; path=/;" are valid and used
- // (lovefilm.se).
- // Look for 2 cases:
- // 1. "foo" or "foo;" where equalIndex is -1
- // 2. "foo; path=..." where the first semicolon is before an equal
- // and a semicolon exists.
- if ((semicolonIndex != -1 && (semicolonIndex < equalIndex)) ||
- equalIndex == -1) {
- // Fix up the index in case we have a string like "testcookie"
- if (semicolonIndex == -1) {
- semicolonIndex = length;
- }
- cookie.name = cookieString.substring(index, semicolonIndex);
- cookie.value = null;
- } else {
- cookie.name = cookieString.substring(index, equalIndex);
- // Make sure we do not throw an exception if the cookie is like
- // "foo="
- if ((equalIndex < length - 1) &&
- (cookieString.charAt(equalIndex + 1) == QUOTATION)) {
- index = cookieString.indexOf(QUOTATION, equalIndex + 2);
- if (index == -1) {
- // bad format, force return
- break;
- }
- }
- // Get the semicolon index again in case it was contained within
- // the quotations.
- semicolonIndex = cookieString.indexOf(SEMICOLON, index);
- if (semicolonIndex == -1) {
- semicolonIndex = length;
- }
- if (semicolonIndex - equalIndex > MAX_COOKIE_LENGTH) {
- // cookie is too big, trim it
- cookie.value = cookieString.substring(equalIndex + 1,
- equalIndex + 1 + MAX_COOKIE_LENGTH);
- } else if (equalIndex + 1 == semicolonIndex
- || semicolonIndex < equalIndex) {
- // this is an unusual case like "foo=;" or "foo="
- cookie.value = "";
- } else {
- cookie.value = cookieString.substring(equalIndex + 1,
- semicolonIndex);
- }
- }
- // get attributes
- index = semicolonIndex;
- while (true) {
- // done
- if (index < 0 || index >= length) {
- break;
- }
-
- // skip white space and semicolon
- if (cookieString.charAt(index) == WHITE_SPACE
- || cookieString.charAt(index) == SEMICOLON) {
- index++;
- continue;
- }
-
- // comma means next cookie
- if (cookieString.charAt(index) == COMMA) {
- index++;
- break;
- }
-
- // "secure" is a known attribute doesn't use "=";
- // while sites like live.com uses "secure="
- if (length - index >= SECURE_LENGTH
- && cookieString.substring(index, index + SECURE_LENGTH).
- equalsIgnoreCase(SECURE)) {
- index += SECURE_LENGTH;
- cookie.secure = true;
- if (index == length) break;
- if (cookieString.charAt(index) == EQUAL) index++;
- continue;
- }
-
- // "httponly" is a known attribute doesn't use "=";
- // while sites like live.com uses "httponly="
- if (length - index >= HTTP_ONLY_LENGTH
- && cookieString.substring(index,
- index + HTTP_ONLY_LENGTH).
- equalsIgnoreCase(HTTP_ONLY)) {
- index += HTTP_ONLY_LENGTH;
- if (index == length) break;
- if (cookieString.charAt(index) == EQUAL) index++;
- // FIXME: currently only parse the attribute
- continue;
- }
- equalIndex = cookieString.indexOf(EQUAL, index);
- if (equalIndex > 0) {
- String name = cookieString.substring(index, equalIndex).toLowerCase();
- int valueIndex = equalIndex + 1;
- while (valueIndex < length && cookieString.charAt(valueIndex) == WHITE_SPACE) {
- valueIndex++;
- }
-
- if (name.equals(EXPIRES)) {
- int comaIndex = cookieString.indexOf(COMMA, equalIndex);
-
- // skip ',' in (Wdy, DD-Mon-YYYY HH:MM:SS GMT) or
- // (Weekday, DD-Mon-YY HH:MM:SS GMT) if it applies.
- // "Wednesday" is the longest Weekday which has length 9
- if ((comaIndex != -1) &&
- (comaIndex - valueIndex <= 10)) {
- index = comaIndex + 1;
- }
- }
- semicolonIndex = cookieString.indexOf(SEMICOLON, index);
- int commaIndex = cookieString.indexOf(COMMA, index);
- if (semicolonIndex == -1 && commaIndex == -1) {
- index = length;
- } else if (semicolonIndex == -1) {
- index = commaIndex;
- } else if (commaIndex == -1) {
- index = semicolonIndex;
- } else {
- index = Math.min(semicolonIndex, commaIndex);
- }
- String value = cookieString.substring(valueIndex, index);
-
- // Strip quotes if they exist
- if (value.length() > 2 && value.charAt(0) == QUOTATION) {
- int endQuote = value.indexOf(QUOTATION, 1);
- if (endQuote > 0) {
- value = value.substring(1, endQuote);
- }
- }
- if (name.equals(EXPIRES)) {
- try {
- cookie.expires = AndroidHttpClient.parseDate(value);
- } catch (IllegalArgumentException ex) {
- Log.e(LOGTAG,
- "illegal format for expires: " + value);
- }
- } else if (name.equals(MAX_AGE)) {
- try {
- cookie.expires = System.currentTimeMillis() + 1000
- * Long.parseLong(value);
- } catch (NumberFormatException ex) {
- Log.e(LOGTAG,
- "illegal format for max-age: " + value);
- }
- } else if (name.equals(PATH)) {
- // only allow non-empty path value
- if (value.length() > 0) {
- cookie.path = value;
- }
- } else if (name.equals(DOMAIN)) {
- int lastPeriod = value.lastIndexOf(PERIOD);
- if (lastPeriod == 0) {
- // disallow cookies set for TLDs like [.com]
- cookie.domain = null;
- continue;
- }
- try {
- Integer.parseInt(value.substring(lastPeriod + 1));
- // no wildcard for ip address match
- if (!value.equals(host)) {
- // no cross-site cookie
- cookie.domain = null;
- }
- continue;
- } catch (NumberFormatException ex) {
- // ignore the exception, value is a host name
- }
- value = value.toLowerCase();
- if (value.charAt(0) != PERIOD) {
- // pre-pended dot to make it as a domain cookie
- value = PERIOD + value;
- lastPeriod++;
- }
- if (host.endsWith(value.substring(1))) {
- int len = value.length();
- int hostLen = host.length();
- if (hostLen > (len - 1)
- && host.charAt(hostLen - len) != PERIOD) {
- // make sure the bar.com doesn't match .ar.com
- cookie.domain = null;
- continue;
- }
- // disallow cookies set on ccTLDs like [.co.uk]
- if ((len == lastPeriod + 3)
- && (len >= 6 && len <= 8)) {
- String s = value.substring(1, lastPeriod);
- if (Arrays.binarySearch(BAD_COUNTRY_2LDS, s) >= 0) {
- cookie.domain = null;
- continue;
- }
- }
- cookie.domain = value;
- } else {
- // no cross-site or more specific sub-domain cookie
- cookie.domain = null;
- }
- }
- } else {
- // bad format, force return
- index = length;
- }
- }
- if (cookie != null && cookie.domain != null) {
- ret.add(cookie);
- }
- }
- return ret;
+ nativeSetAcceptFileSchemeCookies(accept);
}
// Native functions
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index a6998006e895..19fa09672c42 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -100,77 +100,6 @@ public final class CookieSyncManager extends WebSyncManager {
return sRef;
}
- /**
- * Package level api, called from CookieManager. Get all the cookies which
- * matches a given base domain.
- * @param domain
- * @return A list of Cookie
- */
- ArrayList<Cookie> getCookiesForDomain(String domain) {
- // null mDataBase implies that the host application doesn't support
- // persistent cookie. No sync needed.
- if (mDataBase == null) {
- return new ArrayList<Cookie>();
- }
-
- return mDataBase.getCookiesForDomain(domain);
- }
-
- /**
- * Package level api, called from CookieManager Clear all cookies in the
- * database
- */
- void clearAllCookies() {
- // null mDataBase implies that the host application doesn't support
- // persistent cookie.
- if (mDataBase == null) {
- return;
- }
-
- mDataBase.clearCookies();
- }
-
- /**
- * Returns true if there are any saved cookies.
- */
- boolean hasCookies() {
- // null mDataBase implies that the host application doesn't support
- // persistent cookie.
- if (mDataBase == null) {
- return false;
- }
-
- return mDataBase.hasCookies();
- }
-
- /**
- * Package level api, called from CookieManager Clear all session cookies in
- * the database
- */
- void clearSessionCookies() {
- // null mDataBase implies that the host application doesn't support
- // persistent cookie.
- if (mDataBase == null) {
- return;
- }
-
- mDataBase.clearSessionCookies();
- }
-
- /**
- * Package level api, called from CookieManager Clear all expired cookies in
- * the database
- */
- void clearExpiredCookies(long now) {
- // null mDataBase implies that the host application doesn't support
- // persistent cookie.
- if (mDataBase == null) {
- return;
- }
-
- mDataBase.clearExpiredCookies(now);
- }
-
protected void syncFromRamToFlash() {
if (DebugFlags.COOKIE_SYNC_MANAGER) {
Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS");
@@ -182,41 +111,13 @@ public final class CookieSyncManager extends WebSyncManager {
return;
}
- if (JniUtil.useChromiumHttpStack()) {
- manager.flushCookieStore();
- } else {
- ArrayList<Cookie> cookieList = manager.getUpdatedCookiesSince(mLastUpdate);
- mLastUpdate = System.currentTimeMillis();
- syncFromRamToFlash(cookieList);
-
- ArrayList<Cookie> lruList = manager.deleteLRUDomain();
- syncFromRamToFlash(lruList);
- }
+ manager.flushCookieStore();
if (DebugFlags.COOKIE_SYNC_MANAGER) {
Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");
}
}
- private void syncFromRamToFlash(ArrayList<Cookie> list) {
- Iterator<Cookie> iter = list.iterator();
- while (iter.hasNext()) {
- Cookie cookie = iter.next();
- if (cookie.mode != Cookie.MODE_NORMAL) {
- if (cookie.mode != Cookie.MODE_NEW) {
- mDataBase.deleteCookies(cookie.domain, cookie.path,
- cookie.name);
- }
- if (cookie.mode != Cookie.MODE_DELETED) {
- mDataBase.addCookie(cookie);
- CookieManager.getInstance().syncedACookie(cookie);
- } else {
- CookieManager.getInstance().deleteACookie(cookie);
- }
- }
- }
- }
-
private static void checkInstanceIsCreated() {
if (sRef == null) {
throw new IllegalStateException(
diff --git a/core/java/android/webkit/DataLoader.java b/core/java/android/webkit/DataLoader.java
deleted file mode 100644
index e8d906934954..000000000000
--- a/core/java/android/webkit/DataLoader.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.net.http.EventHandler;
-
-import com.android.internal.R;
-
-import java.io.ByteArrayInputStream;
-
-import libcore.io.Base64;
-
-/**
- * This class is a concrete implementation of StreamLoader that uses the
- * content supplied as a URL as the source for the stream. The mimetype
- * optionally provided in the URL is extracted and inserted into the HTTP
- * response headers.
- */
-class DataLoader extends StreamLoader {
-
- /**
- * Constructor uses the dataURL as the source for an InputStream
- * @param dataUrl data: URL string optionally containing a mimetype
- * @param loadListener LoadListener to pass the content to
- */
- DataLoader(String dataUrl, LoadListener loadListener) {
- super(loadListener);
-
- String url = dataUrl.substring("data:".length());
- byte[] data = null;
- int commaIndex = url.indexOf(',');
- if (commaIndex != -1) {
- String contentType = url.substring(0, commaIndex);
- data = url.substring(commaIndex + 1).getBytes();
- loadListener.parseContentTypeHeader(contentType);
- if ("base64".equals(loadListener.transferEncoding())) {
- data = Base64.decode(data);
- }
- } else {
- data = url.getBytes();
- }
- if (data != null) {
- mDataStream = new ByteArrayInputStream(data);
- mContentLength = data.length;
- }
- }
-
- @Override
- protected boolean setupStreamAndSendStatus() {
- if (mDataStream != null) {
- mLoadListener.status(1, 1, 200, "OK");
- return true;
- } else {
- mLoadListener.error(EventHandler.ERROR,
- mContext.getString(R.string.httpError));
- return false;
- }
- }
-
- @Override
- protected void buildHeaders(android.net.http.Headers h) {
- }
-}
diff --git a/core/java/android/webkit/FileLoader.java b/core/java/android/webkit/FileLoader.java
deleted file mode 100644
index e21e9ef8e9f1..000000000000
--- a/core/java/android/webkit/FileLoader.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import com.android.internal.R;
-
-import android.content.res.AssetManager;
-import android.net.http.EventHandler;
-import android.net.http.Headers;
-import android.util.Log;
-import android.util.TypedValue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.lang.reflect.Field;
-
-/**
- * This class is a concrete implementation of StreamLoader that uses a
- * file or asset as the source for the stream.
- *
- */
-class FileLoader extends StreamLoader {
-
- private String mPath; // Full path to the file to load
- private int mType; // Indicates the type of the load
- private boolean mAllowFileAccess; // Allow/block file system access
-
- // used for files under asset directory
- static final int TYPE_ASSET = 1;
- // used for files under res directory
- static final int TYPE_RES = 2;
- // generic file
- static final int TYPE_FILE = 3;
-
- private static final String LOGTAG = "webkit";
-
- /**
- * Construct a FileLoader with the file URL specified as the content
- * source.
- *
- * @param url Full file url pointing to content to be loaded
- * @param loadListener LoadListener to pass the content to
- * @param asset true if url points to an asset.
- * @param allowFileAccess true if this WebView is allowed to access files
- * on the file system.
- */
- FileLoader(String url, LoadListener loadListener, int type,
- boolean allowFileAccess) {
- super(loadListener);
- mType = type;
- mAllowFileAccess = allowFileAccess;
-
- // clean the Url
- int index = url.indexOf('?');
- if (mType == TYPE_ASSET) {
- mPath = index > 0 ? URLUtil.stripAnchor(
- url.substring(URLUtil.ASSET_BASE.length(), index)) :
- URLUtil.stripAnchor(url.substring(
- URLUtil.ASSET_BASE.length()));
- } else if (mType == TYPE_RES) {
- mPath = index > 0 ? URLUtil.stripAnchor(
- url.substring(URLUtil.RESOURCE_BASE.length(), index)) :
- URLUtil.stripAnchor(url.substring(
- URLUtil.RESOURCE_BASE.length()));
- } else {
- mPath = index > 0 ? URLUtil.stripAnchor(
- url.substring(URLUtil.FILE_BASE.length(), index)) :
- URLUtil.stripAnchor(url.substring(
- URLUtil.FILE_BASE.length()));
- }
- }
-
- private String errString(Exception ex) {
- String exMessage = ex.getMessage();
- String errString = mContext.getString(R.string.httpErrorFileNotFound);
- if (exMessage != null) {
- errString += " " + exMessage;
- }
- return errString;
- }
-
- @Override
- protected boolean setupStreamAndSendStatus() {
- try {
- if (mType == TYPE_ASSET) {
- try {
- mDataStream = mContext.getAssets().open(mPath);
- } catch (java.io.FileNotFoundException ex) {
- // try the rest files included in the package
- mDataStream = mContext.getAssets().openNonAsset(mPath);
- }
- } else if (mType == TYPE_RES) {
- // get the resource id from the path. e.g. for the path like
- // drawable/foo.png, the id is located at field "foo" of class
- // "<package>.R$drawable"
- if (mPath == null || mPath.length() == 0) {
- Log.e(LOGTAG, "Need a path to resolve the res file");
- mLoadListener.error(EventHandler.FILE_ERROR, mContext
- .getString(R.string.httpErrorFileNotFound));
- return false;
-
- }
- int slash = mPath.indexOf('/');
- int dot = mPath.indexOf('.', slash);
- if (slash == -1 || dot == -1) {
- Log.e(LOGTAG, "Incorrect res path: " + mPath);
- mLoadListener.error(EventHandler.FILE_ERROR, mContext
- .getString(R.string.httpErrorFileNotFound));
- return false;
- }
- String subClassName = mPath.substring(0, slash);
- String fieldName = mPath.substring(slash + 1, dot);
- String errorMsg = null;
- try {
- final Class<?> d = mContext.getApplicationContext()
- .getClassLoader().loadClass(
- mContext.getPackageName() + ".R$"
- + subClassName);
- final Field field = d.getField(fieldName);
- final int id = field.getInt(null);
- TypedValue value = new TypedValue();
- mContext.getResources().getValue(id, value, true);
- if (value.type == TypedValue.TYPE_STRING) {
- mDataStream = mContext.getAssets().openNonAsset(
- value.assetCookie, value.string.toString(),
- AssetManager.ACCESS_STREAMING);
- } else {
- errorMsg = "Only support TYPE_STRING for the res files";
- }
- } catch (ClassNotFoundException e) {
- errorMsg = "Can't find class: "
- + mContext.getPackageName() + ".R$" + subClassName;
- } catch (SecurityException e) {
- errorMsg = "Caught SecurityException: " + e;
- } catch (NoSuchFieldException e) {
- errorMsg = "Can't find field: " + fieldName + " in "
- + mContext.getPackageName() + ".R$" + subClassName;
- } catch (IllegalArgumentException e) {
- errorMsg = "Caught IllegalArgumentException: " + e;
- } catch (IllegalAccessException e) {
- errorMsg = "Caught IllegalAccessException: " + e;
- }
- if (errorMsg != null) {
- mLoadListener.error(EventHandler.FILE_ERROR, mContext
- .getString(R.string.httpErrorFileNotFound));
- return false;
- }
- } else {
- if (!mAllowFileAccess) {
- mLoadListener.error(EventHandler.FILE_ERROR,
- mContext.getString(R.string.httpErrorFileNotFound));
- return false;
- }
-
- mDataStream = new FileInputStream(mPath);
- mContentLength = (new File(mPath)).length();
- }
- mLoadListener.status(1, 1, 200, "OK");
-
- } catch (java.io.FileNotFoundException ex) {
- mLoadListener.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
- return false;
-
- } catch (java.io.IOException ex) {
- mLoadListener.error(EventHandler.FILE_ERROR, errString(ex));
- return false;
- }
- return true;
- }
-
- @Override
- protected void buildHeaders(Headers headers) {
- // do nothing.
- }
-}
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
deleted file mode 100644
index 0d8030285244..000000000000
--- a/core/java/android/webkit/FrameLoader.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.net.http.ErrorStrings;
-import android.net.http.EventHandler;
-import android.net.http.RequestHandle;
-import android.os.Build;
-import android.util.Log;
-import android.webkit.CacheManager.CacheResult;
-import android.webkit.JniUtil;
-
-import java.util.HashMap;
-import java.util.Map;
-
-class FrameLoader {
-
- private final LoadListener mListener;
- private final String mMethod;
- private final WebSettings mSettings;
- private Map<String, String> mHeaders;
- private byte[] mPostData;
- private Network mNetwork;
- private int mCacheMode;
- private String mReferrer;
- private String mContentType;
- private final String mUaprofHeader;
- private final WebResourceResponse mInterceptResponse;
-
- private static final int URI_PROTOCOL = 0x100;
-
- private static final String CONTENT_TYPE = "content-type";
-
- // Contents of an about:blank page
- private static final String mAboutBlank =
- "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EB\">" +
- "<html><head><title>about:blank</title></head><body></body></html>";
-
- static final String HEADER_STR = "text/xml, text/html, " +
- "application/xhtml+xml, image/png, text/plain, */*;q=0.8";
-
- private static final String LOGTAG = "webkit";
-
- FrameLoader(LoadListener listener, WebSettings settings,
- String method, WebResourceResponse interceptResponse) {
- assert !JniUtil.useChromiumHttpStack();
-
- mListener = listener;
- mHeaders = null;
- mMethod = method;
- mCacheMode = WebSettings.LOAD_NORMAL;
- mSettings = settings;
- mInterceptResponse = interceptResponse;
- mUaprofHeader = mListener.getContext().getResources().getString(
- com.android.internal.R.string.config_useragentprofile_url, Build.MODEL);
- }
-
- public void setReferrer(String ref) {
- // only set referrer for http or https
- if (URLUtil.isNetworkUrl(ref)) mReferrer = ref;
- }
-
- public void setPostData(byte[] postData) {
- mPostData = postData;
- }
-
- public void setContentTypeForPost(String postContentType) {
- mContentType = postContentType;
- }
-
- public void setCacheMode(int cacheMode) {
- mCacheMode = cacheMode;
- }
-
- public void setHeaders(HashMap headers) {
- mHeaders = headers;
- }
-
- public LoadListener getLoadListener() {
- return mListener;
- }
-
- /**
- * Issues the load request.
- *
- * Return value does not indicate if the load was successful or not. It
- * simply indicates that the load request is reasonable.
- *
- * @return true if the load is reasonable.
- */
- public boolean executeLoad() {
- String url = mListener.url();
-
- // Process intercepted requests first as they could be any url.
- if (mInterceptResponse != null) {
- if (mListener.isSynchronous()) {
- mInterceptResponse.loader(mListener).load();
- } else {
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER,
- mInterceptResponse.loader(mListener)).sendToTarget();
- }
- return true;
- } else if (URLUtil.isNetworkUrl(url)){
- if (mSettings.getBlockNetworkLoads()) {
- mListener.error(EventHandler.ERROR_BAD_URL,
- mListener.getContext().getString(
- com.android.internal.R.string.httpErrorBadUrl));
- return false;
- }
- // Make sure the host part of the url is correctly
- // encoded before sending the request
- if (!URLUtil.verifyURLEncoding(mListener.host())) {
- mListener.error(EventHandler.ERROR_BAD_URL,
- mListener.getContext().getString(
- com.android.internal.R.string.httpErrorBadUrl));
- return false;
- }
- mNetwork = Network.getInstance(mListener.getContext());
- if (mListener.isSynchronous()) {
- return handleHTTPLoad();
- }
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_HTTPLOADER, this).sendToTarget();
- return true;
- } else if (handleLocalFile(url, mListener, mSettings)) {
- return true;
- }
- if (DebugFlags.FRAME_LOADER) {
- Log.v(LOGTAG, "FrameLoader.executeLoad: url protocol not supported:"
- + mListener.url());
- }
- mListener.error(EventHandler.ERROR_UNSUPPORTED_SCHEME,
- mListener.getContext().getText(
- com.android.internal.R.string.httpErrorUnsupportedScheme).toString());
- return false;
-
- }
-
- private static boolean handleLocalFile(String url, LoadListener loadListener,
- WebSettings settings) {
- assert !JniUtil.useChromiumHttpStack();
-
- // Attempt to decode the percent-encoded url before passing to the
- // local loaders.
- try {
- url = new String(URLUtil.decode(url.getBytes()));
- } catch (IllegalArgumentException e) {
- loadListener.error(EventHandler.ERROR_BAD_URL,
- loadListener.getContext().getString(
- com.android.internal.R.string.httpErrorBadUrl));
- // Return true here so we do not trigger an unsupported scheme
- // error.
- return true;
- }
- if (URLUtil.isAssetUrl(url)) {
- if (loadListener.isSynchronous()) {
- new FileLoader(url, loadListener, FileLoader.TYPE_ASSET,
- true).load();
- } else {
- // load asset in a separate thread as it involves IO
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER,
- new FileLoader(url, loadListener, FileLoader.TYPE_ASSET,
- true)).sendToTarget();
- }
- return true;
- } else if (URLUtil.isResourceUrl(url)) {
- if (loadListener.isSynchronous()) {
- new FileLoader(url, loadListener, FileLoader.TYPE_RES,
- true).load();
- } else {
- // load resource in a separate thread as it involves IO
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER,
- new FileLoader(url, loadListener, FileLoader.TYPE_RES,
- true)).sendToTarget();
- }
- return true;
- } else if (URLUtil.isFileUrl(url)) {
- if (loadListener.isSynchronous()) {
- new FileLoader(url, loadListener, FileLoader.TYPE_FILE,
- settings.getAllowFileAccess()).load();
- } else {
- // load file in a separate thread as it involves IO
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER,
- new FileLoader(url, loadListener, FileLoader.TYPE_FILE,
- settings.getAllowFileAccess())).sendToTarget();
- }
- return true;
- } else if (settings.getAllowContentAccess() &&
- URLUtil.isContentUrl(url)) {
- // Send the raw url to the ContentLoader because it will do a
- // permission check and the url has to match.
- if (loadListener.isSynchronous()) {
- new ContentLoader(loadListener.url(), loadListener).load();
- } else {
- // load content in a separate thread as it involves IO
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER,
- new ContentLoader(loadListener.url(), loadListener))
- .sendToTarget();
- }
- return true;
- } else if (URLUtil.isDataUrl(url)) {
- // load data in the current thread to reduce the latency
- new DataLoader(url, loadListener).load();
- return true;
- } else if (URLUtil.isAboutUrl(url)) {
- loadListener.data(mAboutBlank.getBytes(), mAboutBlank.length());
- loadListener.endData();
- return true;
- }
- return false;
- }
-
- boolean handleHTTPLoad() {
- if (mHeaders == null) {
- mHeaders = new HashMap<String, String>();
- }
- populateStaticHeaders();
- populateHeaders();
-
- // response was handled by Cache, don't issue HTTP request
- if (handleCache()) {
- // push the request data down to the LoadListener
- // as response from the cache could be a redirect
- // and we may need to initiate a network request if the cache
- // can't satisfy redirect URL
- mListener.setRequestData(mMethod, mHeaders, mPostData);
- return true;
- }
-
- if (DebugFlags.FRAME_LOADER) {
- Log.v(LOGTAG, "FrameLoader: http " + mMethod + " load for: "
- + mListener.url());
- }
-
- boolean ret = false;
- int error = EventHandler.ERROR_UNSUPPORTED_SCHEME;
-
- try {
- ret = mNetwork.requestURL(mMethod, mHeaders,
- mPostData, mListener);
- } catch (android.net.ParseException ex) {
- error = EventHandler.ERROR_BAD_URL;
- } catch (java.lang.RuntimeException ex) {
- /* probably an empty header set by javascript. We want
- the same result as bad URL */
- error = EventHandler.ERROR_BAD_URL;
- }
- if (!ret) {
- mListener.error(error, ErrorStrings.getString(error, mListener.getContext()));
- return false;
- }
- return true;
- }
-
- /*
- * This function is used by handleCache to
- * setup a load from the byte stream in a CacheResult.
- */
- private void startCacheLoad(CacheResult result) {
- if (DebugFlags.FRAME_LOADER) {
- Log.v(LOGTAG, "FrameLoader: loading from cache: "
- + mListener.url());
- }
- // Tell the Listener respond with the cache file
- CacheLoader cacheLoader =
- new CacheLoader(mListener, result);
- mListener.setCacheLoader(cacheLoader);
- if (mListener.isSynchronous()) {
- cacheLoader.load();
- } else {
- // Load the cached file in a separate thread
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER, cacheLoader).sendToTarget();
- }
- }
-
- /*
- * This function is used by the handleHTTPLoad to setup the cache headers
- * correctly.
- * Returns true if the response was handled from the cache
- */
- private boolean handleCache() {
- switch (mCacheMode) {
- // This mode is normally used for a reload, it instructs the http
- // loader to not use the cached content.
- case WebSettings.LOAD_NO_CACHE:
- break;
-
-
- // This mode is used when the content should only be loaded from
- // the cache. If it is not there, then fail the load. This is used
- // to load POST content in a history navigation.
- case WebSettings.LOAD_CACHE_ONLY: {
- CacheResult result = CacheManager.getCacheFile(mListener.url(),
- mListener.postIdentifier(), null);
- if (result != null) {
- startCacheLoad(result);
- } else {
- // This happens if WebCore was first told that the POST
- // response was in the cache, then when we try to use it
- // it has gone.
- // Generate a file not found error
- int err = EventHandler.FILE_NOT_FOUND_ERROR;
- mListener.error(err,
- ErrorStrings.getString(err, mListener.getContext()));
- }
- return true;
- }
-
- // This mode is for when the user is doing a history navigation
- // in the browser and should returned cached content regardless
- // of it's state. If it is not in the cache, then go to the
- // network.
- case WebSettings.LOAD_CACHE_ELSE_NETWORK: {
- if (DebugFlags.FRAME_LOADER) {
- Log.v(LOGTAG, "FrameLoader: checking cache: "
- + mListener.url());
- }
- // Get the cache file name for the current URL, passing null for
- // the validation headers causes no validation to occur
- CacheResult result = CacheManager.getCacheFile(mListener.url(),
- mListener.postIdentifier(), null);
- if (result != null) {
- startCacheLoad(result);
- return true;
- }
- break;
- }
-
- // This is the default case, which is to check to see if the
- // content in the cache can be used. If it can be used, then
- // use it. If it needs revalidation then the relevant headers
- // are added to the request.
- default:
- case WebSettings.LOAD_NORMAL:
- return mListener.checkCache(mHeaders);
- }// end of switch
-
- return false;
- }
-
- /**
- * Add the static headers that don't change with each request.
- */
- private void populateStaticHeaders() {
- // Accept header should already be there as they are built by WebCore,
- // but in the case they are missing, add some.
- String accept = mHeaders.get("Accept");
- if (accept == null || accept.length() == 0) {
- mHeaders.put("Accept", HEADER_STR);
- }
- mHeaders.put("Accept-Charset", "utf-8, iso-8859-1, utf-16, *;q=0.7");
-
- String acceptLanguage = mSettings.getAcceptLanguage();
- if (acceptLanguage.length() > 0) {
- mHeaders.put("Accept-Language", acceptLanguage);
- }
-
- mHeaders.put("User-Agent", mSettings.getUserAgentString());
-
- // Set the x-wap-profile header
- if (mUaprofHeader != null && mUaprofHeader.length() > 0) {
- mHeaders.put("x-wap-profile", mUaprofHeader);
- }
- }
-
- /**
- * Add the content related headers. These headers contain user private data
- * and is not used when we are proxying an untrusted request.
- */
- private void populateHeaders() {
-
- if (mReferrer != null) mHeaders.put("Referer", mReferrer);
- if (mContentType != null) mHeaders.put(CONTENT_TYPE, mContentType);
-
- // if we have an active proxy and have proxy credentials, do pre-emptive
- // authentication to avoid an extra round-trip:
- if (mNetwork.isValidProxySet()) {
- String username;
- String password;
- /* The proxy credentials can be set in the Network thread */
- synchronized (mNetwork) {
- username = mNetwork.getProxyUsername();
- password = mNetwork.getProxyPassword();
- }
- if (username != null && password != null) {
- // we collect credentials ONLY if the proxy scheme is BASIC!!!
- String proxyHeader = RequestHandle.authorizationHeader(true);
- mHeaders.put(proxyHeader,
- "Basic " + RequestHandle.computeBasicAuthResponse(
- username, password));
- }
- }
-
- // Set cookie header
- String cookie = CookieManager.getInstance().getCookie(
- mListener.getWebAddress());
- if (cookie != null && cookie.length() > 0) {
- mHeaders.put("Cookie", cookie);
- }
- }
-}
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index 0baf2eb7371e..aedecf034c29 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -142,8 +142,7 @@ class HTML5Audio extends Handler
// MediaPlayer.OnCompletionListener;
public void onCompletion(MediaPlayer mp) {
- resetMediaPlayer();
- mState = IDLE;
+ mState = COMPLETE;
nativeOnEnded(mNativePointer);
}
@@ -265,7 +264,18 @@ class HTML5Audio extends Handler
private void play() {
- if ((mState >= ERROR && mState < PREPARED) && mUrl != null) {
+ if (mState == COMPLETE) {
+ // Play it again, Sam
+ mTimer.cancel();
+ mTimer = new Timer();
+ mAskToPlay = true;
+ mMediaPlayer.stop();
+ mState = STOPPED;
+ mMediaPlayer.prepareAsync();
+ return;
+ }
+
+ if (((mState >= ERROR && mState < PREPARED)) && mUrl != null) {
resetMediaPlayer();
setDataSource(mUrl);
mAskToPlay = true;
@@ -296,6 +306,12 @@ class HTML5Audio extends Handler
private void seek(int msec) {
if (mState >= PREPARED) {
mMediaPlayer.seekTo(msec);
+ if (mState == COMPLETE) {
+ // Seeking after the stream had completed will
+ // cause us to start playing again. This is to
+ // support audio tags that specify loop=true.
+ play();
+ }
}
}
diff --git a/core/java/android/webkit/HttpAuthHandlerImpl.java b/core/java/android/webkit/HttpAuthHandlerImpl.java
deleted file mode 100644
index 01e8eb8a644f..000000000000
--- a/core/java/android/webkit/HttpAuthHandlerImpl.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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.
- */
-
-package android.webkit;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.ListIterator;
-import java.util.LinkedList;
-
-/**
- * HttpAuthHandler implementation is used only by the Android Java HTTP stack.
- * <p>
- * This class is not needed when we're using the Chromium HTTP stack.
- */
-class HttpAuthHandlerImpl extends HttpAuthHandler {
- /*
- * It is important that the handler is in Network, because we want to share
- * it accross multiple loaders and windows (like our subwindow and the main
- * window).
- */
-
- private static final String LOGTAG = "network";
-
- /**
- * Network.
- */
- private Network mNetwork;
-
- /**
- * Loader queue.
- */
- private LinkedList<LoadListener> mLoaderQueue;
-
-
- // Message id for handling the user response
- private static final int AUTH_PROCEED = 100;
- private static final int AUTH_CANCEL = 200;
-
- // Use to synchronize when making synchronous calls to
- // onReceivedHttpAuthRequest(). We can't use a single Boolean object for
- // both the lock and the state, because Boolean is immutable.
- Object mRequestInFlightLock = new Object();
- boolean mRequestInFlight;
- String mUsername;
- String mPassword;
-
- /**
- * Creates a new HTTP authentication handler with an empty
- * loader queue
- *
- * @param network The parent network object
- */
- /* package */ HttpAuthHandlerImpl(Network network) {
- mNetwork = network;
- mLoaderQueue = new LinkedList<LoadListener>();
- }
-
-
- @Override
- public void handleMessage(Message msg) {
- LoadListener loader = null;
- synchronized (mLoaderQueue) {
- loader = mLoaderQueue.poll();
- }
- assert(loader.isSynchronous() == false);
-
- switch (msg.what) {
- case AUTH_PROCEED:
- String username = msg.getData().getString("username");
- String password = msg.getData().getString("password");
-
- loader.handleAuthResponse(username, password);
- break;
-
- case AUTH_CANCEL:
- loader.handleAuthResponse(null, null);
- break;
- }
-
- processNextLoader();
- }
-
- /**
- * Helper method used to unblock handleAuthRequest(), which in the case of a
- * synchronous request will wait for proxy.onReceivedHttpAuthRequest() to
- * call back to either proceed() or cancel().
- *
- * @param username The username to use for authentication
- * @param password The password to use for authentication
- * @return True if the request is synchronous and handleAuthRequest() has
- * been unblocked
- */
- private boolean handleResponseForSynchronousRequest(String username, String password) {
- LoadListener loader = null;
- synchronized (mLoaderQueue) {
- loader = mLoaderQueue.peek();
- }
- if (loader.isSynchronous()) {
- mUsername = username;
- mPassword = password;
- return true;
- }
- return false;
- }
-
- private void signalRequestComplete() {
- synchronized (mRequestInFlightLock) {
- assert(mRequestInFlight);
- mRequestInFlight = false;
- mRequestInFlightLock.notify();
- }
- }
-
- /**
- * Proceed with the authorization with the given credentials
- *
- * May be called on the UI thread, rather than the WebCore thread.
- *
- * @param username The username to use for authentication
- * @param password The password to use for authentication
- */
- public void proceed(String username, String password) {
- if (handleResponseForSynchronousRequest(username, password)) {
- signalRequestComplete();
- return;
- }
- Message msg = obtainMessage(AUTH_PROCEED);
- msg.getData().putString("username", username);
- msg.getData().putString("password", password);
- sendMessage(msg);
- signalRequestComplete();
- }
-
- /**
- * Cancel the authorization request
- *
- * May be called on the UI thread, rather than the WebCore thread.
- *
- */
- public void cancel() {
- if (handleResponseForSynchronousRequest(null, null)) {
- signalRequestComplete();
- return;
- }
- sendMessage(obtainMessage(AUTH_CANCEL));
- signalRequestComplete();
- }
-
- /**
- * @return True if we can use user credentials on record
- * (ie, if we did not fail trying to use them last time)
- */
- public boolean useHttpAuthUsernamePassword() {
- LoadListener loader = null;
- synchronized (mLoaderQueue) {
- loader = mLoaderQueue.peek();
- }
- if (loader != null) {
- return !loader.authCredentialsInvalid();
- }
-
- return false;
- }
-
- /**
- * Enqueues the loader, if the loader is the only element
- * in the queue, starts processing the loader
- *
- * @param loader The loader that resulted in this http
- * authentication request
- */
- /* package */ void handleAuthRequest(LoadListener loader) {
- // The call to proxy.onReceivedHttpAuthRequest() may be asynchronous. If
- // the request is synchronous, we must block here until we have a
- // response.
- if (loader.isSynchronous()) {
- // If there's a request in flight, wait for it to complete. The
- // response will queue a message on this thread.
- waitForRequestToComplete();
- // Make a request to the proxy for this request, jumping the queue.
- // We use the queue so that the loader is present in
- // useHttpAuthUsernamePassword().
- synchronized (mLoaderQueue) {
- mLoaderQueue.addFirst(loader);
- }
- processNextLoader();
- // Wait for this request to complete.
- waitForRequestToComplete();
- // Pop the loader from the queue.
- synchronized (mLoaderQueue) {
- assert(mLoaderQueue.peek() == loader);
- mLoaderQueue.poll();
- }
- // Call back.
- loader.handleAuthResponse(mUsername, mPassword);
- // The message queued by the response from the last asynchronous
- // request, if present, will start the next request.
- return;
- }
-
- boolean processNext = false;
-
- synchronized (mLoaderQueue) {
- mLoaderQueue.offer(loader);
- processNext =
- (mLoaderQueue.size() == 1);
- }
-
- if (processNext) {
- processNextLoader();
- }
- }
-
- /**
- * Wait for the request in flight, if any, to complete
- */
- private void waitForRequestToComplete() {
- synchronized (mRequestInFlightLock) {
- while (mRequestInFlight) {
- try {
- mRequestInFlightLock.wait();
- } catch(InterruptedException e) {
- Log.e(LOGTAG, "Interrupted while waiting for request to complete");
- }
- }
- }
- }
-
- /**
- * Process the next loader in the queue (helper method)
- */
- private void processNextLoader() {
- LoadListener loader = null;
- synchronized (mLoaderQueue) {
- loader = mLoaderQueue.peek();
- }
- if (loader != null) {
- synchronized (mRequestInFlightLock) {
- assert(mRequestInFlight == false);
- mRequestInFlight = true;
- }
-
- CallbackProxy proxy = loader.getFrame().getCallbackProxy();
-
- String hostname = loader.proxyAuthenticate() ?
- mNetwork.getProxyHostname() : loader.host();
-
- String realm = loader.realm();
-
- proxy.onReceivedHttpAuthRequest(this, hostname, realm);
- }
- }
-
- /**
- * Informs the WebView of a new set of credentials.
- */
- public static void onReceivedCredentials(LoadListener loader,
- String host, String realm, String username, String password) {
- CallbackProxy proxy = loader.getFrame().getCallbackProxy();
- proxy.onReceivedHttpAuthCredentials(host, realm, username, password);
- }
-}
diff --git a/core/java/android/webkit/JniUtil.java b/core/java/android/webkit/JniUtil.java
index 7b449385ebfa..343d34a56643 100644
--- a/core/java/android/webkit/JniUtil.java
+++ b/core/java/android/webkit/JniUtil.java
@@ -37,7 +37,6 @@ class JniUtil {
// Used by the Chromium HTTP stack.
private static String sDatabaseDirectory;
private static String sCacheDirectory;
- private static Boolean sUseChromiumHttpStack;
private static Context sContext;
private static void checkInitialized() {
@@ -111,10 +110,9 @@ class JniUtil {
// content://
if (url.startsWith(ANDROID_CONTENT)) {
try {
- // Strip off mimetype, for compatibility with ContentLoader.java
- // If we don't do this, we can fail to load Gmail attachments,
- // because the URL being loaded doesn't exactly match the URL we
- // have permission to read.
+ // Strip off MIME type. If we don't do this, we can fail to
+ // load Gmail attachments, because the URL being loaded doesn't
+ // exactly match the URL we have permission to read.
int mimeIndex = url.lastIndexOf('?');
if (mimeIndex != -1) {
url = url.substring(0, mimeIndex);
@@ -152,6 +150,7 @@ class JniUtil {
if (url.startsWith(ANDROID_CONTENT)) {
try {
// Strip off mimetype, for compatibility with ContentLoader.java
+ // (used with Android HTTP stack, now removed).
// If we don't do this, we can fail to load Gmail attachments,
// because the URL being loaded doesn't exactly match the URL we
// have permission to read.
@@ -170,19 +169,6 @@ class JniUtil {
}
}
- /**
- * Returns true if we're using the Chromium HTTP stack.
- *
- * TODO: Remove this if/when we permanently switch to the Chromium HTTP stack
- * http:/b/3118772
- */
- static boolean useChromiumHttpStack() {
- if (sUseChromiumHttpStack == null) {
- sUseChromiumHttpStack = nativeUseChromiumHttpStack();
- }
- return sUseChromiumHttpStack;
- }
-
private static synchronized String getAutofillQueryUrl() {
checkInitialized();
// If the device has not checked in it won't have pulled down the system setting for the
@@ -200,7 +186,4 @@ class JniUtil {
long leftToAllocate = memInfo.availMem - memInfo.threshold;
return !memInfo.lowMemory && bytesRequested < leftToAllocate;
}
-
-
- private static native boolean nativeUseChromiumHttpStack();
}
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
deleted file mode 100644
index 4d7ade517a60..000000000000
--- a/core/java/android/webkit/LoadListener.java
+++ /dev/null
@@ -1,1685 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.ParseException;
-import android.net.Uri;
-import android.net.WebAddress;
-import android.net.http.EventHandler;
-import android.net.http.Headers;
-import android.net.http.HttpAuthHeader;
-import android.net.http.RequestHandle;
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.webkit.CacheManager.CacheResult;
-import android.webkit.JniUtil;
-
-import com.android.internal.R;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-class LoadListener extends Handler implements EventHandler {
-
- private static final String LOGTAG = "webkit";
-
- // Messages used internally to communicate state between the
- // Network thread and the WebCore thread.
- private static final int MSG_CONTENT_HEADERS = 100;
- private static final int MSG_CONTENT_DATA = 110;
- private static final int MSG_CONTENT_FINISHED = 120;
- private static final int MSG_CONTENT_ERROR = 130;
- private static final int MSG_LOCATION_CHANGED = 140;
- private static final int MSG_LOCATION_CHANGED_REQUEST = 150;
- private static final int MSG_STATUS = 160;
- private static final int MSG_SSL_CERTIFICATE = 170;
- private static final int MSG_SSL_ERROR = 180;
-
- // Standard HTTP status codes in a more representative format
- private static final int HTTP_OK = 200;
- private static final int HTTP_PARTIAL_CONTENT = 206;
- private static final int HTTP_MOVED_PERMANENTLY = 301;
- private static final int HTTP_FOUND = 302;
- private static final int HTTP_SEE_OTHER = 303;
- private static final int HTTP_NOT_MODIFIED = 304;
- private static final int HTTP_TEMPORARY_REDIRECT = 307;
- private static final int HTTP_AUTH = 401;
- private static final int HTTP_NOT_FOUND = 404;
- private static final int HTTP_PROXY_AUTH = 407;
-
- private static int sNativeLoaderCount;
-
- private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder();
-
- private String mUrl;
- private WebAddress mUri;
- private boolean mPermanent;
- private String mOriginalUrl;
- private Context mContext;
- private BrowserFrame mBrowserFrame;
- private int mNativeLoader;
- private String mMimeType;
- private String mEncoding;
- private String mTransferEncoding;
- private int mStatusCode;
- private String mStatusText;
- public long mContentLength; // Content length of the incoming data
- private boolean mCancelled; // The request has been cancelled.
- private boolean mAuthFailed; // indicates that the prev. auth failed
- private CacheLoader mCacheLoader;
- private boolean mFromCache = false;
- private HttpAuthHeader mAuthHeader;
- private int mErrorID = OK;
- private String mErrorDescription;
- private SslError mSslError;
- private RequestHandle mRequestHandle;
- private RequestHandle mSslErrorRequestHandle;
- private long mPostIdentifier;
- private boolean mSetNativeResponse;
-
- // Request data. It is only valid when we are doing a load from the
- // cache. It is needed if the cache returns a redirect
- private String mMethod;
- private Map<String, String> mRequestHeaders;
- private byte[] mPostData;
- // Flag to indicate that this load is synchronous.
- private boolean mSynchronous;
- private Vector<Message> mMessageQueue;
-
- // Does this loader correspond to the main-frame top-level page?
- private boolean mIsMainPageLoader;
- // Does this loader correspond to the main content (as opposed to a supporting resource)
- private final boolean mIsMainResourceLoader;
- private final boolean mUserGesture;
-
- private Headers mHeaders;
-
- private final String mUsername;
- private final String mPassword;
-
- // =========================================================================
- // Public functions
- // =========================================================================
-
- public static LoadListener getLoadListener(Context context,
- BrowserFrame frame, String url, int nativeLoader,
- boolean synchronous, boolean isMainPageLoader,
- boolean isMainResource, boolean userGesture, long postIdentifier,
- String username, String password) {
-
- sNativeLoaderCount += 1;
- return new LoadListener(context, frame, url, nativeLoader, synchronous,
- isMainPageLoader, isMainResource, userGesture, postIdentifier,
- username, password);
- }
-
- public static int getNativeLoaderCount() {
- return sNativeLoaderCount;
- }
-
- LoadListener(Context context, BrowserFrame frame, String url,
- int nativeLoader, boolean synchronous, boolean isMainPageLoader,
- boolean isMainResource, boolean userGesture, long postIdentifier,
- String username, String password) {
- assert !JniUtil.useChromiumHttpStack();
-
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener constructor url=" + url);
- }
- mContext = context;
- mBrowserFrame = frame;
- setUrl(url);
- mNativeLoader = nativeLoader;
- mSynchronous = synchronous;
- if (synchronous) {
- mMessageQueue = new Vector<Message>();
- }
- mIsMainPageLoader = isMainPageLoader;
- mIsMainResourceLoader = isMainResource;
- mUserGesture = userGesture;
- mPostIdentifier = postIdentifier;
- mUsername = username;
- mPassword = password;
- }
-
- /**
- * We keep a count of refs to the nativeLoader so we do not create
- * so many LoadListeners that the GREFs blow up
- */
- private void clearNativeLoader() {
- sNativeLoaderCount -= 1;
- mNativeLoader = 0;
- mSetNativeResponse = false;
- }
-
- /*
- * This message handler is to facilitate communication between the network
- * thread and the browser thread.
- */
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_CONTENT_HEADERS:
- /*
- * This message is sent when the LoadListener has headers
- * available. The headers are sent onto WebCore to see what we
- * should do with them.
- */
- handleHeaders((Headers) msg.obj);
- break;
-
- case MSG_CONTENT_DATA:
- /*
- * This message is sent when the LoadListener has data available
- * in it's data buffer. This data buffer could be filled from a
- * file (this thread) or from http (Network thread).
- */
- if (mNativeLoader != 0 && !ignoreCallbacks()) {
- commitLoad();
- }
- break;
-
- case MSG_CONTENT_FINISHED:
- /*
- * This message is sent when the LoadListener knows that the
- * load is finished. This message is not sent in the case of an
- * error.
- *
- */
- handleEndData();
- break;
-
- case MSG_CONTENT_ERROR:
- /*
- * This message is sent when a load error has occured. The
- * LoadListener will clean itself up.
- */
- handleError(msg.arg1, (String) msg.obj);
- break;
-
- case MSG_LOCATION_CHANGED:
- /*
- * This message is sent from LoadListener.endData to inform the
- * browser activity that the location of the top level page
- * changed.
- */
- doRedirect();
- break;
-
- case MSG_LOCATION_CHANGED_REQUEST:
- /*
- * This message is sent from endData on receipt of a 307
- * Temporary Redirect in response to a POST -- the user must
- * confirm whether to continue loading. If the user says Yes,
- * we simply call MSG_LOCATION_CHANGED. If the user says No,
- * we call MSG_CONTENT_FINISHED.
- */
- Message contMsg = obtainMessage(MSG_LOCATION_CHANGED);
- Message stopMsg = obtainMessage(MSG_CONTENT_FINISHED);
- mBrowserFrame.getCallbackProxy().onFormResubmission(
- stopMsg, contMsg);
- break;
-
- case MSG_STATUS:
- /*
- * This message is sent from the network thread when the http
- * stack has received the status response from the server.
- */
- HashMap status = (HashMap) msg.obj;
- handleStatus(((Integer) status.get("major")).intValue(),
- ((Integer) status.get("minor")).intValue(),
- ((Integer) status.get("code")).intValue(),
- (String) status.get("reason"));
- break;
-
- case MSG_SSL_CERTIFICATE:
- /*
- * This message is sent when the network thread receives a ssl
- * certificate.
- */
- handleCertificate((SslCertificate) msg.obj);
- break;
-
- case MSG_SSL_ERROR:
- /*
- * This message is sent when the network thread encounters a
- * ssl error.
- */
- handleSslError((SslError) msg.obj);
- break;
- }
- }
-
- /**
- * @return The loader's BrowserFrame.
- */
- BrowserFrame getFrame() {
- return mBrowserFrame;
- }
-
- Context getContext() {
- return mContext;
- }
-
- /* package */ boolean isSynchronous() {
- return mSynchronous;
- }
-
- /**
- * @return True iff the load has been cancelled
- */
- public boolean cancelled() {
- return mCancelled;
- }
-
- /**
- * Parse the headers sent from the server.
- * @param headers gives up the HeaderGroup
- * IMPORTANT: as this is called from network thread, can't call native
- * directly
- */
- public void headers(Headers headers) {
- if (DebugFlags.LOAD_LISTENER) Log.v(LOGTAG, "LoadListener.headers");
- // call db (setCookie) in the non-WebCore thread
- if (mCancelled) return;
- ArrayList<String> cookies = headers.getSetCookie();
- for (int i = 0; i < cookies.size(); ++i) {
- CookieManager.getInstance().setCookie(mUri, cookies.get(i));
- }
- sendMessageInternal(obtainMessage(MSG_CONTENT_HEADERS, headers));
- }
-
- // This is the same regex that DOMImplementation uses to check for xml
- // content. Use this to check if another Activity wants to handle the
- // content before giving it to webkit.
- private static final String XML_MIME_TYPE =
- "^[\\w_\\-+~!$\\^{}|.%'`#&*]+/" +
- "[\\w_\\-+~!$\\^{}|.%'`#&*]+\\+xml$";
-
- // Does the header parsing work on the WebCore thread.
- private void handleHeaders(Headers headers) {
- if (mCancelled) return;
-
- // Note: the headers we care in LoadListeners, like
- // content-type/content-length, should not be updated for partial
- // content. Just skip here and go ahead with adding data.
- if (mStatusCode == HTTP_PARTIAL_CONTENT) {
- // we don't support cache for partial content yet
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget();
- return;
- }
-
- mHeaders = headers;
-
- long contentLength = headers.getContentLength();
- if (contentLength != Headers.NO_CONTENT_LENGTH) {
- mContentLength = contentLength;
- } else {
- mContentLength = 0;
- }
-
- String contentType = headers.getContentType();
- if (contentType != null) {
- parseContentTypeHeader(contentType);
- mMimeType = MimeTypeMap.getSingleton().remapGenericMimeType(
- mMimeType, mUrl, headers.getContentDisposition());
- } else {
- /* Often when servers respond with 304 Not Modified or a
- Redirect, then they don't specify a MIMEType. When this
- occurs, the function below is called. In the case of
- 304 Not Modified, the cached headers are used rather
- than the headers that are returned from the server. */
- guessMimeType();
- }
- // At this point, mMimeType has been set to non-null.
- if (mIsMainPageLoader && mIsMainResourceLoader && mUserGesture &&
- Pattern.matches(XML_MIME_TYPE, mMimeType) &&
- !mMimeType.equalsIgnoreCase("application/xhtml+xml")) {
- Intent i = new Intent(Intent.ACTION_VIEW);
- i.setDataAndType(Uri.parse(url()), mMimeType);
- ResolveInfo info = mContext.getPackageManager().resolveActivity(i,
- PackageManager.MATCH_DEFAULT_ONLY);
- if (info != null && !mContext.getPackageName().equals(
- info.activityInfo.packageName)) {
- // someone (other than the current app) knows how to
- // handle this mime type.
- try {
- mContext.startActivity(i);
- mBrowserFrame.stopLoading();
- return;
- } catch (ActivityNotFoundException ex) {
- // continue loading internally.
- }
- }
- }
-
- // is it an authentication request?
- boolean mustAuthenticate = (mStatusCode == HTTP_AUTH ||
- mStatusCode == HTTP_PROXY_AUTH);
- // is it a proxy authentication request?
- boolean isProxyAuthRequest = (mStatusCode == HTTP_PROXY_AUTH);
- // is this authentication request due to a failed attempt to
- // authenticate ealier?
- mAuthFailed = false;
-
- // if we tried to authenticate ourselves last time
- if (mAuthHeader != null) {
- // we failed, if we must authenticate again now and
- // we have a proxy-ness match
- mAuthFailed = (mustAuthenticate &&
- isProxyAuthRequest == mAuthHeader.isProxy());
-
- // if we did NOT fail and last authentication request was a
- // proxy-authentication request
- if (!mAuthFailed && mAuthHeader.isProxy()) {
- Network network = Network.getInstance(mContext);
- // if we have a valid proxy set
- if (network.isValidProxySet()) {
- /* The proxy credentials can be read in the WebCore thread
- */
- synchronized (network) {
- // save authentication credentials for pre-emptive proxy
- // authentication
- network.setProxyUsername(mAuthHeader.getUsername());
- network.setProxyPassword(mAuthHeader.getPassword());
- }
- }
- }
- }
-
- // it is only here that we can reset the last mAuthHeader object
- // (if existed) and start a new one!!!
- mAuthHeader = null;
- if (mustAuthenticate) {
- if (mStatusCode == HTTP_AUTH) {
- mAuthHeader = parseAuthHeader(
- headers.getWwwAuthenticate());
- } else {
- mAuthHeader = parseAuthHeader(
- headers.getProxyAuthenticate());
- // if successfully parsed the header
- if (mAuthHeader != null) {
- // mark the auth-header object as a proxy
- mAuthHeader.setProxy();
- }
- }
- }
-
- // Only create a cache file if the server has responded positively.
- if ((mStatusCode == HTTP_OK ||
- mStatusCode == HTTP_FOUND ||
- mStatusCode == HTTP_MOVED_PERMANENTLY ||
- mStatusCode == HTTP_TEMPORARY_REDIRECT) &&
- mNativeLoader != 0) {
- // for POST request, only cache the result if there is an identifier
- // associated with it. postUrl() or form submission should set the
- // identifier while XHR POST doesn't.
- if (!mFromCache && mRequestHandle != null
- && (!mRequestHandle.getMethod().equals("POST")
- || mPostIdentifier != 0)) {
- WebViewWorker.CacheCreateData data = new WebViewWorker.CacheCreateData();
- data.mListener = this;
- data.mUrl = mUrl;
- data.mMimeType = mMimeType;
- data.mStatusCode = mStatusCode;
- data.mPostId = mPostIdentifier;
- data.mHeaders = headers;
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_CREATE_CACHE, data).sendToTarget();
- }
- WebViewWorker.CacheEncoding ce = new WebViewWorker.CacheEncoding();
- ce.mEncoding = mEncoding;
- ce.mListener = this;
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_UPDATE_CACHE_ENCODING, ce).sendToTarget();
- }
- commitHeadersCheckRedirect();
- }
-
- /**
- * @return True iff this loader is in the proxy-authenticate state.
- */
- boolean proxyAuthenticate() {
- if (mAuthHeader != null) {
- return mAuthHeader.isProxy();
- }
-
- return false;
- }
-
- /**
- * Report the status of the response.
- * TODO: Comments about each parameter.
- * IMPORTANT: as this is called from network thread, can't call native
- * directly
- */
- public void status(int majorVersion, int minorVersion,
- int code, /* Status-Code value */ String reasonPhrase) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener: from: " + mUrl
- + " major: " + majorVersion
- + " minor: " + minorVersion
- + " code: " + code
- + " reason: " + reasonPhrase);
- }
- HashMap status = new HashMap();
- status.put("major", majorVersion);
- status.put("minor", minorVersion);
- status.put("code", code);
- status.put("reason", reasonPhrase);
- // New status means new data. Clear the old.
- mDataBuilder.clear();
- mMimeType = "";
- mEncoding = "";
- mTransferEncoding = "";
- sendMessageInternal(obtainMessage(MSG_STATUS, status));
- }
-
- // Handle the status callback on the WebCore thread.
- private void handleStatus(int major, int minor, int code, String reason) {
- if (mCancelled) return;
-
- mStatusCode = code;
- mStatusText = reason;
- mPermanent = false;
- }
-
- /**
- * Implementation of certificate handler for EventHandler. Called
- * before a resource is requested. In this context, can be called
- * multiple times if we have redirects
- *
- * IMPORTANT: as this is called from network thread, can't call
- * native directly
- *
- * @param certificate The SSL certifcate or null if the request
- * was not secure
- */
- public void certificate(SslCertificate certificate) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.certificate: " + certificate);
- }
- sendMessageInternal(obtainMessage(MSG_SSL_CERTIFICATE, certificate));
- }
-
- // Handle the certificate on the WebCore thread.
- private void handleCertificate(SslCertificate certificate) {
- // if this is main resource of the top frame
- if (mIsMainPageLoader && mIsMainResourceLoader) {
- // update the browser frame with certificate
- mBrowserFrame.certificate(certificate);
- }
- }
-
- /**
- * Implementation of error handler for EventHandler.
- * Subclasses should call this method to have error fields set.
- * @param id The error id described by EventHandler.
- * @param description A string description of the error.
- * IMPORTANT: as this is called from network thread, can't call native
- * directly
- */
- public void error(int id, String description) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.error url:" +
- url() + " id:" + id + " description:" + description);
- }
- sendMessageInternal(obtainMessage(MSG_CONTENT_ERROR, id, 0, description));
- }
-
- // Handle the error on the WebCore thread.
- private void handleError(int id, String description) {
- mErrorID = id;
- mErrorDescription = description;
- detachRequestHandle();
- notifyError();
- tearDown();
- }
-
- /**
- * Add data to the internal collection of data. This function is used by
- * the data: scheme, about: scheme and http/https schemes.
- * @param data A byte array containing the content.
- * @param length The length of data.
- * IMPORTANT: as this is called from network thread, can't call native
- * directly
- * XXX: Unlike the other network thread methods, this method can do the
- * work of decoding the data and appending it to the data builder.
- */
- public void data(byte[] data, int length) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.data(): url: " + url());
- }
-
- // The reason isEmpty() and append() need to synchronized together is
- // because it is possible for getFirstChunk() to be called multiple
- // times between isEmpty() and append(). This could cause commitLoad()
- // to finish before processing the newly appended data and no message
- // will be sent.
- boolean sendMessage = false;
- synchronized (mDataBuilder) {
- sendMessage = mDataBuilder.isEmpty();
- mDataBuilder.append(data, 0, length);
- }
- if (sendMessage) {
- // Send a message whenever data comes in after a write to WebCore
- sendMessageInternal(obtainMessage(MSG_CONTENT_DATA));
- }
- }
-
- /**
- * Event handler's endData call. Send a message to the handler notifying
- * them that the data has finished.
- * IMPORTANT: as this is called from network thread, can't call native
- * directly
- */
- public void endData() {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.endData(): url: " + url());
- }
- sendMessageInternal(obtainMessage(MSG_CONTENT_FINISHED));
- }
-
- // Handle the end of data.
- private void handleEndData() {
- if (mCancelled) return;
-
- switch (mStatusCode) {
- case HTTP_MOVED_PERMANENTLY:
- // 301 - permanent redirect
- mPermanent = true;
- case HTTP_FOUND:
- case HTTP_SEE_OTHER:
- case HTTP_TEMPORARY_REDIRECT:
- // 301, 302, 303, and 307 - redirect
- if (mStatusCode == HTTP_TEMPORARY_REDIRECT) {
- if (mRequestHandle != null &&
- mRequestHandle.getMethod().equals("POST")) {
- sendMessageInternal(obtainMessage(
- MSG_LOCATION_CHANGED_REQUEST));
- } else if (mMethod != null && mMethod.equals("POST")) {
- sendMessageInternal(obtainMessage(
- MSG_LOCATION_CHANGED_REQUEST));
- } else {
- sendMessageInternal(obtainMessage(MSG_LOCATION_CHANGED));
- }
- } else {
- sendMessageInternal(obtainMessage(MSG_LOCATION_CHANGED));
- }
- return;
-
- case HTTP_AUTH:
- case HTTP_PROXY_AUTH:
- // According to rfc2616, the response for HTTP_AUTH must include
- // WWW-Authenticate header field and the response for
- // HTTP_PROXY_AUTH must include Proxy-Authenticate header field.
- if (mAuthHeader != null &&
- (Network.getInstance(mContext).isValidProxySet() ||
- !mAuthHeader.isProxy())) {
- // If this is the first attempt to authenticate, try again with the username and
- // password supplied in the URL, if present.
- if (!mAuthFailed && mUsername != null && mPassword != null) {
- String host = mAuthHeader.isProxy() ?
- Network.getInstance(mContext).getProxyHostname() :
- mUri.getHost();
- HttpAuthHandlerImpl.onReceivedCredentials(this, host,
- mAuthHeader.getRealm(), mUsername, mPassword);
- makeAuthResponse(mUsername, mPassword);
- } else {
- Network.getInstance(mContext).handleAuthRequest(this);
- }
- return;
- }
- break; // use default
-
- case HTTP_NOT_MODIFIED:
- // Server could send back NOT_MODIFIED even if we didn't
- // ask for it, so make sure we have a valid CacheLoader
- // before calling it.
- if (mCacheLoader != null) {
- if (isSynchronous()) {
- mCacheLoader.load();
- } else {
- // Load the cached file in a separate thread
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER, mCacheLoader)
- .sendToTarget();
- }
- mFromCache = true;
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener cache load url=" + url());
- }
- return;
- }
- break; // use default
-
- case HTTP_NOT_FOUND:
- // Not an error, the server can send back content.
- default:
- break;
- }
- detachRequestHandle();
- tearDown();
- }
-
- /* This method is called from CacheLoader when the initial request is
- * serviced by the Cache. */
- /* package */ void setCacheLoader(CacheLoader c) {
- mCacheLoader = c;
- mFromCache = true;
- }
-
- /**
- * Check the cache for the current URL, and load it if it is valid.
- *
- * @param headers for the request
- * @return true if cached response is used.
- */
- boolean checkCache(Map<String, String> headers) {
- // Get the cache file name for the current URL
- CacheResult result = CacheManager.getCacheFile(url(), mPostIdentifier,
- headers);
-
- // Go ahead and set the cache loader to null in case the result is
- // null.
- mCacheLoader = null;
- // reset the flag
- mFromCache = false;
-
- if (result != null) {
- // The contents of the cache may need to be revalidated so just
- // remember the cache loader in the case that the server responds
- // positively to the cached content. This is also used to detect if
- // a redirect came from the cache.
- mCacheLoader = new CacheLoader(this, result);
-
- // If I got a cachedUrl and the revalidation header was not
- // added, then the cached content valid, we should use it.
- if (!headers.containsKey(
- CacheManager.HEADER_KEY_IFNONEMATCH) &&
- !headers.containsKey(
- CacheManager.HEADER_KEY_IFMODIFIEDSINCE)) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "FrameLoader: HTTP URL in cache " +
- "and usable: " + url());
- }
- if (isSynchronous()) {
- mCacheLoader.load();
- } else {
- // Load the cached file in a separate thread
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_ADD_STREAMLOADER, mCacheLoader)
- .sendToTarget();
- }
- mFromCache = true;
- return true;
- }
- }
- return false;
- }
-
- /**
- * SSL certificate error callback. Handles SSL error(s) on the way up
- * to the user.
- * IMPORTANT: as this is called from network thread, can't call native
- * directly
- */
- public boolean handleSslErrorRequest(SslError error) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG,
- "LoadListener.handleSslErrorRequest(): url:" + url() +
- " primary error: " + error.getPrimaryError() +
- " certificate: " + error.getCertificate());
- }
- // Check the cached preference table before sending a message. This
- // will prevent waiting for an already available answer.
- if (Network.getInstance(mContext).checkSslPrefTable(this, error)) {
- return true;
- }
- // Do not post a message for a synchronous request. This will cause a
- // deadlock. Just bail on the request.
- if (isSynchronous()) {
- mRequestHandle.handleSslErrorResponse(false);
- return true;
- }
- sendMessageInternal(obtainMessage(MSG_SSL_ERROR, error));
- // if it has been canceled, return false so that the network thread
- // won't be blocked. If it is not canceled, save the mRequestHandle
- // so that if it is canceled when MSG_SSL_ERROR is handled, we can
- // still call handleSslErrorResponse which will call restartConnection
- // to unblock the network thread.
- if (!mCancelled) {
- mSslErrorRequestHandle = mRequestHandle;
- }
- return !mCancelled;
- }
-
- // Handle the ssl error on the WebCore thread.
- private void handleSslError(SslError error) {
- if (!mCancelled) {
- mSslError = error;
- Network.getInstance(mContext).handleSslErrorRequest(this);
- } else if (mSslErrorRequestHandle != null) {
- mSslErrorRequestHandle.handleSslErrorResponse(true);
- }
- mSslErrorRequestHandle = null;
- }
-
- /**
- * @return HTTP authentication realm or null if none.
- */
- String realm() {
- if (mAuthHeader == null) {
- return null;
- } else {
- return mAuthHeader.getRealm();
- }
- }
-
- /**
- * Returns true iff an HTTP authentication problem has
- * occured (credentials invalid).
- */
- boolean authCredentialsInvalid() {
- // if it is digest and the nonce is stale, we just
- // resubmit with a new nonce
- return (mAuthFailed &&
- !(mAuthHeader.isDigest() && mAuthHeader.getStale()));
- }
-
- /**
- * @return The last SSL error or null if there is none
- */
- SslError sslError() {
- return mSslError;
- }
-
- /**
- * Handles SSL error(s) on the way down from the user
- * (the user has already provided their feedback).
- */
- void handleSslErrorResponse(boolean proceed) {
- if (mRequestHandle != null) {
- mRequestHandle.handleSslErrorResponse(proceed);
- }
- if (!proceed) {
- mBrowserFrame.stopLoading();
- tearDown();
- }
- }
-
- /**
- * Uses user-supplied credentials to restart a request. If the credentials
- * are null, cancel the request.
- */
- void handleAuthResponse(String username, String password) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.handleAuthResponse: url: " + mUrl
- + " username: " + username
- + " password: " + password);
- }
- if (username != null && password != null) {
- makeAuthResponse(username, password);
- } else {
- // Commit whatever data we have and tear down the loader.
- commitLoad();
- tearDown();
- }
- }
-
- void makeAuthResponse(String username, String password) {
- if (mAuthHeader == null || mRequestHandle == null) {
- return;
- }
-
- mAuthHeader.setUsername(username);
- mAuthHeader.setPassword(password);
-
- int scheme = mAuthHeader.getScheme();
- if (scheme == HttpAuthHeader.BASIC) {
- // create a basic response
- boolean isProxy = mAuthHeader.isProxy();
-
- mRequestHandle.setupBasicAuthResponse(isProxy, username, password);
- } else if (scheme == HttpAuthHeader.DIGEST) {
- // create a digest response
- boolean isProxy = mAuthHeader.isProxy();
-
- String realm = mAuthHeader.getRealm();
- String nonce = mAuthHeader.getNonce();
- String qop = mAuthHeader.getQop();
- String algorithm = mAuthHeader.getAlgorithm();
- String opaque = mAuthHeader.getOpaque();
-
- mRequestHandle.setupDigestAuthResponse(isProxy, username, password,
- realm, nonce, qop, algorithm, opaque);
- }
- }
-
- /**
- * This is called when a request can be satisfied by the cache, however,
- * the cache result could be a redirect. In this case we need to issue
- * the network request.
- * @param method
- * @param headers
- * @param postData
- */
- void setRequestData(String method, Map<String, String> headers,
- byte[] postData) {
- mMethod = method;
- mRequestHeaders = headers;
- mPostData = postData;
- }
-
- /**
- * @return The current URL associated with this load.
- */
- String url() {
- return mUrl;
- }
-
- /**
- * @return The current WebAddress associated with this load.
- */
- WebAddress getWebAddress() {
- return mUri;
- }
-
- /**
- * @return URL hostname (current URL).
- */
- String host() {
- if (mUri != null) {
- return mUri.getHost();
- }
-
- return null;
- }
-
- /**
- * @return The original URL associated with this load.
- */
- String originalUrl() {
- if (mOriginalUrl != null) {
- return mOriginalUrl;
- } else {
- return mUrl;
- }
- }
-
- long postIdentifier() {
- return mPostIdentifier;
- }
-
- void attachRequestHandle(RequestHandle requestHandle) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.attachRequestHandle(): " +
- "requestHandle: " + requestHandle);
- }
- mRequestHandle = requestHandle;
- }
-
- void detachRequestHandle() {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.detachRequestHandle(): " +
- "requestHandle: " + mRequestHandle);
- }
- mRequestHandle = null;
- }
-
- /*
- * This function is called from native WebCore code to
- * notify this LoadListener that the content it is currently
- * downloading should be saved to a file and not sent to
- * WebCore.
- */
- void downloadFile() {
- // remove the cache
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget();
-
- // Inform the client that they should download a file
- mBrowserFrame.getCallbackProxy().onDownloadStart(url(),
- mBrowserFrame.getUserAgentString(),
- mHeaders.getContentDisposition(),
- mMimeType, mContentLength);
-
- // Cancel the download. We need to stop the http load.
- // The native loader object will get cleared by the call to
- // cancel() but will also be cleared on the WebCore side
- // when this function returns.
- cancel();
- }
-
- /*
- * This function is called from native WebCore code to
- * find out if the given URL is in the cache, and if it can
- * be used. This is just for forward/back navigation to a POST
- * URL.
- */
- private static boolean willLoadFromCache(String url, long identifier) {
- assert !JniUtil.useChromiumHttpStack();
- boolean inCache =
- CacheManager.getCacheFile(url, identifier, null) != null;
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "willLoadFromCache: " + url + " in cache: " +
- inCache);
- }
- return inCache;
- }
-
- /*
- * Reset the cancel flag. This is used when we are resuming a stopped
- * download. To suspend a download, we cancel it. It can also be cancelled
- * when it has run out of disk space. In this situation, the download
- * can be resumed.
- */
- void resetCancel() {
- mCancelled = false;
- }
-
- String mimeType() {
- return mMimeType;
- }
-
- String transferEncoding() {
- return mTransferEncoding;
- }
-
- /*
- * Return the size of the content being downloaded. This represents the
- * full content size, even under the situation where the download has been
- * resumed after interruption.
- *
- * @ return full content size
- */
- long contentLength() {
- return mContentLength;
- }
-
- // Commit the headers if the status code is not a redirect.
- private void commitHeadersCheckRedirect() {
- if (mCancelled) return;
-
- // do not call webcore if it is redirect. According to the code in
- // InspectorController::willSendRequest(), the response is only updated
- // when it is not redirect. If we received a not-modified response from
- // the server and mCacheLoader is not null, do not send the response to
- // webkit. This is just a validation response for loading from the
- // cache.
- if ((mStatusCode >= 301 && mStatusCode <= 303) || mStatusCode == 307 ||
- (mStatusCode == 304 && mCacheLoader != null)) {
- return;
- }
-
- commitHeaders();
- }
-
- // This commits the headers without checking the response status code.
- private void commitHeaders() {
- if (mIsMainPageLoader && CertTool.getCertType(mMimeType) != null) {
- // In the case of downloading certificate, we will save it to the
- // KeyStore in commitLoad. Do not call webcore.
- return;
- }
-
- // If the response is an authentication and we've resent the
- // request with some credentials then don't commit the headers
- // of this response; wait for the response to the request with the
- // credentials.
- if (mAuthHeader != null) {
- return;
- }
-
- setNativeResponse();
- }
-
- private void setNativeResponse() {
- int nativeResponse = createNativeResponse();
- // The native code deletes the native response object.
- nativeReceivedResponse(nativeResponse);
- mSetNativeResponse = true;
- }
-
- /**
- * Create a WebCore response object so that it can be used by
- * nativeReceivedResponse or nativeRedirectedToUrl
- * @return native response pointer
- */
- private int createNativeResponse() {
- // If WebCore sends if-modified-since, mCacheLoader is null. If
- // CacheManager sends it, mCacheLoader is not null. In this case, if the
- // server responds with a 304, then we treat it like it was a 200 code
- // and proceed with loading the file from the cache.
- int statusCode = (mStatusCode == HTTP_NOT_MODIFIED &&
- mCacheLoader != null) ? HTTP_OK : mStatusCode;
- // pass content-type content-length and content-encoding
- final int nativeResponse = nativeCreateResponse(
- originalUrl(), statusCode, mStatusText,
- mMimeType, mContentLength, mEncoding);
- if (mHeaders != null) {
- mHeaders.getHeaders(new Headers.HeaderCallback() {
- public void header(String name, String value) {
- nativeSetResponseHeader(nativeResponse, name, value);
- }
- });
- }
- return nativeResponse;
- }
-
- /**
- * Commit the load. It should be ok to call repeatedly but only before
- * tearDown is called.
- */
- private void commitLoad() {
- if (mCancelled) return;
- if (!mSetNativeResponse) {
- setNativeResponse();
- }
-
- if (mIsMainPageLoader) {
- String type = CertTool.getCertType(mMimeType);
- if (type != null) {
- // This must be synchronized so that no more data can be added
- // after getByteSize returns.
- synchronized (mDataBuilder) {
- // In the case of downloading certificate, we will save it
- // to the KeyStore and stop the current loading so that it
- // will not generate a new history page
- byte[] cert = new byte[mDataBuilder.getByteSize()];
- int offset = 0;
- while (true) {
- ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk();
- if (c == null) break;
-
- if (c.mLength != 0) {
- System.arraycopy(c.mArray, 0, cert, offset, c.mLength);
- offset += c.mLength;
- }
- c.release();
- }
- CertTool.addCertificate(mContext, type, cert);
- mBrowserFrame.stopLoading();
- return;
- }
- }
- }
-
- // Give the data to WebKit now. We don't have to synchronize on
- // mDataBuilder here because pulling each chunk removes it from the
- // internal list so it cannot be modified.
- ByteArrayBuilder.Chunk c;
- while (true) {
- c = mDataBuilder.getFirstChunk();
- if (c == null) break;
-
- if (c.mLength != 0) {
- nativeAddData(c.mArray, c.mLength);
- WebViewWorker.CacheData data = new WebViewWorker.CacheData();
- data.mListener = this;
- data.mChunk = c;
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_APPEND_CACHE, data).sendToTarget();
- } else {
- c.release();
- }
- }
- }
-
- /**
- * Tear down the load. Subclasses should clean up any mess because of
- * cancellation or errors during the load.
- */
- void tearDown() {
- if (getErrorID() == OK) {
- WebViewWorker.CacheSaveData data = new WebViewWorker.CacheSaveData();
- data.mListener = this;
- data.mUrl = mUrl;
- data.mPostId = mPostIdentifier;
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_SAVE_CACHE, data).sendToTarget();
- } else {
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget();
- }
- if (mNativeLoader != 0) {
- if (!mSetNativeResponse) {
- setNativeResponse();
- }
-
- nativeFinished();
- clearNativeLoader();
- }
- }
-
- /**
- * Helper for getting the error ID.
- * @return errorID.
- */
- private int getErrorID() {
- return mErrorID;
- }
-
- /**
- * Return the error description.
- * @return errorDescription.
- */
- private String getErrorDescription() {
- return mErrorDescription;
- }
-
- /**
- * Notify the loader we encountered an error.
- */
- void notifyError() {
- if (mNativeLoader != 0) {
- String description = getErrorDescription();
- if (description == null) description = "";
- nativeError(getErrorID(), description, url());
- clearNativeLoader();
- }
- }
-
- /**
- * Pause the load. For example, if a plugin is unable to accept more data,
- * we pause reading from the request. Called directly from the WebCore thread.
- */
- void pauseLoad(boolean pause) {
- if (mRequestHandle != null) {
- mRequestHandle.pauseRequest(pause);
- }
- }
-
- /**
- * Cancel a request.
- * FIXME: This will only work if the request has yet to be handled. This
- * is in no way guarenteed if requests are served in a separate thread.
- * It also causes major problems if cancel is called during an
- * EventHandler's method call.
- */
- public void cancel() {
- if (DebugFlags.LOAD_LISTENER) {
- if (mRequestHandle == null) {
- Log.v(LOGTAG, "LoadListener.cancel(): no requestHandle");
- } else {
- Log.v(LOGTAG, "LoadListener.cancel()");
- }
- }
- if (mRequestHandle != null) {
- mRequestHandle.cancel();
- mRequestHandle = null;
- }
-
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget();
- mCancelled = true;
-
- clearNativeLoader();
- }
-
- // This count is transferred from RequestHandle to LoadListener when
- // loading from the cache so that we can detect redirect loops that switch
- // between the network and the cache.
- private int mCacheRedirectCount;
-
- /*
- * Perform the actual redirection. This involves setting up the new URL,
- * informing WebCore and then telling the Network to start loading again.
- */
- private void doRedirect() {
- // as cancel() can cancel the load before doRedirect() is
- // called through handleMessage, needs to check to see if we
- // are canceled before proceed
- if (mCancelled) {
- return;
- }
-
- // Do the same check for a redirect loop that
- // RequestHandle.setupRedirect does.
- if (mCacheRedirectCount >= RequestHandle.MAX_REDIRECT_COUNT) {
- handleError(EventHandler.ERROR_REDIRECT_LOOP, mContext.getString(
- R.string.httpErrorRedirectLoop));
- return;
- }
-
- String redirectTo = mHeaders.getLocation();
- if (redirectTo != null) {
- int nativeResponse = createNativeResponse();
- redirectTo =
- nativeRedirectedToUrl(mUrl, redirectTo, nativeResponse);
- // nativeRedirectedToUrl() may call cancel(), e.g. when redirect
- // from a https site to a http site, check mCancelled again
- if (mCancelled) {
- return;
- }
- if (redirectTo == null) {
- Log.d(LOGTAG, "Redirection failed for "
- + mHeaders.getLocation());
- cancel();
- return;
- } else if (!URLUtil.isNetworkUrl(redirectTo)) {
- final String text = mContext
- .getString(R.string.open_permission_deny)
- + "\n" + redirectTo;
- if (!mSetNativeResponse) {
- setNativeResponse();
- }
- nativeAddData(text.getBytes(), text.length());
- nativeFinished();
- clearNativeLoader();
- return;
- }
-
-
- // Cache the redirect response
- if (getErrorID() == OK) {
- WebViewWorker.CacheSaveData data = new WebViewWorker.CacheSaveData();
- data.mListener = this;
- data.mUrl = mUrl;
- data.mPostId = mPostIdentifier;
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_SAVE_CACHE, data).sendToTarget();
- } else {
- WebViewWorker.getHandler().obtainMessage(
- WebViewWorker.MSG_REMOVE_CACHE, this).sendToTarget();
- }
-
- // Saving a copy of the unstripped url for the response
- mOriginalUrl = redirectTo;
- // This will strip the anchor
- setUrl(redirectTo);
-
- // Redirect may be in the cache
- if (mRequestHeaders == null) {
- mRequestHeaders = new HashMap<String, String>();
- }
- boolean fromCache = false;
- if (mCacheLoader != null) {
- // This is a redirect from the cache loader. Increment the
- // redirect count to avoid redirect loops.
- mCacheRedirectCount++;
- fromCache = true;
- }
- if (!checkCache(mRequestHeaders)) {
- // mRequestHandle can be null when the request was satisfied
- // by the cache, and the cache returned a redirect
- if (mRequestHandle != null) {
- try {
- mRequestHandle.setupRedirect(mUrl, mStatusCode,
- mRequestHeaders);
- } catch(RuntimeException e) {
- Log.e(LOGTAG, e.getMessage());
- // Signal a bad url error if we could not load the
- // redirection.
- handleError(EventHandler.ERROR_BAD_URL,
- mContext.getString(R.string.httpErrorBadUrl));
- return;
- }
- } else {
- // If the original request came from the cache, there is no
- // RequestHandle, we have to create a new one through
- // Network.requestURL.
- Network network = Network.getInstance(getContext());
- if (!network.requestURL(mMethod, mRequestHeaders,
- mPostData, this)) {
- // Signal a bad url error if we could not load the
- // redirection.
- handleError(EventHandler.ERROR_BAD_URL,
- mContext.getString(R.string.httpErrorBadUrl));
- return;
- }
- }
- if (fromCache) {
- // If we are coming from a cache load, we need to transfer
- // the redirect count to the new (or old) RequestHandle to
- // keep the redirect count in sync.
- mRequestHandle.setRedirectCount(mCacheRedirectCount);
- }
- } else if (!fromCache) {
- // Switching from network to cache means we need to grab the
- // redirect count from the RequestHandle to keep the count in
- // sync. Add 1 to account for the current redirect.
- mCacheRedirectCount = mRequestHandle.getRedirectCount() + 1;
- }
- } else {
- commitHeaders();
- commitLoad();
- tearDown();
- }
-
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.onRedirect(): redirect to: " +
- redirectTo);
- }
- }
-
- /**
- * Parses the content-type header.
- * The first part only allows '-' if it follows x or X.
- */
- private static final Pattern CONTENT_TYPE_PATTERN =
- Pattern.compile("^((?:[xX]-)?[a-zA-Z\\*]+/[\\w\\+\\*-]+[\\.[\\w\\+-]+]*)$");
-
- /* package */ void parseContentTypeHeader(String contentType) {
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "LoadListener.parseContentTypeHeader: " +
- "contentType: " + contentType);
- }
-
- if (contentType != null) {
- int i = contentType.indexOf(';');
- if (i >= 0) {
- mMimeType = contentType.substring(0, i);
-
- int j = contentType.indexOf('=', i);
- if (j > 0) {
- i = contentType.indexOf(';', j);
- if (i < j) {
- i = contentType.length();
- }
- mEncoding = contentType.substring(j + 1, i);
- } else {
- mEncoding = contentType.substring(i + 1);
- }
- // Trim excess whitespace.
- mEncoding = mEncoding.trim().toLowerCase();
-
- if (i < contentType.length() - 1) {
- // for data: uri the mimeType and encoding have
- // the form image/jpeg;base64 or text/plain;charset=utf-8
- // or text/html;charset=utf-8;base64
- mTransferEncoding =
- contentType.substring(i + 1).trim().toLowerCase();
- }
- } else {
- mMimeType = contentType;
- }
-
- // Trim leading and trailing whitespace
- mMimeType = mMimeType.trim();
-
- try {
- Matcher m = CONTENT_TYPE_PATTERN.matcher(mMimeType);
- if (m.find()) {
- mMimeType = m.group(1);
- } else {
- guessMimeType();
- }
- } catch (IllegalStateException ex) {
- guessMimeType();
- }
- }
- // Ensure mMimeType is lower case.
- mMimeType = mMimeType.toLowerCase();
- }
-
- /**
- * @return The HTTP-authentication object or null if there
- * is no supported scheme in the header.
- * If there are several valid schemes present, we pick the
- * strongest one. If there are several schemes of the same
- * strength, we pick the one that comes first.
- */
- private HttpAuthHeader parseAuthHeader(String header) {
- if (header != null) {
- int posMax = 256;
- int posLen = 0;
- int[] pos = new int [posMax];
-
- int headerLen = header.length();
- if (headerLen > 0) {
- // first, we find all unquoted instances of 'Basic' and 'Digest'
- boolean quoted = false;
- for (int i = 0; i < headerLen && posLen < posMax; ++i) {
- if (header.charAt(i) == '\"') {
- quoted = !quoted;
- } else {
- if (!quoted) {
- if (header.regionMatches(true, i,
- HttpAuthHeader.BASIC_TOKEN, 0,
- HttpAuthHeader.BASIC_TOKEN.length())) {
- pos[posLen++] = i;
- continue;
- }
-
- if (header.regionMatches(true, i,
- HttpAuthHeader.DIGEST_TOKEN, 0,
- HttpAuthHeader.DIGEST_TOKEN.length())) {
- pos[posLen++] = i;
- continue;
- }
- }
- }
- }
- }
-
- if (posLen > 0) {
- // consider all digest schemes first (if any)
- for (int i = 0; i < posLen; i++) {
- if (header.regionMatches(true, pos[i],
- HttpAuthHeader.DIGEST_TOKEN, 0,
- HttpAuthHeader.DIGEST_TOKEN.length())) {
- String sub = header.substring(pos[i],
- (i + 1 < posLen ? pos[i + 1] : headerLen));
-
- HttpAuthHeader rval = new HttpAuthHeader(sub);
- if (rval.isSupportedScheme()) {
- // take the first match
- return rval;
- }
- }
- }
-
- // ...then consider all basic schemes (if any)
- for (int i = 0; i < posLen; i++) {
- if (header.regionMatches(true, pos[i],
- HttpAuthHeader.BASIC_TOKEN, 0,
- HttpAuthHeader.BASIC_TOKEN.length())) {
- String sub = header.substring(pos[i],
- (i + 1 < posLen ? pos[i + 1] : headerLen));
-
- HttpAuthHeader rval = new HttpAuthHeader(sub);
- if (rval.isSupportedScheme()) {
- // take the first match
- return rval;
- }
- }
- }
- }
- }
-
- return null;
- }
-
- /**
- * If the content is a redirect or not modified we should not send
- * any data into WebCore as that will cause it create a document with
- * the data, then when we try to provide the real content, it will assert.
- *
- * @return True iff the callback should be ignored.
- */
- private boolean ignoreCallbacks() {
- return (mCancelled || mAuthHeader != null ||
- // Allow 305 (Use Proxy) to call through.
- (mStatusCode > 300 && mStatusCode < 400 && mStatusCode != 305));
- }
-
- /**
- * Sets the current URL associated with this load.
- */
- void setUrl(String url) {
- if (url != null) {
- mUri = null;
- if (URLUtil.isNetworkUrl(url)) {
- mUrl = URLUtil.stripAnchor(url);
- try {
- mUri = new WebAddress(mUrl);
- } catch (ParseException e) {
- e.printStackTrace();
- }
- } else {
- mUrl = url;
- }
- }
- }
-
- /**
- * Guesses MIME type if one was not specified. Defaults to 'text/html'. In
- * addition, tries to guess the MIME type based on the extension.
- *
- */
- private void guessMimeType() {
- // Data urls must have a valid mime type or a blank string for the mime
- // type (implying text/plain).
- if (URLUtil.isDataUrl(mUrl) && mMimeType.length() != 0) {
- cancel();
- final String text = mContext.getString(R.string.httpErrorBadUrl);
- handleError(EventHandler.ERROR_BAD_URL, text);
- } else {
- // Note: This is ok because this is used only for the main content
- // of frames. If no content-type was specified, it is fine to
- // default to text/html.
- mMimeType = "text/html";
- String newMimeType = guessMimeTypeFromExtension(mUrl);
- if (newMimeType != null) {
- mMimeType = newMimeType;
- }
- }
- }
-
- /**
- * guess MIME type based on the file extension.
- */
- private String guessMimeTypeFromExtension(String url) {
- // PENDING: need to normalize url
- if (DebugFlags.LOAD_LISTENER) {
- Log.v(LOGTAG, "guessMimeTypeFromExtension: url = " + url);
- }
-
- return MimeTypeMap.getSingleton().getMimeTypeFromExtension(
- MimeTypeMap.getFileExtensionFromUrl(url));
- }
-
- /**
- * Either send a message to ourselves or queue the message if this is a
- * synchronous load.
- */
- private void sendMessageInternal(Message msg) {
- if (mSynchronous) {
- mMessageQueue.add(msg);
- } else {
- sendMessage(msg);
- }
- }
-
- /**
- * Cycle through our messages for synchronous loads.
- */
- /* package */ void loadSynchronousMessages() {
- if (DebugFlags.LOAD_LISTENER && !mSynchronous) {
- throw new AssertionError();
- }
- // Note: this can be called twice if it is a synchronous network load,
- // and there is a cache, but it needs to go to network to validate. If
- // validation succeed, the CacheLoader is used so this is first called
- // from http thread. Then it is called again from WebViewCore thread
- // after the load is completed. So make sure the queue is cleared but
- // don't set it to null.
- while (!mMessageQueue.isEmpty()) {
- handleMessage(mMessageQueue.remove(0));
- }
- }
-
- //=========================================================================
- // native functions
- //=========================================================================
-
- /**
- * Create a new native response object.
- * @param url The url of the resource.
- * @param statusCode The HTTP status code.
- * @param statusText The HTTP status text.
- * @param mimeType HTTP content-type.
- * @param expectedLength An estimate of the content length or the length
- * given by the server.
- * @param encoding HTTP encoding.
- * @return The native response pointer.
- */
- private native int nativeCreateResponse(String url, int statusCode,
- String statusText, String mimeType, long expectedLength,
- String encoding);
-
- /**
- * Add a response header to the native object.
- * @param nativeResponse The native pointer.
- * @param key String key.
- * @param val String value.
- */
- private native void nativeSetResponseHeader(int nativeResponse, String key,
- String val);
-
- /**
- * Dispatch the response.
- * @param nativeResponse The native pointer.
- */
- private native void nativeReceivedResponse(int nativeResponse);
-
- /**
- * Add data to the loader.
- * @param data Byte array of data.
- * @param length Number of objects in data.
- */
- private native void nativeAddData(byte[] data, int length);
-
- /**
- * Tell the loader it has finished.
- */
- private native void nativeFinished();
-
- /**
- * tell the loader to redirect
- * @param baseUrl The base url.
- * @param redirectTo The url to redirect to.
- * @param nativeResponse The native pointer.
- * @return The new url that the resource redirected to.
- */
- private native String nativeRedirectedToUrl(String baseUrl,
- String redirectTo, int nativeResponse);
-
- /**
- * Tell the loader there is error
- * @param id
- * @param desc
- * @param failingUrl The url that failed.
- */
- private native void nativeError(int id, String desc, String failingUrl);
-
-}
diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java
deleted file mode 100644
index ee9b9492ebeb..000000000000
--- a/core/java/android/webkit/Network.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.http.*;
-import android.os.*;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.Map;
-
-import junit.framework.Assert;
-
-class Network {
-
- private static final String LOGTAG = "network";
-
- /**
- * Static instance of a Network object.
- */
- private static Network sNetwork;
-
- /**
- * Flag to store the state of platform notifications, for the case
- * when the Network object has not been constructed yet
- */
- private static boolean sPlatformNotifications;
-
- /**
- * Reference count for platform notifications as the network class is a
- * static and can exist over multiple activities, thus over multiple
- * onPause/onResume pairs.
- */
- private static int sPlatformNotificationEnableRefCount;
-
- /**
- * Proxy username if known (used for pre-emptive proxy authentication).
- */
- private String mProxyUsername;
-
- /**
- * Proxy password if known (used for pre-emptive proxy authentication).
- */
- private String mProxyPassword;
-
- /**
- * Network request queue (requests are added from the browser thread).
- */
- private RequestQueue mRequestQueue;
-
- /**
- * SSL error handler: takes care of synchronization of multiple async
- * loaders with SSL-related problems.
- */
- private SslErrorHandlerImpl mSslErrorHandler;
-
- /**
- * HTTP authentication handler: takes care of synchronization of HTTP
- * authentication requests.
- */
- private HttpAuthHandlerImpl mHttpAuthHandler;
-
- private Context mContext;
-
- /**
- * True if the currently used network connection is a roaming phone
- * connection.
- */
- private boolean mRoaming;
-
- /**
- * Tracks if we are roaming.
- */
- private RoamingMonitor mRoamingMonitor;
-
- /**
- * @return The singleton instance of the network.
- */
- public static synchronized Network getInstance(Context context) {
- if (sNetwork == null) {
- // Note Context of the Application is used here, rather than
- // the what is passed in (usually a Context derived from an
- // Activity) so the intent receivers belong to the application
- // rather than an activity - this fixes the issue where
- // Activities are created and destroyed during the lifetime of
- // an Application
- sNetwork = new Network(context.getApplicationContext());
- if (sPlatformNotifications) {
- // Adjust the ref count before calling enable as it is already
- // taken into account when the static function was called
- // directly
- --sPlatformNotificationEnableRefCount;
- enablePlatformNotifications();
- }
- }
- return sNetwork;
- }
-
-
- /**
- * Enables data state and proxy tracking
- */
- public static void enablePlatformNotifications() {
- if (++sPlatformNotificationEnableRefCount == 1) {
- if (sNetwork != null) {
- sNetwork.mRequestQueue.enablePlatformNotifications();
- sNetwork.monitorRoaming();
- } else {
- sPlatformNotifications = true;
- }
- }
- }
-
- /**
- * If platform notifications are enabled, this should be called
- * from onPause() or onStop()
- */
- public static void disablePlatformNotifications() {
- if (--sPlatformNotificationEnableRefCount == 0) {
- if (sNetwork != null) {
- sNetwork.mRequestQueue.disablePlatformNotifications();
- sNetwork.stopMonitoringRoaming();
- } else {
- sPlatformNotifications = false;
- }
- }
- }
-
- /**
- * Creates a new Network object.
- * XXX: Must be created in the same thread as WebCore!!!!!
- */
- private Network(Context context) {
- if (DebugFlags.NETWORK) {
- Assert.assertTrue(Thread.currentThread().
- getName().equals(WebViewCore.THREAD_NAME));
- }
- mContext = context;
- mSslErrorHandler = new SslErrorHandlerImpl();
- mHttpAuthHandler = new HttpAuthHandlerImpl(this);
-
- mRequestQueue = new RequestQueue(context);
- }
-
- private class RoamingMonitor extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()))
- return;
-
- final ConnectivityManager connManager = (ConnectivityManager) context
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- final NetworkInfo info = connManager.getActiveNetworkInfo();
- if (info != null)
- mRoaming = info.isRoaming();
- };
- };
-
- private void monitorRoaming() {
- mRoamingMonitor = new RoamingMonitor();
- IntentFilter filter = new IntentFilter();
- filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- mContext.registerReceiver(sNetwork.mRoamingMonitor, filter);
- }
-
- private void stopMonitoringRoaming() {
- if (mRoamingMonitor != null) {
- mContext.unregisterReceiver(mRoamingMonitor);
- mRoamingMonitor = null;
- }
- }
-
- /**
- * Request a url from either the network or the file system.
- * @param url The url to load.
- * @param method The http method.
- * @param headers The http headers.
- * @param postData The body of the request.
- * @param loader A LoadListener for receiving the results of the request.
- * @return True if the request was successfully queued.
- */
- public boolean requestURL(String method,
- Map<String, String> headers,
- byte [] postData,
- LoadListener loader) {
-
- String url = loader.url();
-
- // Not a valid url, return false because we won't service the request!
- if (!URLUtil.isValidUrl(url)) {
- return false;
- }
-
- // asset, res, file system or data stream are handled in the other code
- // path. This only handles network request.
- if (URLUtil.isAssetUrl(url) || URLUtil.isResourceUrl(url)
- || URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) {
- return false;
- }
-
- // If this is a prefetch, abort it if we're roaming.
- if (mRoaming && headers.containsKey("X-Moz") && "prefetch".equals(headers.get("X-Moz"))) {
- return false;
- }
-
- /* FIXME: this is lame. Pass an InputStream in, rather than
- making this lame one here */
- InputStream bodyProvider = null;
- int bodyLength = 0;
- if (postData != null) {
- bodyLength = postData.length;
- bodyProvider = new ByteArrayInputStream(postData);
- }
-
- RequestQueue q = mRequestQueue;
- RequestHandle handle = null;
- if (loader.isSynchronous()) {
- handle = q.queueSynchronousRequest(url, loader.getWebAddress(),
- method, headers, loader, bodyProvider, bodyLength);
- loader.attachRequestHandle(handle);
- handle.processRequest();
- loader.loadSynchronousMessages();
- } else {
- handle = q.queueRequest(url, loader.getWebAddress(), method,
- headers, loader, bodyProvider, bodyLength);
- // FIXME: Although this is probably a rare condition, normal network
- // requests are processed in a separate thread. This means that it
- // is possible to process part of the request before setting the
- // request handle on the loader. We should probably refactor this to
- // ensure the handle is attached before processing begins.
- loader.attachRequestHandle(handle);
- }
-
- return true;
- }
-
- /**
- * @return True iff there is a valid proxy set.
- */
- public boolean isValidProxySet() {
- // The proxy host and port can be set within a different thread during
- // an Intent broadcast.
- synchronized (mRequestQueue) {
- return mRequestQueue.getProxyHost() != null;
- }
- }
-
- /**
- * Get the proxy hostname.
- * @return The proxy hostname obtained from the network queue and proxy
- * settings.
- */
- public String getProxyHostname() {
- return mRequestQueue.getProxyHost().getHostName();
- }
-
- /**
- * @return The proxy username or null if none.
- */
- public synchronized String getProxyUsername() {
- return mProxyUsername;
- }
-
- /**
- * Sets the proxy username.
- * @param proxyUsername Username to use when
- * connecting through the proxy.
- */
- public synchronized void setProxyUsername(String proxyUsername) {
- if (DebugFlags.NETWORK) {
- Assert.assertTrue(isValidProxySet());
- }
-
- mProxyUsername = proxyUsername;
- }
-
- /**
- * @return The proxy password or null if none.
- */
- public synchronized String getProxyPassword() {
- return mProxyPassword;
- }
-
- /**
- * Sets the proxy password.
- * @param proxyPassword Password to use when
- * connecting through the proxy.
- */
- public synchronized void setProxyPassword(String proxyPassword) {
- if (DebugFlags.NETWORK) {
- Assert.assertTrue(isValidProxySet());
- }
-
- mProxyPassword = proxyPassword;
- }
-
- /**
- * Saves the state of network handlers (user SSL and HTTP-authentication
- * preferences).
- * @param outState The out-state to save (write) to.
- * @return True iff succeeds.
- */
- public boolean saveState(Bundle outState) {
- if (DebugFlags.NETWORK) {
- Log.v(LOGTAG, "Network.saveState()");
- }
-
- return mSslErrorHandler.saveState(outState);
- }
-
- /**
- * Restores the state of network handlers (user SSL and HTTP-authentication
- * preferences).
- * @param inState The in-state to load (read) from.
- * @return True iff succeeds.
- */
- public boolean restoreState(Bundle inState) {
- if (DebugFlags.NETWORK) {
- Log.v(LOGTAG, "Network.restoreState()");
- }
-
- return mSslErrorHandler.restoreState(inState);
- }
-
- /**
- * Clears user SSL-error preference table.
- */
- public void clearUserSslPrefTable() {
- mSslErrorHandler.clear();
- }
-
- /**
- * Handles SSL error(s) on the way up to the user: the user must decide
- * whether errors should be ignored or not.
- * @param loader The loader that resulted in SSL errors.
- */
- public void handleSslErrorRequest(LoadListener loader) {
- if (DebugFlags.NETWORK) Assert.assertNotNull(loader);
- if (loader != null) {
- mSslErrorHandler.handleSslErrorRequest(loader);
- }
- }
-
- /* package */ boolean checkSslPrefTable(LoadListener loader,
- SslError error) {
- if (loader != null && error != null) {
- return mSslErrorHandler.checkSslPrefTable(loader, error);
- }
- return false;
- }
-
- /**
- * Handles authentication requests on their way up to the user (the user
- * must provide credentials).
- * @param loader The loader that resulted in an HTTP
- * authentication request.
- */
- public void handleAuthRequest(LoadListener loader) {
- if (DebugFlags.NETWORK) Assert.assertNotNull(loader);
- if (loader != null) {
- mHttpAuthHandler.handleAuthRequest(loader);
- }
- }
-
- // Performance probe
- public void startTiming() {
- mRequestQueue.startTiming();
- }
-
- public void stopTiming() {
- mRequestQueue.stopTiming();
- }
-}
diff --git a/core/java/android/webkit/SelectActionModeCallback.java b/core/java/android/webkit/SelectActionModeCallback.java
index cdf20f649c4a..2a770f5d986c 100644
--- a/core/java/android/webkit/SelectActionModeCallback.java
+++ b/core/java/android/webkit/SelectActionModeCallback.java
@@ -53,10 +53,8 @@ class SelectActionModeCallback implements ActionMode.Callback {
mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy, menu);
final Context context = mWebView.getContext();
- boolean allowText = context.getResources().getBoolean(
- com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
- mode.setTitle(allowText ?
- context.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
+ mode.setTitle(context.getString(com.android.internal.R.string.textSelectionCABTitle));
+ mode.setTitleOptionalHint(true);
// If the action mode UI we're running in isn't capable of taking window focus
// the user won't be able to type into the find on page UI. Disable this functionality.
diff --git a/core/java/android/webkit/SslErrorHandlerImpl.java b/core/java/android/webkit/SslErrorHandlerImpl.java
deleted file mode 100644
index b2e4b131ffc6..000000000000
--- a/core/java/android/webkit/SslErrorHandlerImpl.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * 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.
- */
-
-package android.webkit;
-
-import android.net.http.SslError;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-/**
- * SslErrorHandler's implementation for Android Java HTTP stack.
- * This class is not needed if the Chromium HTTP stack is used.
- */
-class SslErrorHandlerImpl extends SslErrorHandler {
- /* One problem here is that there may potentially be multiple SSL errors
- * coming from multiple loaders. Therefore, we keep a queue of loaders
- * that have SSL-related problems and process errors one by one in the
- * order they were received.
- */
-
- private static final String LOGTAG = "network";
-
- /**
- * Queue of loaders that experience SSL-related problems.
- */
- private LinkedList<LoadListener> mLoaderQueue;
-
- /**
- * SSL error preference table.
- */
- private Bundle mSslPrefTable;
-
- // These are only used in the client facing SslErrorHandler.
- private final SslErrorHandler mOriginHandler;
- private final LoadListener mLoadListener;
-
- // Message id for handling the response from the client.
- private static final int HANDLE_RESPONSE = 100;
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case HANDLE_RESPONSE:
- LoadListener loader = (LoadListener) msg.obj;
- synchronized (SslErrorHandlerImpl.this) {
- handleSslErrorResponse(loader, loader.sslError(),
- msg.arg1 == 1);
- mLoaderQueue.remove(loader);
- fastProcessQueuedSslErrors();
- }
- break;
- }
- }
-
- /**
- * Creates a new error handler with an empty loader queue.
- */
- /* package */ SslErrorHandlerImpl() {
- mLoaderQueue = new LinkedList<LoadListener>();
- mSslPrefTable = new Bundle();
-
- // These are used by client facing SslErrorHandlers.
- mOriginHandler = null;
- mLoadListener = null;
- }
-
- /**
- * Create a new error handler that will be passed to the client.
- */
- private SslErrorHandlerImpl(SslErrorHandler origin, LoadListener listener) {
- mOriginHandler = origin;
- mLoadListener = listener;
- }
-
- /**
- * Saves this handler's state into a map.
- * @return True iff succeeds.
- */
- /* package */ synchronized boolean saveState(Bundle outState) {
- boolean success = (outState != null);
- if (success) {
- // TODO?
- outState.putBundle("ssl-error-handler", mSslPrefTable);
- }
-
- return success;
- }
-
- /**
- * Restores this handler's state from a map.
- * @return True iff succeeds.
- */
- /* package */ synchronized boolean restoreState(Bundle inState) {
- boolean success = (inState != null);
- if (success) {
- success = inState.containsKey("ssl-error-handler");
- if (success) {
- mSslPrefTable = inState.getBundle("ssl-error-handler");
- }
- }
-
- return success;
- }
-
- /**
- * Clears SSL error preference table.
- */
- /* package */ synchronized void clear() {
- mSslPrefTable.clear();
- }
-
- /**
- * Handles requests from the network stack about whether to proceed with a
- * load given an SSL error(s). We may ask the client what to do, or use a
- * cached response.
- */
- /* package */ synchronized void handleSslErrorRequest(LoadListener loader) {
- if (DebugFlags.SSL_ERROR_HANDLER) {
- Log.v(LOGTAG, "SslErrorHandler.handleSslErrorRequest(): " +
- "url=" + loader.url());
- }
-
- if (!loader.cancelled()) {
- mLoaderQueue.offer(loader);
- if (loader == mLoaderQueue.peek()) {
- fastProcessQueuedSslErrors();
- }
- }
- }
-
- /**
- * Check the preference table to see if we already have a 'proceed' decision
- * from the client for this host and for an error of equal or greater
- * severity than the supplied error. If so, instruct the loader to proceed
- * and return true. Otherwise return false.
- */
- /* package */ synchronized boolean checkSslPrefTable(LoadListener loader,
- SslError error) {
- final String host = loader.host();
- final int primary = error.getPrimaryError();
-
- if (DebugFlags.SSL_ERROR_HANDLER) {
- assert host != null;
- assert primary != -1;
- }
-
- if (mSslPrefTable.containsKey(host) && primary <= mSslPrefTable.getInt(host)) {
- if (!loader.cancelled()) {
- loader.handleSslErrorResponse(true);
- }
- return true;
- }
- return false;
- }
-
- /**
- * Processes queued SSL-error confirmation requests in
- * a tight loop while there is no need to ask the client.
- */
- /* package */void fastProcessQueuedSslErrors() {
- while (processNextLoader());
- }
-
- /**
- * Processes the next loader in the queue.
- * @return True iff should proceed to processing the
- * following loader in the queue
- */
- private synchronized boolean processNextLoader() {
- LoadListener loader = mLoaderQueue.peek();
- if (loader != null) {
- // if this loader has been cancelled
- if (loader.cancelled()) {
- // go to the following loader in the queue. Make sure this
- // loader has been removed from the queue.
- mLoaderQueue.remove(loader);
- return true;
- }
-
- SslError error = loader.sslError();
-
- if (DebugFlags.SSL_ERROR_HANDLER) {
- assert error != null;
- }
-
- // checkSslPrefTable() will instruct the loader to proceed if we
- // have a cached 'proceed' decision. It does not remove the loader
- // from the queue.
- if (checkSslPrefTable(loader, error)) {
- mLoaderQueue.remove(loader);
- return true;
- }
-
- // If we can not proceed based on a cached decision, ask the client.
- CallbackProxy proxy = loader.getFrame().getCallbackProxy();
- proxy.onReceivedSslError(new SslErrorHandlerImpl(this, loader), error);
- }
-
- // the queue must be empty, stop
- return false;
- }
-
- /**
- * Proceed with this load.
- */
- public void proceed() {
- mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
- HANDLE_RESPONSE, 1, 0, mLoadListener));
- }
-
- /**
- * Cancel this load and all pending loads for the WebView that had the
- * error.
- */
- public void cancel() {
- mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
- HANDLE_RESPONSE, 0, 0, mLoadListener));
- }
-
- /**
- * Handles the response from the client about whether to proceed with this
- * load. We save the response to be re-used in the future.
- */
- /* package */ synchronized void handleSslErrorResponse(LoadListener loader,
- SslError error, boolean proceed) {
- if (DebugFlags.SSL_ERROR_HANDLER) {
- assert loader != null;
- assert error != null;
- }
-
- if (DebugFlags.SSL_ERROR_HANDLER) {
- Log.v(LOGTAG, "SslErrorHandler.handleSslErrorResponse():"
- + " proceed: " + proceed
- + " url:" + loader.url());
- }
-
- if (!loader.cancelled()) {
- if (proceed) {
- // Update the SSL error preference table
- int primary = error.getPrimaryError();
- String host = loader.host();
-
- if (DebugFlags.SSL_ERROR_HANDLER) {
- assert host != null;
- assert primary != -1;
- }
- boolean hasKey = mSslPrefTable.containsKey(host);
- if (!hasKey || primary > mSslPrefTable.getInt(host)) {
- mSslPrefTable.putInt(host, primary);
- }
- }
- loader.handleSslErrorResponse(proceed);
- }
- }
-}
diff --git a/core/java/android/webkit/StreamLoader.java b/core/java/android/webkit/StreamLoader.java
deleted file mode 100644
index 7bcd50dd4677..000000000000
--- a/core/java/android/webkit/StreamLoader.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.content.Context;
-import android.net.http.EventHandler;
-import android.net.http.Headers;
-import android.os.Handler;
-import android.os.Message;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This abstract class is used for all content loaders that rely on streaming
- * content into the rendering engine loading framework.
- *
- * The class implements a state machine to load the content into the frame in
- * a similar manor to the way content arrives from the network. The class uses
- * messages to move from one state to the next, which enables async. loading of
- * the streamed content.
- *
- * Classes that inherit from this class must implement two methods, the first
- * method is used to setup the InputStream and notify the loading framework if
- * it can load it's content. The other method allows the derived class to add
- * additional HTTP headers to the response.
- *
- * By default, content loaded with a StreamLoader is marked with a HTTP header
- * that indicates the content should not be cached.
- *
- */
-abstract class StreamLoader implements Handler.Callback {
-
- private static final int MSG_STATUS = 100; // Send status to loader
- private static final int MSG_HEADERS = 101; // Send headers to loader
- private static final int MSG_DATA = 102; // Send data to loader
- private static final int MSG_END = 103; // Send endData to loader
-
- protected final Context mContext;
- protected final LoadListener mLoadListener; // loader class
- protected InputStream mDataStream; // stream to read data from
- protected long mContentLength; // content length of data
- private byte [] mData; // buffer to pass data to loader with.
-
- // Handler which will be initialized in the thread where load() is called.
- private Handler mHandler;
-
- /**
- * Constructor. Although this class calls the LoadListener, it only calls
- * the EventHandler Interface methods. LoadListener concrete class is used
- * to avoid the penality of calling an interface.
- *
- * @param loadlistener The LoadListener to call with the data.
- */
- StreamLoader(LoadListener loadlistener) {
- mLoadListener = loadlistener;
- mContext = loadlistener.getContext();
- }
-
- /**
- * This method is called when the derived class should setup mDataStream,
- * and call mLoadListener.status() to indicate that the load can occur. If it
- * fails to setup, it should still call status() with the error code.
- *
- * @return true if stream was successfully setup
- */
- protected abstract boolean setupStreamAndSendStatus();
-
- /**
- * This method is called when the headers are about to be sent to the
- * load framework. The derived class has the opportunity to add addition
- * headers.
- *
- * @param headers Map of HTTP headers that will be sent to the loader.
- */
- abstract protected void buildHeaders(Headers headers);
-
- /**
- * Calling this method starts the load of the content for this StreamLoader.
- * This method simply creates a Handler in the current thread and posts a
- * message to send the status and returns immediately.
- */
- final void load() {
- synchronized (this) {
- if (mHandler == null) {
- mHandler = new Handler(this);
- }
- }
-
- if (!mLoadListener.isSynchronous()) {
- mHandler.sendEmptyMessage(MSG_STATUS);
- } else {
- // Load the stream synchronously.
- if (setupStreamAndSendStatus()) {
- // We were able to open the stream, create the array
- // to pass data to the loader
- mData = new byte[8192];
- sendHeaders();
- while (!sendData() && !mLoadListener.cancelled());
- closeStreamAndSendEndData();
- mLoadListener.loadSynchronousMessages();
- }
- }
- }
-
- public boolean handleMessage(Message msg) {
- if (mLoadListener.isSynchronous()) {
- throw new AssertionError();
- }
- if (mLoadListener.cancelled()) {
- closeStreamAndSendEndData();
- return true;
- }
- switch(msg.what) {
- case MSG_STATUS:
- if (setupStreamAndSendStatus()) {
- // We were able to open the stream, create the array
- // to pass data to the loader
- mData = new byte[8192];
- mHandler.sendEmptyMessage(MSG_HEADERS);
- }
- break;
- case MSG_HEADERS:
- sendHeaders();
- mHandler.sendEmptyMessage(MSG_DATA);
- break;
- case MSG_DATA:
- if (sendData()) {
- mHandler.sendEmptyMessage(MSG_END);
- } else {
- mHandler.sendEmptyMessage(MSG_DATA);
- }
- break;
- case MSG_END:
- closeStreamAndSendEndData();
- break;
- default:
- return false;
- }
- return true;
- }
-
- /**
- * Construct the headers and pass them to the EventHandler.
- */
- private void sendHeaders() {
- Headers headers = new Headers();
- if (mContentLength > 0) {
- headers.setContentLength(mContentLength);
- }
- buildHeaders(headers);
- mLoadListener.headers(headers);
- }
-
- /**
- * Read data from the stream and pass it to the EventHandler.
- * If an error occurs reading the stream, then an error is sent to the
- * EventHandler, and moves onto the next state - end of data.
- * @return True if all the data has been read. False if sendData should be
- * called again.
- */
- private boolean sendData() {
- if (mDataStream != null) {
- try {
- int amount = mDataStream.read(mData);
- if (amount > 0) {
- mLoadListener.data(mData, amount);
- return false;
- }
- } catch (IOException ex) {
- mLoadListener.error(EventHandler.FILE_ERROR, ex.getMessage());
- }
- }
- return true;
- }
-
- /**
- * Close the stream and inform the EventHandler that load is complete.
- */
- private void closeStreamAndSendEndData() {
- if (mDataStream != null) {
- try {
- mDataStream.close();
- } catch (IOException ex) {
- // ignore.
- }
- }
- mLoadListener.endData();
- }
-}
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
index 24e0d11b0562..650310e219a4 100644
--- a/core/java/android/webkit/WebResourceResponse.java
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -26,24 +26,6 @@ import java.io.InputStream;
* response when the WebView requests a particular resource.
*/
public class WebResourceResponse {
-
- private class Loader extends StreamLoader {
- Loader(LoadListener loadListener) {
- super(loadListener);
- mDataStream = mInputStream;
- }
- @Override
- protected boolean setupStreamAndSendStatus() {
- mLoadListener.status(1, 1, mDataStream != null ? 200 : 404, "");
- return true;
- }
- @Override
- protected void buildHeaders(Headers headers) {
- headers.setContentType(mMimeType);
- headers.setContentEncoding(mEncoding);
- }
- }
-
// Accessed by jni, do not rename without modifying the jni code.
private String mMimeType;
private String mEncoding;
@@ -114,8 +96,4 @@ public class WebResourceResponse {
public InputStream getData() {
return mInputStream;
}
-
- StreamLoader loader(LoadListener listener) {
- return new Loader(listener);
- }
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6dc3be540f0e..86185103c5d5 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -68,6 +68,7 @@ import android.text.InputType;
import android.text.Selection;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.view.Display;
@@ -111,6 +112,8 @@ import android.widget.CheckedTextView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.OverScroller;
+import android.widget.PopupWindow;
+import android.widget.TextView;
import android.widget.Toast;
import junit.framework.Assert;
@@ -382,21 +385,24 @@ public class WebView extends AbsoluteLayout
@Override
public boolean sendKeyEvent(KeyEvent event) {
- // Latin IME occasionally sends delete codes directly using
- // sendKeyEvents. WebViewInputConnection should treat this
- // as a deleteSurroundingText.
- if (!mIsKeySentByMe
- && event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
- Editable editable = getEditable();
- int selectionStart = Selection.getSelectionStart(editable);
- int selectionEnd = Selection.getSelectionEnd(editable);
- if (selectionEnd > 0 && (selectionStart == selectionEnd)) {
- int action = event.getAction();
- if (action == KeyEvent.ACTION_UP) {
+ // Some IMEs send key events directly using sendKeyEvents.
+ // WebViewInputConnection should treat these as text changes.
+ if (!mIsKeySentByMe) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
return deleteSurroundingText(1, 0);
- } else if (action == KeyEvent.ACTION_DOWN) {
- return true; // the delete will happen in ACTION_UP
+ } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
+ return deleteSurroundingText(0, 1);
+ } else if (event.getUnicodeChar() != 0){
+ String newComposingText =
+ Character.toString((char)event.getUnicodeChar());
+ return commitText(newComposingText, 1);
}
+ } else if (event.getAction() == KeyEvent.ACTION_DOWN &&
+ (event.getKeyCode() == KeyEvent.KEYCODE_DEL
+ || event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL
+ || event.getUnicodeChar() != 0)) {
+ return true; // only act on action_down
}
}
return super.sendKeyEvent(event);
@@ -419,6 +425,23 @@ public class WebView extends AbsoluteLayout
setSelection(selectionStart, selectionEnd);
}
+ public void replaceSelection(CharSequence text) {
+ Editable editable = getEditable();
+ int selectionStart = Selection.getSelectionStart(editable);
+ int selectionEnd = Selection.getSelectionEnd(editable);
+ setNewText(selectionStart, selectionEnd, text);
+ editable.replace(selectionStart, selectionEnd, text);
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ // Since the text has changed, do not allow the IME to replace the
+ // existing text as though it were a completion.
+ imm.restartInput(WebView.this);
+ }
+ // Move caret to the end of the new text
+ int newCaret = selectionStart + text.length();
+ setSelection(newCaret, newCaret);
+ }
+
@Override
public boolean setComposingText(CharSequence text, int newCursorPosition) {
Editable editable = getEditable();
@@ -456,6 +479,38 @@ public class WebView extends AbsoluteLayout
return super.deleteSurroundingText(leftLength, rightLength);
}
+ @Override
+ public boolean performEditorAction(int editorAction) {
+
+ boolean handled = true;
+ switch (editorAction) {
+ case EditorInfo.IME_ACTION_NEXT:
+ WebView.this.requestFocus(FOCUS_FORWARD);
+ break;
+ case EditorInfo.IME_ACTION_PREVIOUS:
+ WebView.this.requestFocus(FOCUS_BACKWARD);
+ break;
+ case EditorInfo.IME_ACTION_DONE:
+ WebView.this.hideSoftKeyboard();
+ break;
+ case EditorInfo.IME_ACTION_GO:
+ case EditorInfo.IME_ACTION_SEARCH:
+ WebView.this.hideSoftKeyboard();
+ String text = getEditable().toString();
+ passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_ENTER));
+ passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_ENTER));
+ break;
+
+ default:
+ handled = super.performEditorAction(editorAction);
+ break;
+ }
+
+ return handled;
+ }
+
public void initEditorInfo(WebViewCore.TextFieldInitData initData) {
int type = initData.mType;
int inputType = InputType.TYPE_CLASS_TEXT
@@ -555,8 +610,8 @@ public class WebView extends AbsoluteLayout
if (isCharacterAdd) {
sendCharacter(text.charAt(textLength - 1));
} else if (isCharacterDelete) {
- sendDeleteKey();
- } else if (textLength != originalLength ||
+ sendKey(KeyEvent.KEYCODE_DEL);
+ } else if ((textLength != originalLength) ||
!TextUtils.regionMatches(text, 0, original, 0,
textLength)) {
// Send a message so that key strokes and text replacement
@@ -583,25 +638,102 @@ public class WebView extends AbsoluteLayout
for (KeyEvent event : events) {
sendKeyEvent(event);
}
+ } else {
+ Message msg = mPrivateHandler.obtainMessage(KEY_PRESS, (int) c, 0);
+ mPrivateHandler.sendMessage(msg);
}
}
/**
- * Send the delete character as a key down and up event.
+ * Send a key event for a specific key code, not a standard
+ * unicode character.
+ * @param keyCode The key code to send.
*/
- private void sendDeleteKey() {
+ private void sendKey(int keyCode) {
long eventTime = SystemClock.uptimeMillis();
sendKeyEvent(new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0, 0,
+ KeyEvent.ACTION_DOWN, keyCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD));
sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
- KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL, 0, 0,
+ KeyEvent.ACTION_UP, keyCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD));
}
}
+ private class PastePopupWindow extends PopupWindow implements OnClickListener {
+ private ViewGroup mContentView;
+ private TextView mPasteTextView;
+
+ public PastePopupWindow() {
+ super(WebView.this.mContext, null,
+ com.android.internal.R.attr.textSelectHandleWindowStyle);
+ setClippingEnabled(true);
+ LinearLayout linearLayout = new LinearLayout(WebView.this.getContext());
+ linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+ mContentView = linearLayout;
+ mContentView.setBackgroundResource(
+ com.android.internal.R.drawable.text_edit_paste_window);
+
+ LayoutInflater inflater = (LayoutInflater)WebView.this.mContext.
+ getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ ViewGroup.LayoutParams wrapContent = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mPasteTextView = (TextView) inflater.inflate(
+ com.android.internal.R.layout.text_edit_action_popup_text, null);
+ mPasteTextView.setLayoutParams(wrapContent);
+ mContentView.addView(mPasteTextView);
+ mPasteTextView.setText(com.android.internal.R.string.paste);
+ mPasteTextView.setOnClickListener(this);
+ this.setContentView(mContentView);
+ }
+
+ public void show(Rect cursorRect, int windowLeft, int windowTop) {
+ measureContent();
+
+ int width = mContentView.getMeasuredWidth();
+ int height = mContentView.getMeasuredHeight();
+ int y = cursorRect.top - height;
+ if (y < windowTop) {
+ // There's not enough room vertically, move it below the
+ // handle.
+ // The selection handle is vertically offset by 1/4 of the
+ // line height.
+ y = cursorRect.bottom - (cursorRect.height() / 4) +
+ mSelectHandleCenter.getIntrinsicHeight();
+ }
+ int x = cursorRect.centerX() - (width / 2);
+ if (x < windowLeft) {
+ x = windowLeft;
+ }
+ if (!isShowing()) {
+ showAtLocation(WebView.this, Gravity.NO_GRAVITY, x, y);
+ }
+ update(x, y, width, height);
+ }
+
+ public void hide() {
+ dismiss();
+ }
+
+ @Override
+ public void onClick(View view) {
+ pasteFromClipboard();
+ selectionDone();
+ }
+
+ protected void measureContent() {
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ mContentView.measure(
+ View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
+ View.MeasureSpec.AT_MOST),
+ View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
+ View.MeasureSpec.AT_MOST));
+ }
+ }
// The listener to capture global layout change event.
private InnerGlobalLayoutListener mGlobalLayoutListener = null;
@@ -629,6 +761,7 @@ public class WebView extends AbsoluteLayout
private boolean mGLViewportEmpty = false;
WebViewInputConnection mInputConnection = null;
private int mFieldPointer;
+ private PastePopupWindow mPasteWindow;
/**
* Transportation object for returning WebView across thread boundaries.
@@ -908,14 +1041,22 @@ public class WebView extends AbsoluteLayout
// know to handle Shift and arrows natively first
private boolean mAccessibilityScriptInjected;
+
+ /**
+ * How long the caret handle will last without being touched.
+ */
+ private static final long CARET_HANDLE_STAMINA_MS = 3000;
+
private Drawable mSelectHandleLeft;
private Drawable mSelectHandleRight;
+ private Drawable mSelectHandleCenter;
private Rect mSelectCursorBase = new Rect();
private int mSelectCursorBaseLayerId;
private Rect mSelectCursorExtent = new Rect();
private int mSelectCursorExtentLayerId;
private Rect mSelectDraggingCursor;
private Point mSelectDraggingOffset = new Point();
+ private boolean mIsCaretSelection;
static final int HANDLE_ID_START = 0;
static final int HANDLE_ID_END = 1;
static final int HANDLE_ID_BASE = 2;
@@ -1012,6 +1153,8 @@ public class WebView extends AbsoluteLayout
static final int COPY_TO_CLIPBOARD = 141;
static final int INIT_EDIT_FIELD = 142;
static final int REPLACE_TEXT = 143;
+ static final int CLEAR_CARET_HANDLE = 144;
+ static final int KEY_PRESS = 145;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
@@ -1418,7 +1561,7 @@ public class WebView extends AbsoluteLayout
IntentFilter filter = new IntentFilter();
filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
sTrustStorageListener = new TrustStorageListener();
- Intent current =
+ Intent current =
context.getApplicationContext().registerReceiver(sTrustStorageListener, filter);
if (current != null) {
handleCertTrustChanged();
@@ -2030,7 +2173,6 @@ public class WebView extends AbsoluteLayout
public static void enablePlatformNotifications() {
checkThread();
synchronized (WebView.class) {
- Network.enablePlatformNotifications();
sNotificationsEnabled = true;
Context context = JniUtil.getContext();
if (context != null)
@@ -2048,7 +2190,6 @@ public class WebView extends AbsoluteLayout
public static void disablePlatformNotifications() {
checkThread();
synchronized (WebView.class) {
- Network.disablePlatformNotifications();
sNotificationsEnabled = false;
Context context = JniUtil.getContext();
if (context != null)
@@ -5108,31 +5249,45 @@ public class WebView extends AbsoluteLayout
}
private void drawTextSelectionHandles(Canvas canvas) {
- if (mSelectHandleLeft == null) {
- mSelectHandleLeft = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_left);
- }
int[] handles = new int[4];
getSelectionHandles(handles);
int start_x = contentToViewDimension(handles[0]);
int start_y = contentToViewDimension(handles[1]);
int end_x = contentToViewDimension(handles[2]);
int end_y = contentToViewDimension(handles[3]);
- // Magic formula copied from TextView
- start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
- mSelectHandleLeft.setBounds(start_x, start_y,
- start_x + mSelectHandleLeft.getIntrinsicWidth(),
- start_y + mSelectHandleLeft.getIntrinsicHeight());
- if (mSelectHandleRight == null) {
- mSelectHandleRight = mContext.getResources().getDrawable(
- com.android.internal.R.drawable.text_select_handle_right);
+
+ if (mIsCaretSelection) {
+ if (mSelectHandleCenter == null) {
+ mSelectHandleCenter = mContext.getResources().getDrawable(
+ com.android.internal.R.drawable.text_select_handle_middle);
+ }
+ // Caret handle is centered
+ start_x -= (mSelectHandleCenter.getIntrinsicWidth() / 2);
+ mSelectHandleCenter.setBounds(start_x, start_y,
+ start_x + mSelectHandleCenter.getIntrinsicWidth(),
+ start_y + mSelectHandleCenter.getIntrinsicHeight());
+ mSelectHandleCenter.draw(canvas);
+ } else {
+ if (mSelectHandleLeft == null) {
+ mSelectHandleLeft = mContext.getResources().getDrawable(
+ com.android.internal.R.drawable.text_select_handle_left);
+ }
+ // Magic formula copied from TextView
+ start_x -= (mSelectHandleLeft.getIntrinsicWidth() * 3) / 4;
+ mSelectHandleLeft.setBounds(start_x, start_y,
+ start_x + mSelectHandleLeft.getIntrinsicWidth(),
+ start_y + mSelectHandleLeft.getIntrinsicHeight());
+ if (mSelectHandleRight == null) {
+ mSelectHandleRight = mContext.getResources().getDrawable(
+ com.android.internal.R.drawable.text_select_handle_right);
+ }
+ end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
+ mSelectHandleRight.setBounds(end_x, end_y,
+ end_x + mSelectHandleRight.getIntrinsicWidth(),
+ end_y + mSelectHandleRight.getIntrinsicHeight());
+ mSelectHandleLeft.draw(canvas);
+ mSelectHandleRight.draw(canvas);
}
- end_x -= mSelectHandleRight.getIntrinsicWidth() / 4;
- mSelectHandleRight.setBounds(end_x, end_y,
- end_x + mSelectHandleRight.getIntrinsicWidth(),
- end_y + mSelectHandleRight.getIntrinsicHeight());
- mSelectHandleLeft.draw(canvas);
- mSelectHandleRight.draw(canvas);
}
/**
@@ -5554,6 +5709,9 @@ public class WebView extends AbsoluteLayout
+ "keyCode=" + keyCode
+ ", " + event + ", unicode=" + event.getUnicodeChar());
}
+ if (mIsCaretSelection) {
+ selectionDone();
+ }
if (mBlockWebkitViewMessages) {
return false;
}
@@ -5866,6 +6024,7 @@ public class WebView extends AbsoluteLayout
private boolean startSelectActionMode() {
mSelectCallback = new SelectActionModeCallback();
+ mSelectCallback.setTextSelected(!mIsCaretSelection);
mSelectCallback.setWebView(this);
if (startActionMode(mSelectCallback) == null) {
// There is no ActionMode, so do not allow the user to modify a
@@ -5877,6 +6036,27 @@ public class WebView extends AbsoluteLayout
return true;
}
+ private void showPasteWindow() {
+ ClipboardManager cm = (ClipboardManager)(mContext
+ .getSystemService(Context.CLIPBOARD_SERVICE));
+ if (cm.hasPrimaryClip()) {
+ Rect cursorRect = contentToViewRect(mSelectCursorBase);
+ int[] location = new int[2];
+ getLocationInWindow(location);
+ cursorRect.offset(location[0] - mScrollX, location[1] - mScrollY);
+ if (mPasteWindow == null) {
+ mPasteWindow = new PastePopupWindow();
+ }
+ mPasteWindow.show(cursorRect, location[0], location[1]);
+ }
+ }
+
+ private void hidePasteButton() {
+ if (mPasteWindow != null) {
+ mPasteWindow.hide();
+ }
+ }
+
private void syncSelectionCursors() {
mSelectCursorBaseLayerId =
nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE, mSelectCursorBase);
@@ -5886,7 +6066,9 @@ public class WebView extends AbsoluteLayout
private boolean setupWebkitSelect() {
syncSelectionCursors();
- if (!startSelectActionMode()) {
+ if (mIsCaretSelection) {
+ showPasteWindow();
+ } else if (!startSelectActionMode()) {
selectionDone();
return false;
}
@@ -5897,6 +6079,9 @@ public class WebView extends AbsoluteLayout
private void updateWebkitSelection() {
int[] handles = null;
+ if (mIsCaretSelection) {
+ mSelectCursorExtent.set(mSelectCursorBase);
+ }
if (mSelectingText) {
handles = new int[4];
handles[0] = mSelectCursorBase.centerX();
@@ -5910,6 +6095,14 @@ public class WebView extends AbsoluteLayout
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles);
}
+ private void resetCaretTimer() {
+ mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
+ if (!mSelectionStarted) {
+ mPrivateHandler.sendEmptyMessageDelayed(CLEAR_CARET_HANDLE,
+ CARET_HANDLE_STAMINA_MS);
+ }
+ }
+
/**
* Use this method to put the WebView into text selection mode.
* Do not rely on this functionality; it will be deprecated in the future.
@@ -5934,12 +6127,18 @@ public class WebView extends AbsoluteLayout
*/
void selectionDone() {
if (mSelectingText) {
+ hidePasteButton();
mSelectingText = false;
// finish is idempotent, so this is fine even if selectionDone was
// called by mSelectCallback.onDestroyActionMode
- mSelectCallback.finish();
- mSelectCallback = null;
- updateWebkitSelection();
+ if (mSelectCallback != null) {
+ mSelectCallback.finish();
+ mSelectCallback = null;
+ }
+ if (!mIsCaretSelection) {
+ updateWebkitSelection();
+ }
+ mIsCaretSelection = false;
invalidate(); // redraw without selection
mAutoScrollX = 0;
mAutoScrollY = 0;
@@ -5998,12 +6197,8 @@ public class WebView extends AbsoluteLayout
if (clipData != null) {
ClipData.Item clipItem = clipData.getItemAt(0);
CharSequence pasteText = clipItem.getText();
- if (pasteText != null) {
- int[] handles = new int[4];
- getSelectionHandles(handles);
- mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
- mWebViewCore.sendMessage(EventHub.INSERT_TEXT,
- pasteText.toString());
+ if (mInputConnection != null) {
+ mInputConnection.replaceSelection(pasteText);
}
}
}
@@ -6553,18 +6748,27 @@ public class WebView extends AbsoluteLayout
(eventTime - mLastTouchUpTime), eventTime);
}
mSelectionStarted = false;
- if (mSelectingText && mSelectHandleLeft != null
- && mSelectHandleRight != null) {
+ if (mSelectingText) {
int shiftedY = y - getTitleHeight() + mScrollY;
int shiftedX = x + mScrollX;
- if (mSelectHandleLeft.getBounds()
+ if (mSelectHandleCenter != null && mSelectHandleCenter.getBounds()
.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
mSelectDraggingCursor = mSelectCursorBase;
- } else if (mSelectHandleRight.getBounds()
+ mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
+ hidePasteButton();
+ } else if (mSelectHandleLeft != null
+ && mSelectHandleLeft.getBounds()
+ .contains(shiftedX, shiftedY)) {
+ mSelectionStarted = true;
+ mSelectDraggingCursor = mSelectCursorBase;
+ } else if (mSelectHandleRight != null
+ && mSelectHandleRight.getBounds()
.contains(shiftedX, shiftedY)) {
mSelectionStarted = true;
mSelectDraggingCursor = mSelectCursorExtent;
+ } else if (mIsCaretSelection) {
+ selectionDone();
}
if (mSelectDraggingCursor != null) {
mSelectDraggingOffset.set(
@@ -7216,6 +7420,10 @@ public class WebView extends AbsoluteLayout
if (mSelectingText) {
mSelectionStarted = false;
syncSelectionCursors();
+ if (mIsCaretSelection) {
+ resetCaretTimer();
+ showPasteWindow();
+ }
invalidate();
}
}
@@ -7857,7 +8065,10 @@ public class WebView extends AbsoluteLayout
}
}, ViewConfiguration.getPressedStateDuration());
}
- if (sDisableNavcache) {
+ if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) {
+ playSoundEffect(SoundEffectConstants.CLICK);
+ overrideLoading(mFocusedNode.mIntentUrl);
+ } else if (sDisableNavcache) {
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
// use "0" as generation id to inform WebKit to use the same x/y as
// it used when processing GET_TOUCH_HIGHLIGHT_RECTS
@@ -9095,24 +9306,7 @@ public class WebView extends AbsoluteLayout
WebKitHitTest hit = (WebKitHitTest) msg.obj;
mFocusedNode = hit;
setTouchHighlightRects(hit);
- if (hit == null) {
- mInitialHitTestResult = null;
- } else {
- mInitialHitTestResult = new HitTestResult();
- if (hit.mLinkUrl != null) {
- mInitialHitTestResult.mType = HitTestResult.SRC_ANCHOR_TYPE;
- mInitialHitTestResult.mExtra = hit.mLinkUrl;
- if (hit.mImageUrl != null) {
- mInitialHitTestResult.mType = HitTestResult.SRC_IMAGE_ANCHOR_TYPE;
- mInitialHitTestResult.mExtra = hit.mImageUrl;
- }
- } else if (hit.mImageUrl != null) {
- mInitialHitTestResult.mType = HitTestResult.IMAGE_TYPE;
- mInitialHitTestResult.mExtra = hit.mImageUrl;
- } else if (hit.mEditable) {
- mInitialHitTestResult.mType = HitTestResult.EDIT_TEXT_TYPE;
- }
- }
+ setHitTestResult(hit);
break;
case SAVE_WEBARCHIVE_FINISHED:
@@ -9173,6 +9367,13 @@ public class WebView extends AbsoluteLayout
}
break;
}
+ case CLEAR_CARET_HANDLE:
+ selectionDone();
+ break;
+
+ case KEY_PRESS:
+ mWebViewCore.sendMessage(EventHub.KEY_PRESS, msg.arg1);
+ break;
default:
super.handleMessage(msg);
@@ -9181,6 +9382,53 @@ public class WebView extends AbsoluteLayout
}
}
+ private void setHitTestTypeFromUrl(String url) {
+ String substr = null;
+ if (url.startsWith(SCHEME_GEO)) {
+ mInitialHitTestResult.mType = HitTestResult.GEO_TYPE;
+ substr = url.substring(SCHEME_GEO.length());
+ } else if (url.startsWith(SCHEME_TEL)) {
+ mInitialHitTestResult.mType = HitTestResult.PHONE_TYPE;
+ substr = url.substring(SCHEME_TEL.length());
+ } else if (url.startsWith(SCHEME_MAILTO)) {
+ mInitialHitTestResult.mType = HitTestResult.EMAIL_TYPE;
+ substr = url.substring(SCHEME_MAILTO.length());
+ } else {
+ mInitialHitTestResult.mType = HitTestResult.SRC_ANCHOR_TYPE;
+ mInitialHitTestResult.mExtra = url;
+ return;
+ }
+ try {
+ mInitialHitTestResult.mExtra = URLDecoder.decode(substr, "UTF-8");
+ } catch (Throwable e) {
+ Log.w(LOGTAG, "Failed to decode URL! " + substr, e);
+ mInitialHitTestResult.mType = HitTestResult.UNKNOWN_TYPE;
+ }
+ }
+
+ private void setHitTestResult(WebKitHitTest hit) {
+ if (hit == null) {
+ mInitialHitTestResult = null;
+ return;
+ }
+ mInitialHitTestResult = new HitTestResult();
+ if (hit.mLinkUrl != null) {
+ setHitTestTypeFromUrl(hit.mLinkUrl);
+ if (hit.mImageUrl != null
+ && mInitialHitTestResult.mType == HitTestResult.SRC_ANCHOR_TYPE) {
+ mInitialHitTestResult.mType = HitTestResult.SRC_IMAGE_ANCHOR_TYPE;
+ mInitialHitTestResult.mExtra = hit.mImageUrl;
+ }
+ } else if (hit.mImageUrl != null) {
+ mInitialHitTestResult.mType = HitTestResult.IMAGE_TYPE;
+ mInitialHitTestResult.mExtra = hit.mImageUrl;
+ } else if (hit.mEditable) {
+ mInitialHitTestResult.mType = HitTestResult.EDIT_TEXT_TYPE;
+ } else if (hit.mIntentUrl != null) {
+ setHitTestTypeFromUrl(hit.mIntentUrl);
+ }
+ }
+
private boolean shouldDrawHighlightRect() {
if (mFocusedNode == null || mInitialHitTestResult == null) {
return false;
@@ -9188,7 +9436,7 @@ public class WebView extends AbsoluteLayout
if (mTouchHighlightRegion.isEmpty()) {
return false;
}
- if (mFocusedNode.mHasFocus) {
+ if (mFocusedNode.mHasFocus && !isInTouchMode()) {
return !mFocusedNode.mEditable;
}
if (mInitialHitTestResult.mType == HitTestResult.UNKNOWN_TYPE) {
@@ -9423,14 +9671,20 @@ public class WebView extends AbsoluteLayout
mInputConnection.setSelection(data.mStart, data.mEnd);
}
}
-
nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);
- if (data.mSelectTextPtr != 0) {
+
+ if (data.mSelectTextPtr != 0 &&
+ (data.mStart != data.mEnd ||
+ (mFieldPointer == nodePointer && mFieldPointer != 0))) {
+ mIsCaretSelection = (data.mStart == data.mEnd);
if (!mSelectingText) {
setupWebkitSelect();
} else if (!mSelectionStarted) {
syncSelectionCursors();
}
+ if (mIsCaretSelection) {
+ resetCaretTimer();
+ }
} else {
selectionDone();
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 84f0b9c845e5..e7da1a8c40e7 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -879,6 +879,7 @@ public final class WebViewCore {
static class WebKitHitTest {
String mLinkUrl;
+ String mIntentUrl;
String mAnchorText;
String mImageUrl;
String mAltDisplayString;
@@ -1172,8 +1173,11 @@ public final class WebViewCore {
static final int TRUST_STORAGE_UPDATED = 220;
// find-on-page controls
- static final int FIND_ALL = 220;
- static final int FIND_NEXT = 221;
+ static final int FIND_ALL = 221;
+ static final int FIND_NEXT = 222;
+
+ // key was pressed (down and up)
+ static final int KEY_PRESS = 223;
// Private handler for WebCore messages.
private Handler mHandler;
@@ -1354,6 +1358,10 @@ public final class WebViewCore {
key((KeyEvent) msg.obj, false);
break;
+ case KEY_PRESS:
+ keyPress(msg.arg1);
+ break;
+
case FAKE_CLICK:
nativeClick(mNativeClass, msg.arg1, msg.arg2, true);
break;
@@ -1402,21 +1410,12 @@ public final class WebViewCore {
Process.setThreadPriority(mTid,
Process.THREAD_PRIORITY_BACKGROUND);
pauseTimers();
- if (!JniUtil.useChromiumHttpStack()) {
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_PAUSE_CACHE_TRANSACTION);
- } else {
- nativeCloseIdleConnections(mNativeClass);
- }
+ nativeCloseIdleConnections(mNativeClass);
break;
case RESUME_TIMERS:
Process.setThreadPriority(mTid, mSavedPriority);
resumeTimers();
- if (!JniUtil.useChromiumHttpStack()) {
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_RESUME_CACHE_TRANSACTION);
- }
break;
case ON_PAUSE:
@@ -1490,14 +1489,10 @@ public final class WebViewCore {
}
case CLEAR_SSL_PREF_TABLE:
- if (JniUtil.useChromiumHttpStack()) {
- // FIXME: This will not work for connections currently in use, as
- // they cache the certificate responses. See http://b/5324235.
- SslCertLookupTable.getInstance().clear();
- nativeCloseIdleConnections(mNativeClass);
- } else {
- Network.getInstance(mContext).clearUserSslPrefTable();
- }
+ // FIXME: This will not work for connections currently in use, as
+ // they cache the certificate responses. See http://b/5324235.
+ SslCertLookupTable.getInstance().clear();
+ nativeCloseIdleConnections(mNativeClass);
break;
case TOUCH_UP:
@@ -2073,6 +2068,11 @@ public final class WebViewCore {
}
}
+ private void keyPress(int unicodeChar) {
+ nativeKey(mNativeClass, 0, unicodeChar, 0, false, false, false, true);
+ nativeKey(mNativeClass, 0, unicodeChar, 0, false, false, false, false);
+ }
+
// These values are used to avoid requesting a layout based on old values
private int mCurrentViewWidth = 0;
private int mCurrentViewHeight = 0;
@@ -2445,14 +2445,6 @@ public final class WebViewCore {
// called by JNI
private void sendNotifyProgressFinished() {
sendUpdateTextEntry();
- if (!JniUtil.useChromiumHttpStack()) {
- // as CacheManager can behave based on database transaction, we need to
- // call tick() to trigger endTransaction
- WebViewWorker.getHandler().removeMessages(
- WebViewWorker.MSG_CACHE_TRANSACTION_TICKER);
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_CACHE_TRANSACTION_TICKER);
- }
contentDraw();
}
@@ -2834,7 +2826,7 @@ public final class WebViewCore {
// called by JNI
private void initEditField(int pointer, String text, int inputType,
boolean isSpellCheckEnabled, boolean nextFieldIsText,
- String label, int start, int end) {
+ String label, int start, int end, int selectionPtr) {
if (mWebView == null) {
return;
}
@@ -2844,7 +2836,7 @@ public final class WebViewCore {
WebView.INIT_EDIT_FIELD, initData).sendToTarget();
Message.obtain(mWebView.mPrivateHandler,
WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
- 0, new TextSelectionData(start, end, 0))
+ 0, new TextSelectionData(start, end, selectionPtr))
.sendToTarget();
}
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 695c154acba0..757a619ffe6b 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -31,9 +31,6 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;
-import android.webkit.CookieManager.Cookie;
-import android.webkit.CacheManager.CacheResult;
-import android.webkit.JniUtil;
public class WebViewDatabase {
private static final String DATABASE_FILE = "webview.db";
@@ -55,39 +52,25 @@ public class WebViewDatabase {
// 10 -> 11 Drop cookies and cache now managed by the chromium stack,
// and update the form data table to use the new format
// implemented for b/5265606.
- private static final int CACHE_DATABASE_VERSION = 4;
- // 1 -> 2 Add expires String
- // 2 -> 3 Add content-disposition
- // 3 -> 4 Add crossdomain (For x-permitted-cross-domain-policies header)
private static WebViewDatabase mInstance = null;
private static SQLiteDatabase mDatabase = null;
- private static SQLiteDatabase mCacheDatabase = null;
// synchronize locks
- private final Object mCookieLock = new Object();
private final Object mPasswordLock = new Object();
private final Object mFormLock = new Object();
private final Object mHttpAuthLock = new Object();
- // TODO: The Chromium HTTP stack handles cookies independently.
- // We should consider removing the cookies table if and when we switch to
- // the Chromium HTTP stack for good.
private static final String mTableNames[] = {
- "cookies", "password", "formurl", "formdata", "httpauth"
+ "password", "formurl", "formdata", "httpauth"
};
// Table ids (they are index to mTableNames)
- private static final int TABLE_COOKIES_ID = 0;
-
- private static final int TABLE_PASSWORD_ID = 1;
-
- private static final int TABLE_FORMURL_ID = 2;
-
- private static final int TABLE_FORMDATA_ID = 3;
-
- private static final int TABLE_HTTPAUTH_ID = 4;
+ private static final int TABLE_PASSWORD_ID = 0;
+ private static final int TABLE_FORMURL_ID = 1;
+ private static final int TABLE_FORMDATA_ID = 2;
+ private static final int TABLE_HTTPAUTH_ID = 3;
// column id strings for "_id" which can be used by any table
private static final String ID_COL = "_id";
@@ -96,51 +79,9 @@ public class WebViewDatabase {
"_id"
};
- // column id strings for "cookies" table
- private static final String COOKIES_NAME_COL = "name";
-
- private static final String COOKIES_VALUE_COL = "value";
-
- private static final String COOKIES_DOMAIN_COL = "domain";
-
- private static final String COOKIES_PATH_COL = "path";
-
- private static final String COOKIES_EXPIRES_COL = "expires";
-
- private static final String COOKIES_SECURE_COL = "secure";
-
- // column id strings for "cache" table
- private static final String CACHE_URL_COL = "url";
-
- private static final String CACHE_FILE_PATH_COL = "filepath";
-
- private static final String CACHE_LAST_MODIFY_COL = "lastmodify";
-
- private static final String CACHE_ETAG_COL = "etag";
-
- private static final String CACHE_EXPIRES_COL = "expires";
-
- private static final String CACHE_EXPIRES_STRING_COL = "expiresstring";
-
- private static final String CACHE_MIMETYPE_COL = "mimetype";
-
- private static final String CACHE_ENCODING_COL = "encoding";
-
- private static final String CACHE_HTTP_STATUS_COL = "httpstatus";
-
- private static final String CACHE_LOCATION_COL = "location";
-
- private static final String CACHE_CONTENTLENGTH_COL = "contentlength";
-
- private static final String CACHE_CONTENTDISPOSITION_COL = "contentdisposition";
-
- private static final String CACHE_CROSSDOMAIN_COL = "crossdomain";
-
// column id strings for "password" table
private static final String PASSWORD_HOST_COL = "host";
-
private static final String PASSWORD_USERNAME_COL = "username";
-
private static final String PASSWORD_PASSWORD_COL = "password";
// column id strings for "formurl" table
@@ -148,38 +89,15 @@ public class WebViewDatabase {
// column id strings for "formdata" table
private static final String FORMDATA_URLID_COL = "urlid";
-
private static final String FORMDATA_NAME_COL = "name";
-
private static final String FORMDATA_VALUE_COL = "value";
// column id strings for "httpauth" table
private static final String HTTPAUTH_HOST_COL = "host";
-
private static final String HTTPAUTH_REALM_COL = "realm";
-
private static final String HTTPAUTH_USERNAME_COL = "username";
-
private static final String HTTPAUTH_PASSWORD_COL = "password";
- // use InsertHelper to improve insert performance by 40%
- private static DatabaseUtils.InsertHelper mCacheInserter;
- private static int mCacheUrlColIndex;
- private static int mCacheFilePathColIndex;
- private static int mCacheLastModifyColIndex;
- private static int mCacheETagColIndex;
- private static int mCacheExpiresColIndex;
- private static int mCacheExpiresStringColIndex;
- private static int mCacheMimeTypeColIndex;
- private static int mCacheEncodingColIndex;
- private static int mCacheHttpStatusColIndex;
- private static int mCacheLocationColIndex;
- private static int mCacheContentLengthColIndex;
- private static int mCacheContentDispositionColIndex;
- private static int mCacheCrossDomainColIndex;
-
- private static int mCacheTransactionRefcount;
-
// Initially true until the background thread completes.
private boolean mInitialized = false;
@@ -207,11 +125,9 @@ public class WebViewDatabase {
}
initDatabase(context);
- if (JniUtil.useChromiumHttpStack()) {
- context.deleteDatabase(CACHE_DATABASE_FILE);
- } else {
- initCacheDatabase(context);
- }
+ // Before using the Chromium HTTP stack, we stored the WebKit cache in
+ // our own DB. Clean up the DB file if it's still around.
+ context.deleteDatabase(CACHE_DATABASE_FILE);
// Thread done, notify.
mInitialized = true;
@@ -254,83 +170,6 @@ public class WebViewDatabase {
mDatabase.setLockingEnabled(false);
}
- private void initCacheDatabase(Context context) {
- assert !JniUtil.useChromiumHttpStack();
-
- try {
- mCacheDatabase = context.openOrCreateDatabase(
- CACHE_DATABASE_FILE, 0, null);
- } catch (SQLiteException e) {
- // try again by deleting the old db and create a new one
- if (context.deleteDatabase(CACHE_DATABASE_FILE)) {
- mCacheDatabase = context.openOrCreateDatabase(
- CACHE_DATABASE_FILE, 0, null);
- }
- }
- mCacheDatabase.enableWriteAheadLogging();
-
- // mCacheDatabase should not be null,
- // the only case is RequestAPI test has problem to create db
- if (mCacheDatabase == null) {
- mInitialized = true;
- notify();
- return;
- }
-
- if (mCacheDatabase.getVersion() != CACHE_DATABASE_VERSION) {
- mCacheDatabase.beginTransactionNonExclusive();
- try {
- upgradeCacheDatabase();
- bootstrapCacheDatabase();
- mCacheDatabase.setTransactionSuccessful();
- } finally {
- mCacheDatabase.endTransaction();
- }
- // Erase the files from the file system in the
- // case that the database was updated and the
- // there were existing cache content
- CacheManager.removeAllCacheFiles();
- }
-
- // use read_uncommitted to speed up READ
- mCacheDatabase.execSQL("PRAGMA read_uncommitted = true;");
- // as only READ can be called in the
- // non-WebViewWorkerThread, and read_uncommitted is used,
- // we can turn off database lock to use transaction.
- mCacheDatabase.setLockingEnabled(false);
-
- // use InsertHelper for faster insertion
- mCacheInserter =
- new DatabaseUtils.InsertHelper(mCacheDatabase,
- "cache");
- mCacheUrlColIndex = mCacheInserter
- .getColumnIndex(CACHE_URL_COL);
- mCacheFilePathColIndex = mCacheInserter
- .getColumnIndex(CACHE_FILE_PATH_COL);
- mCacheLastModifyColIndex = mCacheInserter
- .getColumnIndex(CACHE_LAST_MODIFY_COL);
- mCacheETagColIndex = mCacheInserter
- .getColumnIndex(CACHE_ETAG_COL);
- mCacheExpiresColIndex = mCacheInserter
- .getColumnIndex(CACHE_EXPIRES_COL);
- mCacheExpiresStringColIndex = mCacheInserter
- .getColumnIndex(CACHE_EXPIRES_STRING_COL);
- mCacheMimeTypeColIndex = mCacheInserter
- .getColumnIndex(CACHE_MIMETYPE_COL);
- mCacheEncodingColIndex = mCacheInserter
- .getColumnIndex(CACHE_ENCODING_COL);
- mCacheHttpStatusColIndex = mCacheInserter
- .getColumnIndex(CACHE_HTTP_STATUS_COL);
- mCacheLocationColIndex = mCacheInserter
- .getColumnIndex(CACHE_LOCATION_COL);
- mCacheContentLengthColIndex = mCacheInserter
- .getColumnIndex(CACHE_CONTENTLENGTH_COL);
- mCacheContentDispositionColIndex = mCacheInserter
- .getColumnIndex(CACHE_CONTENTDISPOSITION_COL);
- mCacheCrossDomainColIndex = mCacheInserter
- .getColumnIndex(CACHE_CROSSDOMAIN_COL);
- }
-
private static void upgradeDatabase() {
upgradeDatabaseToV10();
upgradeDatabaseFromV10ToV11();
@@ -347,14 +186,12 @@ public class WebViewDatabase {
return;
}
- if (JniUtil.useChromiumHttpStack()) {
- // Clear out old java stack cookies - this data is now stored in
- // a separate database managed by the Chrome stack.
- mDatabase.execSQL("DROP TABLE IF EXISTS " + mTableNames[TABLE_COOKIES_ID]);
+ // Clear out old java stack cookies - this data is now stored in
+ // a separate database managed by the Chrome stack.
+ mDatabase.execSQL("DROP TABLE IF EXISTS cookies");
- // Likewise for the old cache table.
- mDatabase.execSQL("DROP TABLE IF EXISTS cache");
- }
+ // Likewise for the old cache table.
+ mDatabase.execSQL("DROP TABLE IF EXISTS cache");
// Update form autocomplete URLs to match new ICS formatting.
Cursor c = mDatabase.query(mTableNames[TABLE_FORMURL_ID], null, null,
@@ -397,8 +234,7 @@ public class WebViewDatabase {
return;
}
- mDatabase.execSQL("DROP TABLE IF EXISTS "
- + mTableNames[TABLE_COOKIES_ID]);
+ mDatabase.execSQL("DROP TABLE IF EXISTS cookies");
mDatabase.execSQL("DROP TABLE IF EXISTS cache");
mDatabase.execSQL("DROP TABLE IF EXISTS "
+ mTableNames[TABLE_FORMURL_ID]);
@@ -409,16 +245,6 @@ public class WebViewDatabase {
mDatabase.execSQL("DROP TABLE IF EXISTS "
+ mTableNames[TABLE_PASSWORD_ID]);
- // cookies
- mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_COOKIES_ID]
- + " (" + ID_COL + " INTEGER PRIMARY KEY, "
- + COOKIES_NAME_COL + " TEXT, " + COOKIES_VALUE_COL
- + " TEXT, " + COOKIES_DOMAIN_COL + " TEXT, "
- + COOKIES_PATH_COL + " TEXT, " + COOKIES_EXPIRES_COL
- + " INTEGER, " + COOKIES_SECURE_COL + " INTEGER" + ");");
- mDatabase.execSQL("CREATE INDEX cookiesIndex ON "
- + mTableNames[TABLE_COOKIES_ID] + " (path)");
-
// formurl
mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMURL_ID]
+ " (" + ID_COL + " INTEGER PRIMARY KEY, " + FORMURL_URL_COL
@@ -449,36 +275,6 @@ public class WebViewDatabase {
+ ") ON CONFLICT REPLACE);");
}
- private static void upgradeCacheDatabase() {
- int oldVersion = mCacheDatabase.getVersion();
- if (oldVersion != 0) {
- Log.i(LOGTAG, "Upgrading cache database from version "
- + oldVersion + " to "
- + CACHE_DATABASE_VERSION + ", which will destroy all old data");
- }
- mCacheDatabase.execSQL("DROP TABLE IF EXISTS cache");
- mCacheDatabase.setVersion(CACHE_DATABASE_VERSION);
- }
-
- private static void bootstrapCacheDatabase() {
- if (mCacheDatabase != null) {
- mCacheDatabase.execSQL("CREATE TABLE cache"
- + " (" + ID_COL + " INTEGER PRIMARY KEY, " + CACHE_URL_COL
- + " TEXT, " + CACHE_FILE_PATH_COL + " TEXT, "
- + CACHE_LAST_MODIFY_COL + " TEXT, " + CACHE_ETAG_COL
- + " TEXT, " + CACHE_EXPIRES_COL + " INTEGER, "
- + CACHE_EXPIRES_STRING_COL + " TEXT, "
- + CACHE_MIMETYPE_COL + " TEXT, " + CACHE_ENCODING_COL
- + " TEXT," + CACHE_HTTP_STATUS_COL + " INTEGER, "
- + CACHE_LOCATION_COL + " TEXT, " + CACHE_CONTENTLENGTH_COL
- + " INTEGER, " + CACHE_CONTENTDISPOSITION_COL + " TEXT, "
- + CACHE_CROSSDOMAIN_COL + " TEXT,"
- + " UNIQUE (" + CACHE_URL_COL + ") ON CONFLICT REPLACE);");
- mCacheDatabase.execSQL("CREATE INDEX cacheUrlIndex ON cache ("
- + CACHE_URL_COL + ")");
- }
- }
-
// Wait for the background initialization thread to complete and check the
// database creation status.
private boolean checkInitialized() {
@@ -516,422 +312,6 @@ public class WebViewDatabase {
}
//
- // cookies functions
- //
-
- /**
- * Get cookies in the format of CookieManager.Cookie inside an ArrayList for
- * a given domain
- *
- * @return ArrayList<Cookie> If nothing is found, return an empty list.
- */
- ArrayList<Cookie> getCookiesForDomain(String domain) {
- ArrayList<Cookie> list = new ArrayList<Cookie>();
- if (domain == null || !checkInitialized()) {
- return list;
- }
-
- synchronized (mCookieLock) {
- final String[] columns = new String[] {
- ID_COL, COOKIES_DOMAIN_COL, COOKIES_PATH_COL,
- COOKIES_NAME_COL, COOKIES_VALUE_COL, COOKIES_EXPIRES_COL,
- COOKIES_SECURE_COL
- };
- final String selection = "(" + COOKIES_DOMAIN_COL
- + " GLOB '*' || ?)";
- Cursor cursor = null;
- try {
- cursor = mDatabase.query(mTableNames[TABLE_COOKIES_ID],
- columns, selection, new String[] { domain }, null, null,
- null);
- if (cursor.moveToFirst()) {
- int domainCol = cursor.getColumnIndex(COOKIES_DOMAIN_COL);
- int pathCol = cursor.getColumnIndex(COOKIES_PATH_COL);
- int nameCol = cursor.getColumnIndex(COOKIES_NAME_COL);
- int valueCol = cursor.getColumnIndex(COOKIES_VALUE_COL);
- int expiresCol = cursor.getColumnIndex(COOKIES_EXPIRES_COL);
- int secureCol = cursor.getColumnIndex(COOKIES_SECURE_COL);
- do {
- Cookie cookie = new Cookie();
- cookie.domain = cursor.getString(domainCol);
- cookie.path = cursor.getString(pathCol);
- cookie.name = cursor.getString(nameCol);
- cookie.value = cursor.getString(valueCol);
- if (cursor.isNull(expiresCol)) {
- cookie.expires = -1;
- } else {
- cookie.expires = cursor.getLong(expiresCol);
- }
- cookie.secure = cursor.getShort(secureCol) != 0;
- cookie.mode = Cookie.MODE_NORMAL;
- list.add(cookie);
- } while (cursor.moveToNext());
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "getCookiesForDomain", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return list;
- }
- }
-
- /**
- * Delete cookies which matches (domain, path, name).
- *
- * @param domain If it is null, nothing happens.
- * @param path If it is null, all the cookies match (domain) will be
- * deleted.
- * @param name If it is null, all the cookies match (domain, path) will be
- * deleted.
- */
- void deleteCookies(String domain, String path, String name) {
- if (domain == null || !checkInitialized()) {
- return;
- }
-
- synchronized (mCookieLock) {
- final String where = "(" + COOKIES_DOMAIN_COL + " == ?) AND ("
- + COOKIES_PATH_COL + " == ?) AND (" + COOKIES_NAME_COL
- + " == ?)";
- mDatabase.delete(mTableNames[TABLE_COOKIES_ID], where,
- new String[] { domain, path, name });
- }
- }
-
- /**
- * Add a cookie to the database
- *
- * @param cookie
- */
- void addCookie(Cookie cookie) {
- if (cookie.domain == null || cookie.path == null || cookie.name == null
- || !checkInitialized()) {
- return;
- }
-
- synchronized (mCookieLock) {
- ContentValues cookieVal = new ContentValues();
- cookieVal.put(COOKIES_DOMAIN_COL, cookie.domain);
- cookieVal.put(COOKIES_PATH_COL, cookie.path);
- cookieVal.put(COOKIES_NAME_COL, cookie.name);
- cookieVal.put(COOKIES_VALUE_COL, cookie.value);
- if (cookie.expires != -1) {
- cookieVal.put(COOKIES_EXPIRES_COL, cookie.expires);
- }
- cookieVal.put(COOKIES_SECURE_COL, cookie.secure);
- mDatabase.insert(mTableNames[TABLE_COOKIES_ID], null, cookieVal);
- }
- }
-
- /**
- * Whether there is any cookies in the database
- *
- * @return TRUE if there is cookie.
- */
- boolean hasCookies() {
- synchronized (mCookieLock) {
- return hasEntries(TABLE_COOKIES_ID);
- }
- }
-
- /**
- * Clear cookie database
- */
- void clearCookies() {
- if (!checkInitialized()) {
- return;
- }
-
- synchronized (mCookieLock) {
- mDatabase.delete(mTableNames[TABLE_COOKIES_ID], null, null);
- }
- }
-
- /**
- * Clear session cookies, which means cookie doesn't have EXPIRES.
- */
- void clearSessionCookies() {
- if (!checkInitialized()) {
- return;
- }
-
- final String sessionExpired = COOKIES_EXPIRES_COL + " ISNULL";
- synchronized (mCookieLock) {
- mDatabase.delete(mTableNames[TABLE_COOKIES_ID], sessionExpired,
- null);
- }
- }
-
- /**
- * Clear expired cookies
- *
- * @param now Time for now
- */
- void clearExpiredCookies(long now) {
- if (!checkInitialized()) {
- return;
- }
-
- final String expires = COOKIES_EXPIRES_COL + " <= ?";
- synchronized (mCookieLock) {
- mDatabase.delete(mTableNames[TABLE_COOKIES_ID], expires,
- new String[] { Long.toString(now) });
- }
- }
-
- //
- // cache functions
- //
-
- // only called from WebViewWorkerThread
- boolean startCacheTransaction() {
- if (++mCacheTransactionRefcount == 1) {
- if (!Thread.currentThread().equals(
- WebViewWorker.getHandler().getLooper().getThread())) {
- Log.w(LOGTAG, "startCacheTransaction should be called from "
- + "WebViewWorkerThread instead of from "
- + Thread.currentThread().getName());
- }
- mCacheDatabase.beginTransactionNonExclusive();
- return true;
- }
- return false;
- }
-
- // only called from WebViewWorkerThread
- boolean endCacheTransaction() {
- if (--mCacheTransactionRefcount == 0) {
- if (!Thread.currentThread().equals(
- WebViewWorker.getHandler().getLooper().getThread())) {
- Log.w(LOGTAG, "endCacheTransaction should be called from "
- + "WebViewWorkerThread instead of from "
- + Thread.currentThread().getName());
- }
- try {
- mCacheDatabase.setTransactionSuccessful();
- } finally {
- mCacheDatabase.endTransaction();
- }
- return true;
- }
- return false;
- }
-
- /**
- * Get a cache item.
- *
- * @param url The url
- * @return CacheResult The CacheManager.CacheResult
- */
- CacheResult getCache(String url) {
- assert !JniUtil.useChromiumHttpStack();
-
- if (url == null || !checkInitialized()) {
- return null;
- }
-
- Cursor cursor = null;
- final String query = "SELECT filepath, lastmodify, etag, expires, "
- + "expiresstring, mimetype, encoding, httpstatus, location, contentlength, "
- + "contentdisposition, crossdomain FROM cache WHERE url = ?";
- try {
- cursor = mCacheDatabase.rawQuery(query, new String[] { url });
- if (cursor.moveToFirst()) {
- CacheResult ret = new CacheResult();
- ret.localPath = cursor.getString(0);
- ret.lastModified = cursor.getString(1);
- ret.etag = cursor.getString(2);
- ret.expires = cursor.getLong(3);
- ret.expiresString = cursor.getString(4);
- ret.mimeType = cursor.getString(5);
- ret.encoding = cursor.getString(6);
- ret.httpStatusCode = cursor.getInt(7);
- ret.location = cursor.getString(8);
- ret.contentLength = cursor.getLong(9);
- ret.contentdisposition = cursor.getString(10);
- ret.crossDomain = cursor.getString(11);
- return ret;
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "getCache", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return null;
- }
-
- /**
- * Remove a cache item.
- *
- * @param url The url
- */
- void removeCache(String url) {
- assert !JniUtil.useChromiumHttpStack();
-
- if (url == null || !checkInitialized()) {
- return;
- }
-
- mCacheDatabase.execSQL("DELETE FROM cache WHERE url = ?", new String[] { url });
- }
-
- /**
- * Add or update a cache. CACHE_URL_COL is unique in the table.
- *
- * @param url The url
- * @param c The CacheManager.CacheResult
- */
- void addCache(String url, CacheResult c) {
- assert !JniUtil.useChromiumHttpStack();
-
- if (url == null || !checkInitialized()) {
- return;
- }
-
- mCacheInserter.prepareForInsert();
- mCacheInserter.bind(mCacheUrlColIndex, url);
- mCacheInserter.bind(mCacheFilePathColIndex, c.localPath);
- mCacheInserter.bind(mCacheLastModifyColIndex, c.lastModified);
- mCacheInserter.bind(mCacheETagColIndex, c.etag);
- mCacheInserter.bind(mCacheExpiresColIndex, c.expires);
- mCacheInserter.bind(mCacheExpiresStringColIndex, c.expiresString);
- mCacheInserter.bind(mCacheMimeTypeColIndex, c.mimeType);
- mCacheInserter.bind(mCacheEncodingColIndex, c.encoding);
- mCacheInserter.bind(mCacheHttpStatusColIndex, c.httpStatusCode);
- mCacheInserter.bind(mCacheLocationColIndex, c.location);
- mCacheInserter.bind(mCacheContentLengthColIndex, c.contentLength);
- mCacheInserter.bind(mCacheContentDispositionColIndex,
- c.contentdisposition);
- mCacheInserter.bind(mCacheCrossDomainColIndex, c.crossDomain);
- mCacheInserter.execute();
- }
-
- /**
- * Clear cache database
- */
- void clearCache() {
- if (!checkInitialized()) {
- return;
- }
-
- mCacheDatabase.delete("cache", null, null);
- }
-
- boolean hasCache() {
- if (!checkInitialized()) {
- return false;
- }
-
- Cursor cursor = null;
- boolean ret = false;
- try {
- cursor = mCacheDatabase.query("cache", ID_PROJECTION,
- null, null, null, null, null);
- ret = cursor.moveToFirst() == true;
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "hasCache", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return ret;
- }
-
- long getCacheTotalSize() {
- if (mCacheDatabase == null) {
- return 0;
- }
- long size = 0;
- Cursor cursor = null;
- final String query = "SELECT SUM(contentlength) as sum FROM cache";
- try {
- cursor = mCacheDatabase.rawQuery(query, null);
- if (cursor.moveToFirst()) {
- size = cursor.getLong(0);
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "getCacheTotalSize", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return size;
- }
-
- List<String> trimCache(long amount) {
- ArrayList<String> pathList = new ArrayList<String>(100);
- Cursor cursor = null;
- final String query = "SELECT contentlength, filepath FROM cache ORDER BY expires ASC";
- try {
- cursor = mCacheDatabase.rawQuery(query, null);
- if (cursor.moveToFirst()) {
- int batchSize = 100;
- StringBuilder pathStr = new StringBuilder(20 + 16 * batchSize);
- pathStr.append("DELETE FROM cache WHERE filepath IN (?");
- for (int i = 1; i < batchSize; i++) {
- pathStr.append(", ?");
- }
- pathStr.append(")");
- SQLiteStatement statement = null;
- try {
- statement = mCacheDatabase.compileStatement(
- pathStr.toString());
- // as bindString() uses 1-based index, initialize index to 1
- int index = 1;
- do {
- long length = cursor.getLong(0);
- if (length == 0) {
- continue;
- }
- amount -= length;
- String filePath = cursor.getString(1);
- statement.bindString(index, filePath);
- pathList.add(filePath);
- if (index++ == batchSize) {
- statement.execute();
- statement.clearBindings();
- index = 1;
- }
- } while (cursor.moveToNext() && amount > 0);
- if (index > 1) {
- // there may be old bindings from the previous statement
- // if index is less than batchSize, which is Ok.
- statement.execute();
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "trimCache SQLiteStatement", e);
- } finally {
- if (statement != null) statement.close();
- }
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "trimCache Cursor", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return pathList;
- }
-
- List<String> getAllCacheFileNames() {
- ArrayList<String> pathList = null;
- Cursor cursor = null;
- try {
- cursor = mCacheDatabase.rawQuery("SELECT filepath FROM cache",
- null);
- if (cursor != null && cursor.moveToFirst()) {
- pathList = new ArrayList<String>(cursor.getCount());
- do {
- pathList.add(cursor.getString(0));
- } while (cursor.moveToNext());
- }
- } catch (IllegalStateException e) {
- Log.e(LOGTAG, "getAllCacheFileNames", e);
- } finally {
- if (cursor != null) cursor.close();
- }
- return pathList;
- }
-
- //
// password functions
//
diff --git a/core/java/android/webkit/WebViewWorker.java b/core/java/android/webkit/WebViewWorker.java
deleted file mode 100644
index 6a4ca2918f1c..000000000000
--- a/core/java/android/webkit/WebViewWorker.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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.
- */
-
-package android.webkit;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.net.http.Headers;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-
-/**
- * WebViewWorker executes in a separate thread other than UI and WebViewCore. To
- * avoid blocking UI or WebKit's execution, the caller can send a message to
- * WebViewWorker.getHandler() and it will be handled in the WebViewWorkerThread.
- */
-final class WebViewWorker extends Handler {
-
- private static final String THREAD_NAME = "WebViewWorkerThread";
-
- private static WebViewWorker sWorkerHandler;
-
- private static Map<LoadListener, CacheManager.CacheResult> mCacheResultMap
- = new HashMap<LoadListener, CacheManager.CacheResult>();
-
- /**
- * Package level class to be used while creating a cache entry.
- */
- static class CacheCreateData {
- LoadListener mListener;
- String mUrl;
- String mMimeType;
- int mStatusCode;
- long mPostId;
- Headers mHeaders;
- }
-
- /**
- * Package level class to be used while saving a cache entry.
- */
- static class CacheSaveData {
- LoadListener mListener;
- String mUrl;
- long mPostId;
- }
-
- /**
- * Package level class to be used while updating a cache entry's encoding.
- */
- static class CacheEncoding {
- LoadListener mListener;
- String mEncoding;
- }
-
- /**
- * Package level class to be used while appending data to a cache entry.
- */
- static class CacheData {
- LoadListener mListener;
- ByteArrayBuilder.Chunk mChunk;
- }
-
- static synchronized WebViewWorker getHandler() {
- if (sWorkerHandler == null) {
- HandlerThread thread = new HandlerThread(THREAD_NAME,
- android.os.Process.THREAD_PRIORITY_DEFAULT
- + android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE);
- thread.start();
- sWorkerHandler = new WebViewWorker(thread.getLooper());
- }
- return sWorkerHandler;
- }
-
- private WebViewWorker(Looper looper) {
- super(looper);
- }
-
- // trigger transaction once a minute
- private static final int CACHE_TRANSACTION_TICKER_INTERVAL = 60 * 1000;
-
- private static boolean mCacheTickersBlocked = true;
-
- // message ids
- static final int MSG_ADD_STREAMLOADER = 101;
- static final int MSG_ADD_HTTPLOADER = 102;
- static final int MSG_CREATE_CACHE = 103;
- static final int MSG_UPDATE_CACHE_ENCODING = 104;
- static final int MSG_APPEND_CACHE = 105;
- static final int MSG_SAVE_CACHE = 106;
- static final int MSG_REMOVE_CACHE = 107;
- static final int MSG_TRIM_CACHE = 108;
- static final int MSG_CLEAR_CACHE = 109;
- static final int MSG_CACHE_TRANSACTION_TICKER = 110;
- static final int MSG_PAUSE_CACHE_TRANSACTION = 111;
- static final int MSG_RESUME_CACHE_TRANSACTION = 112;
-
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case MSG_ADD_STREAMLOADER: {
- StreamLoader loader = (StreamLoader) msg.obj;
- loader.load();
- break;
- }
- case MSG_ADD_HTTPLOADER: {
- FrameLoader loader = (FrameLoader) msg.obj;
- loader.handleHTTPLoad();
- break;
- }
- case MSG_CREATE_CACHE: {
- assert !JniUtil.useChromiumHttpStack();
- CacheCreateData data = (CacheCreateData) msg.obj;
- CacheManager.CacheResult cache = CacheManager.createCacheFile(
- data.mUrl, data.mStatusCode, data.mHeaders,
- data.mMimeType, data.mPostId, false);
- if (cache != null) {
- mCacheResultMap.put(data.mListener, cache);
- } else {
- mCacheResultMap.remove(data.mListener);
- }
- break;
- }
- case MSG_UPDATE_CACHE_ENCODING: {
- assert !JniUtil.useChromiumHttpStack();
- CacheEncoding data = (CacheEncoding) msg.obj;
- CacheManager.CacheResult cache = mCacheResultMap
- .get(data.mListener);
- if (cache != null) {
- cache.encoding = data.mEncoding;
- }
- break;
- }
- case MSG_APPEND_CACHE: {
- assert !JniUtil.useChromiumHttpStack();
- CacheData data = (CacheData) msg.obj;
- CacheManager.CacheResult cache = mCacheResultMap
- .get(data.mListener);
- if (cache != null) {
- cache.contentLength += data.mChunk.mLength;
- if (cache.contentLength > CacheManager.CACHE_MAX_SIZE) {
- CacheManager.cleanupCacheFile(cache);
- mCacheResultMap.remove(data.mListener);
- } else {
- try {
- cache.outStream.write(data.mChunk.mArray, 0,
- data.mChunk.mLength);
- } catch (IOException e) {
- CacheManager.cleanupCacheFile(cache);
- mCacheResultMap.remove(data.mListener);
- }
- }
- }
- data.mChunk.release();
- break;
- }
- case MSG_SAVE_CACHE: {
- assert !JniUtil.useChromiumHttpStack();
- CacheSaveData data = (CacheSaveData) msg.obj;
- CacheManager.CacheResult cache = mCacheResultMap
- .get(data.mListener);
- if (cache != null) {
- CacheManager.saveCacheFile(data.mUrl, data.mPostId, cache);
- mCacheResultMap.remove(data.mListener);
- }
- break;
- }
- case MSG_REMOVE_CACHE: {
- assert !JniUtil.useChromiumHttpStack();
- LoadListener listener = (LoadListener) msg.obj;
- CacheManager.CacheResult cache = mCacheResultMap.get(listener);
- if (cache != null) {
- CacheManager.cleanupCacheFile(cache);
- mCacheResultMap.remove(listener);
- }
- break;
- }
- case MSG_TRIM_CACHE: {
- assert !JniUtil.useChromiumHttpStack();
- CacheManager.trimCacheIfNeeded();
- break;
- }
- case MSG_CLEAR_CACHE: {
- assert !JniUtil.useChromiumHttpStack();
- CacheManager.clearCache();
- break;
- }
- case MSG_CACHE_TRANSACTION_TICKER: {
- assert !JniUtil.useChromiumHttpStack();
- if (!mCacheTickersBlocked) {
- CacheManager.endTransaction();
- CacheManager.startTransaction();
- sendEmptyMessageDelayed(MSG_CACHE_TRANSACTION_TICKER,
- CACHE_TRANSACTION_TICKER_INTERVAL);
- }
- break;
- }
- case MSG_PAUSE_CACHE_TRANSACTION: {
- assert !JniUtil.useChromiumHttpStack();
- if (CacheManager.disableTransaction()) {
- mCacheTickersBlocked = true;
- removeMessages(MSG_CACHE_TRANSACTION_TICKER);
- }
- break;
- }
- case MSG_RESUME_CACHE_TRANSACTION: {
- assert !JniUtil.useChromiumHttpStack();
- if (CacheManager.enableTransaction()) {
- mCacheTickersBlocked = false;
- sendEmptyMessageDelayed(MSG_CACHE_TRANSACTION_TICKER,
- CACHE_TRANSACTION_TICKER_INTERVAL);
- }
- break;
- }
- }
- }
-}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2602523c283f..577444068bd7 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1020,6 +1020,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mChoiceMode != CHOICE_MODE_NONE) {
handled = true;
+ boolean checkedStateChanged = false;
if (mChoiceMode == CHOICE_MODE_MULTIPLE ||
(mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL && mChoiceActionMode != null)) {
@@ -1042,6 +1043,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
position, id, newValue);
dispatchItemClick = false;
}
+ checkedStateChanged = true;
} else if (mChoiceMode == CHOICE_MODE_SINGLE) {
boolean newValue = !mCheckStates.get(position, false);
if (newValue) {
@@ -1055,11 +1057,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
} else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
mCheckedItemCount = 0;
}
+ checkedStateChanged = true;
}
- mDataChanged = true;
- rememberSyncState();
- requestLayout();
+ if (checkedStateChanged) {
+ updateOnScreenCheckedViews();
+ }
}
if (dispatchItemClick) {
@@ -1070,6 +1073,28 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
+ * Perform a quick, in-place update of the checked or activated state
+ * on all visible item views. This should only be called when a valid
+ * choice mode is active.
+ */
+ private void updateOnScreenCheckedViews() {
+ final int firstPos = mFirstPosition;
+ final int count = getChildCount();
+ final boolean useActivated = getContext().getApplicationInfo().targetSdkVersion
+ >= android.os.Build.VERSION_CODES.HONEYCOMB;
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ final int position = firstPos + i;
+
+ if (child instanceof Checkable) {
+ ((Checkable) child).setChecked(mCheckStates.get(position));
+ } else if (useActivated) {
+ child.setActivated(mCheckStates.get(position));
+ }
+ }
+ }
+
+ /**
* @see #setChoiceMode(int)
*
* @return The current choice mode
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 988760db7028..e6184d5e605c 100755
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -26,6 +26,12 @@ import android.content.pm.PackageParser;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -61,18 +67,52 @@ public class AppSecurityPermissions implements View.OnClickListener {
BOTH
}
+ static class MyPermissionInfo extends PermissionInfo {
+ /**
+ * PackageInfo.requestedPermissionsFlags for the new package being installed.
+ */
+ int mNewReqFlags;
+
+ /**
+ * PackageInfo.requestedPermissionsFlags for the currently installed
+ * package, if it is installed.
+ */
+ int mExistingReqFlags;
+
+ /**
+ * True if this should be considered a new permission.
+ */
+ boolean mNew;
+
+ MyPermissionInfo() {
+ }
+
+ MyPermissionInfo(PermissionInfo info) {
+ super(info);
+ }
+
+ MyPermissionInfo(MyPermissionInfo info) {
+ super(info);
+ mNewReqFlags = info.mNewReqFlags;
+ mExistingReqFlags = info.mExistingReqFlags;
+ mNew = info.mNew;
+ }
+ }
+
private final static String TAG = "AppSecurityPermissions";
private boolean localLOGV = false;
private Context mContext;
private LayoutInflater mInflater;
private PackageManager mPm;
private LinearLayout mPermsView;
- private Map<String, String> mDangerousMap;
- private Map<String, String> mNormalMap;
- private List<PermissionInfo> mPermsList;
+ private Map<String, CharSequence> mNewMap;
+ private Map<String, CharSequence> mDangerousMap;
+ private Map<String, CharSequence> mNormalMap;
+ private List<MyPermissionInfo> mPermsList;
private String mDefaultGrpLabel;
private String mDefaultGrpName="DefaultGrp";
private String mPermFormat;
+ private CharSequence mNewPermPrefix;
private Drawable mNormalIcon;
private Drawable mDangerousIcon;
private boolean mExpanded;
@@ -84,20 +124,23 @@ public class AppSecurityPermissions implements View.OnClickListener {
private State mCurrentState;
private LinearLayout mNonDangerousList;
private LinearLayout mDangerousList;
+ private LinearLayout mNewList;
private HashMap<String, CharSequence> mGroupLabelCache;
private View mNoPermsView;
-
+
public AppSecurityPermissions(Context context, List<PermissionInfo> permList) {
mContext = context;
mPm = mContext.getPackageManager();
- mPermsList = permList;
+ for (PermissionInfo pi : permList) {
+ mPermsList.add(new MyPermissionInfo(pi));
+ }
}
public AppSecurityPermissions(Context context, String packageName) {
mContext = context;
mPm = mContext.getPackageManager();
- mPermsList = new ArrayList<PermissionInfo>();
- Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
+ mPermsList = new ArrayList<MyPermissionInfo>();
+ Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
PackageInfo pkgInfo;
try {
pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
@@ -109,7 +152,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
}
- for(PermissionInfo tmpInfo : permSet) {
+ for(MyPermissionInfo tmpInfo : permSet) {
mPermsList.add(tmpInfo);
}
}
@@ -117,21 +160,27 @@ public class AppSecurityPermissions implements View.OnClickListener {
public AppSecurityPermissions(Context context, PackageParser.Package pkg) {
mContext = context;
mPm = mContext.getPackageManager();
- mPermsList = new ArrayList<PermissionInfo>();
- Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
+ mPermsList = new ArrayList<MyPermissionInfo>();
+ Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
if(pkg == null) {
return;
}
+
+ // Convert to a PackageInfo
+ PackageInfo info = PackageParser.generatePackageInfo(pkg, null,
+ PackageManager.GET_PERMISSIONS, 0, 0, null);
+ PackageInfo installedPkgInfo = null;
// Get requested permissions
- if (pkg.requestedPermissions != null) {
- ArrayList<String> strList = pkg.requestedPermissions;
- int size = strList.size();
- if (size > 0) {
- extractPerms(strList.toArray(new String[size]), permSet);
+ if (info.requestedPermissions != null) {
+ try {
+ installedPkgInfo = mPm.getPackageInfo(info.packageName,
+ PackageManager.GET_PERMISSIONS);
+ } catch (NameNotFoundException e) {
}
+ extractPerms(info, permSet, installedPkgInfo);
}
// Get permissions related to shared user if any
- if(pkg.mSharedUserId != null) {
+ if (pkg.mSharedUserId != null) {
int sharedUid;
try {
sharedUid = mPm.getUidForSharedUser(pkg.mSharedUserId);
@@ -141,7 +190,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
}
}
// Retrieve list of permissions
- for(PermissionInfo tmpInfo : permSet) {
+ for (MyPermissionInfo tmpInfo : permSet) {
mPermsList.add(tmpInfo);
}
}
@@ -159,7 +208,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
description, dangerous, icon);
}
- private void getAllUsedPermissions(int sharedUid, Set<PermissionInfo> permSet) {
+ private void getAllUsedPermissions(int sharedUid, Set<MyPermissionInfo> permSet) {
String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
if(sharedPkgList == null || (sharedPkgList.length == 0)) {
return;
@@ -170,29 +219,65 @@ public class AppSecurityPermissions implements View.OnClickListener {
}
private void getPermissionsForPackage(String packageName,
- Set<PermissionInfo> permSet) {
+ Set<MyPermissionInfo> permSet) {
PackageInfo pkgInfo;
try {
pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
} catch (NameNotFoundException e) {
- Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
+ Log.w(TAG, "Couldn't retrieve permissions for package:"+packageName);
return;
}
if ((pkgInfo != null) && (pkgInfo.requestedPermissions != null)) {
- extractPerms(pkgInfo.requestedPermissions, permSet);
+ extractPerms(pkgInfo, permSet, pkgInfo);
}
}
-
- private void extractPerms(String strList[], Set<PermissionInfo> permSet) {
- if((strList == null) || (strList.length == 0)) {
+
+ private void extractPerms(PackageInfo info, Set<MyPermissionInfo> permSet,
+ PackageInfo installedPkgInfo) {
+ String[] strList = info.requestedPermissions;
+ int[] flagsList = info.requestedPermissionsFlags;
+ if ((strList == null) || (strList.length == 0)) {
return;
}
- for(String permName:strList) {
+ for (int i=0; i<strList.length; i++) {
+ String permName = strList[i];
+ // If we are only looking at an existing app, then we only
+ // care about permissions that have actually been granted to it.
+ if (installedPkgInfo != null && info == installedPkgInfo) {
+ if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
+ continue;
+ }
+ }
try {
PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
- if(tmpPermInfo != null) {
- permSet.add(tmpPermInfo);
+ if (tmpPermInfo == null) {
+ continue;
+ }
+ int existingIndex = -1;
+ if (installedPkgInfo != null
+ && installedPkgInfo.requestedPermissions != null) {
+ for (int j=0; j<installedPkgInfo.requestedPermissions.length; j++) {
+ if (permName.equals(installedPkgInfo.requestedPermissions[j])) {
+ existingIndex = j;
+ break;
+ }
+ }
}
+ final int existingFlags = existingIndex >= 0 ?
+ installedPkgInfo.requestedPermissionsFlags[existingIndex] : 0;
+ if (!isDisplayablePermission(tmpPermInfo, flagsList[i], existingFlags)) {
+ // This is not a permission that is interesting for the user
+ // to see, so skip it.
+ continue;
+ }
+ MyPermissionInfo myPerm = new MyPermissionInfo(tmpPermInfo);
+ myPerm.mNewReqFlags = flagsList[i];
+ myPerm.mExistingReqFlags = existingFlags;
+ // This is a new permission if the app is already installed and
+ // doesn't currently hold this permission.
+ myPerm.mNew = installedPkgInfo != null
+ && (existingFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
+ permSet.add(myPerm);
} catch (NameNotFoundException e) {
Log.i(TAG, "Ignoring unknown permission:"+permName);
}
@@ -210,6 +295,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
mShowMore = mPermsView.findViewById(R.id.show_more);
mShowMoreIcon = (ImageView) mShowMore.findViewById(R.id.show_more_icon);
mShowMoreText = (TextView) mShowMore.findViewById(R.id.show_more_text);
+ mNewList = (LinearLayout) mPermsView.findViewById(R.id.new_perms_list);
mDangerousList = (LinearLayout) mPermsView.findViewById(R.id.dangerous_perms_list);
mNonDangerousList = (LinearLayout) mPermsView.findViewById(R.id.non_dangerous_perms_list);
mNoPermsView = mPermsView.findViewById(R.id.no_permissions);
@@ -222,6 +308,7 @@ public class AppSecurityPermissions implements View.OnClickListener {
// Pick up from framework resources instead.
mDefaultGrpLabel = mContext.getString(R.string.default_permission_group);
mPermFormat = mContext.getString(R.string.permissions_format);
+ mNewPermPrefix = mContext.getText(R.string.perms_new_perm_prefix);
mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
mShowMaxIcon = mContext.getResources().getDrawable(R.drawable.expander_close_holo_dark);
@@ -233,38 +320,55 @@ public class AppSecurityPermissions implements View.OnClickListener {
}
/**
- * Canonicalizes the group description before it is displayed to the user.
- *
- * TODO check for internationalization issues remove trailing '.' in str1
- */
- private String canonicalizeGroupDesc(String groupDesc) {
- if ((groupDesc == null) || (groupDesc.length() == 0)) {
- return null;
- }
- // Both str1 and str2 are non-null and are non-zero in size.
- int len = groupDesc.length();
- if(groupDesc.charAt(len-1) == '.') {
- groupDesc = groupDesc.substring(0, len-1);
- }
- return groupDesc;
- }
-
- /**
* Utility method that concatenates two strings defined by mPermFormat.
* a null value is returned if both str1 and str2 are null, if one of the strings
* is null the other non null value is returned without formatting
* this is to placate initial error checks
*/
- private String formatPermissions(String groupDesc, CharSequence permDesc) {
- if(groupDesc == null) {
- if(permDesc == null) {
- return null;
+ private CharSequence formatPermissions(CharSequence groupDesc, CharSequence permDesc,
+ boolean newPerms) {
+ if (permDesc == null) {
+ return groupDesc;
+ }
+ // Sometimes people write permission names with a trailing period;
+ // strip that if it appears.
+ int len = permDesc.length();
+ if (len > 0 && permDesc.charAt(len-1) == '.') {
+ permDesc = (permDesc.toString()).substring(0, len-1);
+ }
+ if (newPerms) {
+ if (true) {
+ // If this is a new permission, format it appropriately.
+ SpannableStringBuilder builder = new SpannableStringBuilder();
+ if (groupDesc != null) {
+ // The previous permissions go in front, with a newline
+ // separating them.
+ builder.append(groupDesc);
+ builder.append("\n");
+ }
+ Parcel parcel = Parcel.obtain();
+ TextUtils.writeToParcel(mNewPermPrefix, parcel, 0);
+ parcel.setDataPosition(0);
+ CharSequence newStr = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+ builder.append(newStr);
+ builder.append(permDesc);
+ return builder;
+ } else {
+ // If this is a new permission, format it appropriately.
+ SpannableStringBuilder builder = new SpannableStringBuilder(permDesc);
+ builder.insert(0, mNewPermPrefix);
+ if (groupDesc != null) {
+ // The previous permissions go in front, with a newline
+ // separating them.
+ builder.insert(0, "\n");
+ builder.insert(0, groupDesc);
+ }
+ return builder;
}
- return permDesc.toString();
}
- groupDesc = canonicalizeGroupDesc(groupDesc);
- if(permDesc == null) {
- return groupDesc;
+ if (groupDesc == null) {
+ return permDesc;
}
// groupDesc and permDesc are non null
return String.format(mPermFormat, groupDesc, permDesc.toString());
@@ -295,9 +399,8 @@ public class AppSecurityPermissions implements View.OnClickListener {
* Utility method that displays permissions from a map containing group name and
* list of permission descriptions.
*/
- private void displayPermissions(boolean dangerous) {
- Map<String, String> permInfoMap = dangerous ? mDangerousMap : mNormalMap;
- LinearLayout permListView = dangerous ? mDangerousList : mNonDangerousList;
+ private void displayPermissions(Map<String, CharSequence> permInfoMap,
+ LinearLayout permListView, boolean dangerous) {
permListView.removeAllViews();
Set<String> permInfoStrSet = permInfoMap.keySet();
@@ -349,17 +452,20 @@ public class AppSecurityPermissions implements View.OnClickListener {
break;
case DANGEROUS_ONLY:
- displayPermissions(true);
+ displayPermissions(mNewMap, mNewList, true);
+ displayPermissions(mDangerousMap, mDangerousList, true);
break;
case NORMAL_ONLY:
- displayPermissions(false);
+ displayPermissions(mNewMap, mNewList, true);
+ displayPermissions(mNormalMap, mNonDangerousList, false);
break;
case BOTH:
- displayPermissions(true);
+ displayPermissions(mNewMap, mNewList, true);
+ displayPermissions(mDangerousMap, mDangerousList, true);
if (mExpanded) {
- displayPermissions(false);
+ displayPermissions(mNormalMap, mNonDangerousList, false);
mShowMoreIcon.setImageDrawable(mShowMaxIcon);
mShowMoreText.setText(R.string.perms_hide);
mNonDangerousList.setVisibility(View.VISIBLE);
@@ -372,22 +478,38 @@ public class AppSecurityPermissions implements View.OnClickListener {
break;
}
}
-
- private boolean isDisplayablePermission(PermissionInfo pInfo) {
- if(pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS ||
- pInfo.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
+
+ private boolean isDisplayablePermission(PermissionInfo pInfo, int newReqFlags,
+ int existingReqFlags) {
+ final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+ // Dangerous and normal permissions are always shown to the user.
+ if (base == PermissionInfo.PROTECTION_DANGEROUS ||
+ base == PermissionInfo.PROTECTION_NORMAL) {
+ return true;
+ }
+ // Development permissions are only shown to the user if they are already
+ // granted to the app -- if we are installing an app and they are not
+ // already granted, they will not be granted as part of the install.
+ // Note we also need the app to have specified this permission is not
+ // required -- this is not technically needed, but it helps various things
+ // if we ensure apps always mark development permissions as option, so that
+ // even not knowing what a permission is we can still know whether it will
+ // be granted to the app when it is installed.
+ if ((existingReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
+ && (newReqFlags&PackageInfo.REQUESTED_PERMISSION_REQUIRED) == 0
+ && (pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
return true;
}
return false;
}
-
+
/*
* Utility method that aggregates all permission descriptions categorized by group
* Say group1 has perm11, perm12, perm13, the group description will be
* perm11_Desc, perm12_Desc, perm13_Desc
*/
- private void aggregateGroupDescs(
- Map<String, List<PermissionInfo> > map, Map<String, String> retMap) {
+ private void aggregateGroupDescs(Map<String, List<MyPermissionInfo> > map,
+ Map<String, CharSequence> retMap, boolean newPerms) {
if(map == null) {
return;
}
@@ -397,20 +519,20 @@ public class AppSecurityPermissions implements View.OnClickListener {
Set<String> grpNames = map.keySet();
Iterator<String> grpNamesIter = grpNames.iterator();
while(grpNamesIter.hasNext()) {
- String grpDesc = null;
+ CharSequence grpDesc = null;
String grpNameKey = grpNamesIter.next();
- List<PermissionInfo> grpPermsList = map.get(grpNameKey);
+ List<MyPermissionInfo> grpPermsList = map.get(grpNameKey);
if(grpPermsList == null) {
continue;
}
for(PermissionInfo permInfo: grpPermsList) {
CharSequence permDesc = permInfo.loadLabel(mPm);
- grpDesc = formatPermissions(grpDesc, permDesc);
+ grpDesc = formatPermissions(grpDesc, permDesc, newPerms);
}
// Insert grpDesc into map
if(grpDesc != null) {
if(localLOGV) Log.i(TAG, "Group:"+grpNameKey+" description:"+grpDesc.toString());
- retMap.put(grpNameKey, grpDesc.toString());
+ retMap.put(grpNameKey, grpDesc);
}
}
}
@@ -428,42 +550,53 @@ public class AppSecurityPermissions implements View.OnClickListener {
}
}
- private void setPermissions(List<PermissionInfo> permList) {
+ private void setPermissions(List<MyPermissionInfo> permList) {
mGroupLabelCache = new HashMap<String, CharSequence>();
//add the default label so that uncategorized permissions can go here
mGroupLabelCache.put(mDefaultGrpName, mDefaultGrpLabel);
// Map containing group names and a list of permissions under that group
+ // that are new from the current install
+ mNewMap = new HashMap<String, CharSequence>();
+ // Map containing group names and a list of permissions under that group
// categorized as dangerous
- mDangerousMap = new HashMap<String, String>();
+ mDangerousMap = new HashMap<String, CharSequence>();
// Map containing group names and a list of permissions under that group
// categorized as normal
- mNormalMap = new HashMap<String, String>();
+ mNormalMap = new HashMap<String, CharSequence>();
// Additional structures needed to ensure that permissions are unique under
// each group
- Map<String, List<PermissionInfo>> dangerousMap =
- new HashMap<String, List<PermissionInfo>>();
- Map<String, List<PermissionInfo> > normalMap =
- new HashMap<String, List<PermissionInfo>>();
+ Map<String, List<MyPermissionInfo>> newMap =
+ new HashMap<String, List<MyPermissionInfo>>();
+ Map<String, List<MyPermissionInfo>> dangerousMap =
+ new HashMap<String, List<MyPermissionInfo>>();
+ Map<String, List<MyPermissionInfo> > normalMap =
+ new HashMap<String, List<MyPermissionInfo>>();
PermissionInfoComparator permComparator = new PermissionInfoComparator(mPm);
if (permList != null) {
// First pass to group permissions
- for (PermissionInfo pInfo : permList) {
+ for (MyPermissionInfo pInfo : permList) {
if(localLOGV) Log.i(TAG, "Processing permission:"+pInfo.name);
- if(!isDisplayablePermission(pInfo)) {
+ if(!isDisplayablePermission(pInfo, pInfo.mNewReqFlags, pInfo.mExistingReqFlags)) {
if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" is not displayable");
continue;
}
- Map<String, List<PermissionInfo> > permInfoMap =
- (pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) ?
- dangerousMap : normalMap;
+ Map<String, List<MyPermissionInfo> > permInfoMap;
+ if (pInfo.mNew) {
+ permInfoMap = newMap;
+ } else if ((pInfo.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
+ == PermissionInfo.PROTECTION_DANGEROUS) {
+ permInfoMap = dangerousMap;
+ } else {
+ permInfoMap = normalMap;
+ }
String grpName = (pInfo.group == null) ? mDefaultGrpName : pInfo.group;
if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" belongs to group:"+grpName);
- List<PermissionInfo> grpPermsList = permInfoMap.get(grpName);
+ List<MyPermissionInfo> grpPermsList = permInfoMap.get(grpName);
if(grpPermsList == null) {
- grpPermsList = new ArrayList<PermissionInfo>();
+ grpPermsList = new ArrayList<MyPermissionInfo>();
permInfoMap.put(grpName, grpPermsList);
grpPermsList.add(pInfo);
} else {
@@ -477,12 +610,13 @@ public class AppSecurityPermissions implements View.OnClickListener {
}
// Second pass to actually form the descriptions
// Look at dangerous permissions first
- aggregateGroupDescs(dangerousMap, mDangerousMap);
- aggregateGroupDescs(normalMap, mNormalMap);
+ aggregateGroupDescs(newMap, mNewMap, true);
+ aggregateGroupDescs(dangerousMap, mDangerousMap, false);
+ aggregateGroupDescs(normalMap, mNormalMap, false);
}
mCurrentState = State.NO_PERMS;
- if(mDangerousMap.size() > 0) {
+ if (mNewMap.size() > 0 || mDangerousMap.size() > 0) {
mCurrentState = (mNormalMap.size() > 0) ? State.BOTH : State.DANGEROUS_ONLY;
} else if(mNormalMap.size() > 0) {
mCurrentState = State.NORMAL_ONLY;
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index ecf19b3ee226..2cacbdcac31a 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -282,6 +282,13 @@ public class Spinner extends AbsSpinner implements OnClickListener {
throw new RuntimeException("setOnItemClickListener cannot be used with a spinner.");
}
+ /**
+ * @hide internal use only
+ */
+ public void setOnItemClickListenerInt(OnItemClickListener l) {
+ super.setOnItemClickListener(l);
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -707,6 +714,9 @@ public class Spinner extends AbsSpinner implements OnClickListener {
public void onClick(DialogInterface dialog, int which) {
setSelection(which);
+ if (mOnItemClickListener != null) {
+ performItemClick(null, which, mListAdapter.getItemId(which));
+ }
dismiss();
}
}
@@ -724,6 +734,9 @@ public class Spinner extends AbsSpinner implements OnClickListener {
setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
Spinner.this.setSelection(position);
+ if (mOnItemClickListener != null) {
+ Spinner.this.performItemClick(null, position, mAdapter.getItemId(position));
+ }
dismiss();
}
});
diff --git a/core/java/android/widget/TableLayout.java b/core/java/android/widget/TableLayout.java
index f5d374656d89..b870ceeac4de 100644
--- a/core/java/android/widget/TableLayout.java
+++ b/core/java/android/widget/TableLayout.java
@@ -735,8 +735,7 @@ public class TableLayout extends LinearLayout {
* @param heightAttr the height attribute to fetch
*/
@Override
- protected void setBaseAttributes(TypedArray a,
- int widthAttr, int heightAttr) {
+ protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) {
this.width = MATCH_PARENT;
if (a.hasValue(heightAttr)) {
this.height = a.getLayoutDimension(heightAttr, "layout_height");
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f66da2959b42..f384dc1c0467 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -232,25 +232,72 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
static final String LOG_TAG = "TextView";
static final boolean DEBUG_EXTRACT = false;
- private static final int PRIORITY = 100;
- private int mCurrentAlpha = 255;
+ // Enum for the "typeface" XML parameter.
+ // TODO: How can we get this from the XML instead of hardcoding it here?
+ private static final int SANS = 1;
+ private static final int SERIF = 2;
+ private static final int MONOSPACE = 3;
- final int[] mTempCoords = new int[2];
- Rect mTempRect;
+ // Bitfield for the "numeric" XML parameter.
+ // TODO: How can we get this from the XML instead of hardcoding it here?
+ private static final int SIGNED = 2;
+ private static final int DECIMAL = 4;
+
+ private static enum TEXT_ALIGN {
+ INHERIT, GRAVITY, TEXT_START, TEXT_END, CENTER, VIEW_START, VIEW_END;
+ }
+
+ /**
+ * Draw marquee text with fading edges as usual
+ */
+ private static final int MARQUEE_FADE_NORMAL = 0;
+
+ /**
+ * Draw marquee text as ellipsize end while inactive instead of with the fade.
+ * (Useful for devices where the fade can be expensive if overdone)
+ */
+ private static final int MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS = 1;
+
+ /**
+ * Draw marquee text with fading edges because it is currently active/animating.
+ */
+ private static final int MARQUEE_FADE_SWITCH_SHOW_FADE = 2;
+
+ private static final int LINES = 1;
+ private static final int EMS = LINES;
+ private static final int PIXELS = 2;
+
+ private static final RectF TEMP_RECTF = new RectF();
+ private static final float[] TEMP_POSITION = new float[2];
+
+ // XXX should be much larger
+ private static final int VERY_WIDE = 1024*1024;
+ private static final int BLINK = 500;
+ private static final int ANIMATED_SCROLL_GAP = 250;
+
+ private static final InputFilter[] NO_FILTERS = new InputFilter[0];
+ private static final Spanned EMPTY_SPANNED = new SpannedString("");
+
+ private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
+ private static final int CHANGE_WATCHER_PRIORITY = 100;
+
+ // New state used to change background based on whether this TextView is multiline.
+ private static final int[] MULTILINE_STATE_SET = { R.attr.state_multiline };
+
+ // System wide time for last cut or copy action.
+ private static long LAST_CUT_OR_COPY_TIME;
+
+ private int mCurrentAlpha = 255;
private ColorStateList mTextColor;
- private int mCurTextColor;
private ColorStateList mHintTextColor;
private ColorStateList mLinkTextColor;
+ private int mCurTextColor;
private int mCurHintTextColor;
private boolean mFreezesText;
- private boolean mFrozenWithFocus;
private boolean mTemporaryDetach;
private boolean mDispatchTemporaryDetach;
- private boolean mDiscardNextActionUp = false;
- private boolean mIgnoreActionUpEvent = false;
-
private Editable.Factory mEditableFactory = Editable.Factory.getInstance();
private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance();
@@ -258,18 +305,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private boolean mPreDrawRegistered;
- private TextUtils.TruncateAt mEllipsize = null;
-
- // Enum for the "typeface" XML parameter.
- // TODO: How can we get this from the XML instead of hardcoding it here?
- private static final int SANS = 1;
- private static final int SERIF = 2;
- private static final int MONOSPACE = 3;
-
- // Bitfield for the "numeric" XML parameter.
- // TODO: How can we get this from the XML instead of hardcoding it here?
- private static final int SIGNED = 2;
- private static final int DECIMAL = 4;
+ private TextUtils.TruncateAt mEllipsize;
static class Drawables {
final Rect mCompoundRect = new Rect();
@@ -283,96 +319,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private Drawables mDrawables;
- private DisplayList mTextDisplayList;
- private boolean mTextDisplayListIsValid;
-
- private CharSequence mError;
- private boolean mErrorWasChanged;
- private ErrorPopup mPopup;
- /**
- * This flag is set if the TextView tries to display an error before it
- * is attached to the window (so its position is still unknown).
- * It causes the error to be shown later, when onAttachedToWindow()
- * is called.
- */
- private boolean mShowErrorAfterAttach;
-
- private CharWrapper mCharWrapper = null;
-
- private boolean mSelectionMoved = false;
- private boolean mTouchFocusSelected = false;
+ private CharWrapper mCharWrapper;
private Marquee mMarquee;
private boolean mRestartMarquee;
private int mMarqueeRepeatLimit = 3;
- static class InputContentType {
- int imeOptions = EditorInfo.IME_NULL;
- String privateImeOptions;
- CharSequence imeActionLabel;
- int imeActionId;
- Bundle extras;
- OnEditorActionListener onEditorActionListener;
- boolean enterDown;
- }
- InputContentType mInputContentType;
-
- static class InputMethodState {
- Rect mCursorRectInWindow = new Rect();
- RectF mTmpRectF = new RectF();
- float[] mTmpOffset = new float[2];
- ExtractedTextRequest mExtracting;
- final ExtractedText mTmpExtracted = new ExtractedText();
- int mBatchEditNesting;
- boolean mCursorChanged;
- boolean mSelectionModeChanged;
- boolean mContentChanged;
- int mChangedStart, mChangedEnd, mChangedDelta;
- }
- InputMethodState mInputMethodState;
-
- private int mTextSelectHandleLeftRes;
- private int mTextSelectHandleRightRes;
- private int mTextSelectHandleRes;
-
- private int mTextEditSuggestionItemLayout;
- private SuggestionsPopupWindow mSuggestionsPopupWindow;
- private SuggestionRangeSpan mSuggestionRangeSpan;
- private Runnable mShowSuggestionRunnable;
-
- private int mCursorDrawableRes;
- private final Drawable[] mCursorDrawable = new Drawable[2];
- private int mCursorCount; // Actual current number of used mCursorDrawable: 0, 1 or 2 (split)
-
- private Drawable mSelectHandleLeft;
- private Drawable mSelectHandleRight;
- private Drawable mSelectHandleCenter;
-
- // Global listener that detects changes in the global position of the TextView
- private PositionListener mPositionListener;
-
- private float mLastDownPositionX, mLastDownPositionY;
- private Callback mCustomSelectionActionModeCallback;
-
- // Set when this TextView gained focus with some text selected. Will start selection mode.
- private boolean mCreatedWithASelection = false;
-
- private WordIterator mWordIterator;
-
- private SpellChecker mSpellChecker;
-
// The alignment to pass to Layout, or null if not resolved.
private Layout.Alignment mLayoutAlignment;
// The default value for mTextAlign.
- private TextAlign mTextAlign = TextAlign.INHERIT;
-
- private static enum TextAlign {
- INHERIT, GRAVITY, TEXT_START, TEXT_END, CENTER, VIEW_START, VIEW_END;
- }
+ private TEXT_ALIGN mTextAlign = TEXT_ALIGN.INHERIT;
- private boolean mResolvedDrawables = false;
+ private boolean mResolvedDrawables;
/**
* On some devices the fading edges add a performance penalty if used
@@ -387,21 +347,90 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
private Layout mSavedMarqueeModeLayout;
- /**
- * Draw marquee text with fading edges as usual
- */
- private static final int MARQUEE_FADE_NORMAL = 0;
+ @ViewDebug.ExportedProperty(category = "text")
+ private CharSequence mText;
+ private CharSequence mTransformed;
+ private BufferType mBufferType = BufferType.NORMAL;
- /**
- * Draw marquee text as ellipsize end while inactive instead of with the fade.
- * (Useful for devices where the fade can be expensive if overdone)
- */
- private static final int MARQUEE_FADE_SWITCH_SHOW_ELLIPSIS = 1;
+ private CharSequence mHint;
+ private Layout mHintLayout;
+
+ private MovementMethod mMovement;
+
+ private TransformationMethod mTransformation;
+ private boolean mAllowTransformationLengthChange;
+ private ChangeWatcher mChangeWatcher;
+
+ private ArrayList<TextWatcher> mListeners;
+
+ // display attributes
+ private final TextPaint mTextPaint;
+ private boolean mUserSetTextScaleX;
+ private Layout mLayout;
+
+ private int mGravity = Gravity.TOP | Gravity.START;
+ private boolean mHorizontallyScrolling;
+
+ private int mAutoLinkMask;
+ private boolean mLinksClickable = true;
+
+ private float mSpacingMult = 1.0f;
+ private float mSpacingAdd = 0.0f;
+
+ private int mMaximum = Integer.MAX_VALUE;
+ private int mMaxMode = LINES;
+ private int mMinimum = 0;
+ private int mMinMode = LINES;
+
+ private int mOldMaximum = mMaximum;
+ private int mOldMaxMode = mMaxMode;
+
+ private int mMaxWidth = Integer.MAX_VALUE;
+ private int mMaxWidthMode = PIXELS;
+ private int mMinWidth = 0;
+ private int mMinWidthMode = PIXELS;
+
+ private boolean mSingleLine;
+ private int mDesiredHeightAtMeasure = -1;
+ private boolean mIncludePad = true;
+
+ // tmp primitives, so we don't alloc them on each draw
+ private Rect mTempRect;
+ private long mLastScroll;
+ private Scroller mScroller;
+
+ private BoringLayout.Metrics mBoring, mHintBoring;
+ private BoringLayout mSavedLayout, mSavedHintLayout;
+
+ private TextDirectionHeuristic mTextDir;
+
+ private InputFilter[] mFilters = NO_FILTERS;
+
+ // It is possible to have a selection even when mEditor is null (programmatically set, like when
+ // a link is pressed). These highlight-related fields do not go in mEditor.
+ private int mHighlightColor = 0x6633B5E5;
+ private Path mHighlightPath;
+ private final Paint mHighlightPaint;
+ private boolean mHighlightPathBogus = true;
+
+ // Although these fields are specific to editable text, they are not added to Editor because
+ // they are defined by the TextView's style and are theme-dependent.
+ private int mCursorDrawableRes;
+ // These four fields, could be moved to Editor, since we know their default values and we
+ // could condition the creation of the Editor to a non standard value. This is however
+ // brittle since the hardcoded values here (such as
+ // com.android.internal.R.drawable.text_select_handle_left) would have to be updated if the
+ // default style is modified.
+ private int mTextSelectHandleLeftRes;
+ private int mTextSelectHandleRightRes;
+ private int mTextSelectHandleRes;
+ private int mTextEditSuggestionItemLayout;
/**
- * Draw marquee text with fading edges because it is currently active/animating.
+ * EditText specific data, created on demand when one of the Editor fields is used.
+ * See {@link #createEditorIfNeeded(String)}.
*/
- private static final int MARQUEE_FADE_SWITCH_SHOW_FADE = 2;
+ private Editor mEditor;
/*
* Kick-start the font cache for the zygote process (to pay the cost of
@@ -454,14 +483,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTextPaint.density = res.getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling(compat.applicationScale);
- // If we get the paint from the skin, we should set it to left, since
- // the layout always wants it to be left.
- // mTextPaint.setTextAlign(Paint.Align.LEFT);
-
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
mMovement = getDefaultMovementMethod();
+
mTransformation = null;
int textColorHighlight = 0;
@@ -608,12 +634,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mLinksClickable = a.getBoolean(attr, true);
break;
-// TODO uncomment when this attribute is made public in the next release
-// also add TextView_showSoftInputOnFocus to the list of attributes above
-// case com.android.internal.R.styleable.TextView_showSoftInputOnFocus:
-// setShowSoftInputOnFocus(a.getBoolean(attr, true));
-// break;
-
case com.android.internal.R.styleable.TextView_drawableLeft:
drawableLeft = a.getDrawable(attr);
break;
@@ -805,30 +825,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextView_inputType:
- inputType = a.getInt(attr, mInputType);
+ inputType = a.getInt(attr, EditorInfo.TYPE_NULL);
break;
case com.android.internal.R.styleable.TextView_imeOptions:
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
+ createEditorIfNeeded("IME options specified in constructor");
+ if (getEditor().mInputContentType == null) {
+ getEditor().mInputContentType = new InputContentType();
}
- mInputContentType.imeOptions = a.getInt(attr,
- mInputContentType.imeOptions);
+ getEditor().mInputContentType.imeOptions = a.getInt(attr,
+ getEditor().mInputContentType.imeOptions);
break;
case com.android.internal.R.styleable.TextView_imeActionLabel:
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
+ createEditorIfNeeded("IME action label specified in constructor");
+ if (getEditor().mInputContentType == null) {
+ getEditor().mInputContentType = new InputContentType();
}
- mInputContentType.imeActionLabel = a.getText(attr);
+ getEditor().mInputContentType.imeActionLabel = a.getText(attr);
break;
case com.android.internal.R.styleable.TextView_imeActionId:
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
+ createEditorIfNeeded("IME action id specified in constructor");
+ if (getEditor().mInputContentType == null) {
+ getEditor().mInputContentType = new InputContentType();
}
- mInputContentType.imeActionId = a.getInt(attr,
- mInputContentType.imeActionId);
+ getEditor().mInputContentType.imeActionId = a.getInt(attr,
+ getEditor().mInputContentType.imeActionId);
break;
case com.android.internal.R.styleable.TextView_privateImeOptions:
@@ -866,7 +889,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextView_textIsSelectable:
- mTextIsSelectable = a.getBoolean(attr, false);
+ setTextIsSelectable(a.getBoolean(attr, false));
break;
case com.android.internal.R.styleable.TextView_textAllCaps:
@@ -897,35 +920,39 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
try {
- mInput = (KeyListener) c.newInstance();
+ createEditorIfNeeded("inputMethod in ctor");
+ getEditor().mKeyListener = (KeyListener) c.newInstance();
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
try {
- mInputType = inputType != EditorInfo.TYPE_NULL
+ getEditor().mInputType = inputType != EditorInfo.TYPE_NULL
? inputType
- : mInput.getInputType();
+ : getEditor().mKeyListener.getInputType();
} catch (IncompatibleClassChangeError e) {
- mInputType = EditorInfo.TYPE_CLASS_TEXT;
+ getEditor().mInputType = EditorInfo.TYPE_CLASS_TEXT;
}
} else if (digits != null) {
- mInput = DigitsKeyListener.getInstance(digits.toString());
+ createEditorIfNeeded("digits in ctor");
+ getEditor().mKeyListener = DigitsKeyListener.getInstance(digits.toString());
// If no input type was specified, we will default to generic
// text, since we can't tell the IME about the set of digits
// that was selected.
- mInputType = inputType != EditorInfo.TYPE_NULL
+ getEditor().mInputType = inputType != EditorInfo.TYPE_NULL
? inputType : EditorInfo.TYPE_CLASS_TEXT;
} else if (inputType != EditorInfo.TYPE_NULL) {
setInputType(inputType, true);
// If set, the input type overrides what was set using the deprecated singleLine flag.
singleLine = !isMultilineInputType(inputType);
} else if (phone) {
- mInput = DialerKeyListener.getInstance();
- mInputType = inputType = EditorInfo.TYPE_CLASS_PHONE;
+ createEditorIfNeeded("dialer in ctor");
+ getEditor().mKeyListener = DialerKeyListener.getInstance();
+ getEditor().mInputType = inputType = EditorInfo.TYPE_CLASS_PHONE;
} else if (numeric != 0) {
- mInput = DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
+ createEditorIfNeeded("numeric in ctor");
+ getEditor().mKeyListener = DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
(numeric & DECIMAL) != 0);
inputType = EditorInfo.TYPE_CLASS_NUMBER;
if ((numeric & SIGNED) != 0) {
@@ -934,7 +961,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if ((numeric & DECIMAL) != 0) {
inputType |= EditorInfo.TYPE_NUMBER_FLAG_DECIMAL;
}
- mInputType = inputType;
+ getEditor().mInputType = inputType;
} else if (autotext || autocap != -1) {
TextKeyListener.Capitalize cap;
@@ -961,22 +988,24 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
}
- mInput = TextKeyListener.getInstance(autotext, cap);
- mInputType = inputType;
- } else if (mTextIsSelectable) {
+ createEditorIfNeeded("text input in ctor");
+ getEditor().mKeyListener = TextKeyListener.getInstance(autotext, cap);
+ getEditor().mInputType = inputType;
+ } else if (isTextSelectable()) {
// Prevent text changes from keyboard.
- mInputType = EditorInfo.TYPE_NULL;
- mInput = null;
+ if (mEditor != null) {
+ getEditor().mKeyListener = null;
+ getEditor().mInputType = EditorInfo.TYPE_NULL;
+ }
bufferType = BufferType.SPANNABLE;
- // Required to request focus while in touch mode.
- setFocusableInTouchMode(true);
// So that selection can be changed using arrow keys and touch is handled.
setMovementMethod(ArrowKeyMovementMethod.getInstance());
} else if (editable) {
- mInput = TextKeyListener.getInstance();
- mInputType = EditorInfo.TYPE_CLASS_TEXT;
+ createEditorIfNeeded("editable input in ctor");
+ getEditor().mKeyListener = TextKeyListener.getInstance();
+ getEditor().mInputType = EditorInfo.TYPE_CLASS_TEXT;
} else {
- mInput = null;
+ if (mEditor != null) getEditor().mKeyListener = null;
switch (buffertype) {
case 0:
@@ -991,27 +1020,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- // mInputType has been set from inputType, possibly modified by mInputMethod.
- // Specialize mInputType to [web]password if we have a text class and the original input
- // type was a password.
- if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
- if (password || passwordInputType) {
- mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
- | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
- }
- if (webPasswordInputType) {
- mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
- | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
- }
- } else if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_NUMBER) {
- if (numberPasswordInputType) {
- mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
- | EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD;
- }
- }
+ if (mEditor != null) getEditor().adjustInputType(password, passwordInputType, webPasswordInputType,
+ numberPasswordInputType);
if (selectallonfocus) {
- mSelectAllOnFocus = true;
+ createEditorIfNeeded("selectallonfocus in constructor");
+ getEditor().mSelectAllOnFocus = true;
if (bufferType == BufferType.NORMAL)
bufferType = BufferType.SPANNABLE;
@@ -1027,7 +1041,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
setInputTypeSingleLine(singleLine);
applySingleLine(singleLine, singleLine, singleLine);
- if (singleLine && mInput == null && ellipsize < 0) {
+ if (singleLine && getKeyListener() == null && ellipsize < 0) {
ellipsize = 3; // END
}
@@ -1068,7 +1082,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (password || passwordInputType || webPasswordInputType || numberPasswordInputType) {
setTransformationMethod(PasswordTransformationMethod.getInstance());
typefaceIndex = MONOSPACE;
- } else if ((mInputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))
+ } else if (mEditor != null && (getEditor().mInputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))
== (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
typefaceIndex = MONOSPACE;
}
@@ -1097,7 +1111,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
com.android.internal.R.styleable.View,
defStyle, 0);
- boolean focusable = mMovement != null || mInput != null;
+ boolean focusable = mMovement != null || getKeyListener() != null;
boolean clickable = focusable;
boolean longClickable = focusable;
@@ -1205,7 +1219,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (imm != null) imm.restartInput(this);
}
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
prepareCursorControllers();
// start or stop the cursor blinking as appropriate
@@ -1310,7 +1324,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* This will frequently be null for non-EditText TextViews.
*/
public final KeyListener getKeyListener() {
- return mInput;
+ return mEditor == null ? null : getEditor().mKeyListener;
}
/**
@@ -1340,16 +1354,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
fixFocusableAndClickableSettings();
if (input != null) {
+ createEditorIfNeeded("input is not null");
try {
- mInputType = mInput.getInputType();
+ getEditor().mInputType = getEditor().mKeyListener.getInputType();
} catch (IncompatibleClassChangeError e) {
- mInputType = EditorInfo.TYPE_CLASS_TEXT;
+ getEditor().mInputType = EditorInfo.TYPE_CLASS_TEXT;
}
// Change inputType, without affecting transformation.
// No need to applySingleLine since mSingleLine is unchanged.
setInputTypeSingleLine(mSingleLine);
} else {
- mInputType = EditorInfo.TYPE_NULL;
+ if (mEditor != null) getEditor().mInputType = EditorInfo.TYPE_NULL;
}
InputMethodManager imm = InputMethodManager.peekInstance();
@@ -1357,11 +1372,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void setKeyListenerOnly(KeyListener input) {
- mInput = input;
- if (mInput != null && !(mText instanceof Editable))
- setText(mText);
+ if (mEditor == null && input == null) return; // null is the default value
+
+ createEditorIfNeeded("setKeyListenerOnly");
+ if (getEditor().mKeyListener != input) {
+ getEditor().mKeyListener = input;
+ if (input != null && !(mText instanceof Editable)) {
+ setText(mText);
+ }
- setFilters((Editable) mText, mFilters);
+ setFilters((Editable) mText, mFilters);
+ }
}
/**
@@ -1384,19 +1405,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* back the way you want it.
*/
public final void setMovementMethod(MovementMethod movement) {
- mMovement = movement;
+ if (mMovement != movement) {
+ mMovement = movement;
- if (mMovement != null && !(mText instanceof Spannable))
- setText(mText);
+ if (movement != null && !(mText instanceof Spannable)) {
+ setText(mText);
+ }
- fixFocusableAndClickableSettings();
+ fixFocusableAndClickableSettings();
- // SelectionModifierCursorController depends on textCanBeSelected, which depends on mMovement
- prepareCursorControllers();
+ // SelectionModifierCursorController depends on textCanBeSelected, which depends on mMovement
+ prepareCursorControllers();
+ }
}
private void fixFocusableAndClickableSettings() {
- if ((mMovement != null) || mInput != null) {
+ if (mMovement != null || (mEditor != null && getEditor().mKeyListener != null)) {
setFocusable(true);
setClickable(true);
setLongClickable(true);
@@ -1439,7 +1463,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (method instanceof TransformationMethod2) {
TransformationMethod2 method2 = (TransformationMethod2) method;
- mAllowTransformationLengthChange = !mTextIsSelectable && !(mText instanceof Editable);
+ mAllowTransformationLengthChange = !isTextSelectable() && !(mText instanceof Editable);
method2.setLengthChangesAllowed(mAllowTransformationLengthChange);
} else {
mAllowTransformationLengthChange = false;
@@ -2311,7 +2335,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void setHighlightColor(int color) {
if (mHighlightColor != color) {
mHighlightColor = color;
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
invalidate();
}
}
@@ -2332,7 +2356,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mShadowDx = dx;
mShadowDy = dy;
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
invalidate();
}
@@ -2824,7 +2848,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
if (inval) {
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
invalidate();
}
}
@@ -2862,73 +2886,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- /**
- * User interface state that is stored by TextView for implementing
- * {@link View#onSaveInstanceState}.
- */
- public static class SavedState extends BaseSavedState {
- int selStart;
- int selEnd;
- CharSequence text;
- boolean frozenWithFocus;
- CharSequence error;
-
- SavedState(Parcelable superState) {
- super(superState);
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- super.writeToParcel(out, flags);
- out.writeInt(selStart);
- out.writeInt(selEnd);
- out.writeInt(frozenWithFocus ? 1 : 0);
- TextUtils.writeToParcel(text, out, flags);
-
- if (error == null) {
- out.writeInt(0);
- } else {
- out.writeInt(1);
- TextUtils.writeToParcel(error, out, flags);
- }
- }
-
- @Override
- public String toString() {
- String str = "TextView.SavedState{"
- + Integer.toHexString(System.identityHashCode(this))
- + " start=" + selStart + " end=" + selEnd;
- if (text != null) {
- str += " text=" + text;
- }
- return str + "}";
- }
-
- @SuppressWarnings("hiding")
- 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];
- }
- };
-
- private SavedState(Parcel in) {
- super(in);
- selStart = in.readInt();
- selEnd = in.readInt();
- frozenWithFocus = (in.readInt() != 0);
- text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
-
- if (in.readInt() != 0) {
- error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- }
- }
- }
-
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
@@ -2968,8 +2925,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
sp.removeSpan(cw);
}
- removeMisspelledSpans(sp);
- sp.removeSpan(mSuggestionRangeSpan);
+ if (mEditor != null) {
+ removeMisspelledSpans(sp);
+ sp.removeSpan(getEditor().mSuggestionRangeSpan);
+ }
ss.text = sp;
} else {
@@ -2980,7 +2939,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
ss.frozenWithFocus = true;
}
- ss.error = mError;
+ ss.error = getError();
return ss;
}
@@ -3030,11 +2989,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
"/" + ss.selEnd + " out of range for " + restored +
"text " + mText);
} else {
- Selection.setSelection((Spannable) mText, ss.selStart,
- ss.selEnd);
+ Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd);
if (ss.frozenWithFocus) {
- mFrozenWithFocus = true;
+ createEditorIfNeeded("restore instance with focus");
+ getEditor().mFrozenWithFocus = true;
}
}
}
@@ -3192,7 +3151,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
needEditableForNotification = true;
}
- if (type == BufferType.EDITABLE || mInput != null || needEditableForNotification) {
+ if (type == BufferType.EDITABLE || getKeyListener() != null || needEditableForNotification) {
+ createEditorIfNeeded("setText with BufferType.EDITABLE or non null mInput");
Editable t = mEditableFactory.newEditable(text);
text = t;
setFilters(t, mFilters);
@@ -3257,10 +3217,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mChangeWatcher = new ChangeWatcher();
sp.setSpan(mChangeWatcher, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE |
- (PRIORITY << Spanned.SPAN_PRIORITY_SHIFT));
+ (CHANGE_WATCHER_PRIORITY << Spanned.SPAN_PRIORITY_SHIFT));
- if (mInput != null) {
- sp.setSpan(mInput, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ if (mEditor != null && getEditor().mKeyListener != null) {
+ sp.setSpan(getEditor().mKeyListener, 0, textLength, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
if (mTransformation != null) {
@@ -3275,7 +3235,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* selection, so reset mSelectionMoved to keep that from
* interfering with the normal on-focus selection-setting.
*/
- mSelectionMoved = false;
+ if (mEditor != null) getEditor().mSelectionMoved = false;
}
}
@@ -3329,100 +3289,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
setText(mCharWrapper, mBufferType, false, oldlen);
}
- private static class CharWrapper implements CharSequence, GetChars, GraphicsOperations {
- private char[] mChars;
- private int mStart, mLength;
-
- public CharWrapper(char[] chars, int start, int len) {
- mChars = chars;
- mStart = start;
- mLength = len;
- }
-
- /* package */ void set(char[] chars, int start, int len) {
- mChars = chars;
- mStart = start;
- mLength = len;
- }
-
- public int length() {
- return mLength;
- }
-
- public char charAt(int off) {
- return mChars[off + mStart];
- }
-
- @Override
- public String toString() {
- return new String(mChars, mStart, mLength);
- }
-
- public CharSequence subSequence(int start, int end) {
- if (start < 0 || end < 0 || start > mLength || end > mLength) {
- throw new IndexOutOfBoundsException(start + ", " + end);
- }
-
- return new String(mChars, start + mStart, end - start);
- }
-
- public void getChars(int start, int end, char[] buf, int off) {
- if (start < 0 || end < 0 || start > mLength || end > mLength) {
- throw new IndexOutOfBoundsException(start + ", " + end);
- }
-
- System.arraycopy(mChars, start + mStart, buf, off, end - start);
- }
-
- public void drawText(Canvas c, int start, int end,
- float x, float y, Paint p) {
- c.drawText(mChars, start + mStart, end - start, x, y, p);
- }
-
- public void drawTextRun(Canvas c, int start, int end,
- int contextStart, int contextEnd, float x, float y, int flags, Paint p) {
- int count = end - start;
- int contextCount = contextEnd - contextStart;
- c.drawTextRun(mChars, start + mStart, count, contextStart + mStart,
- contextCount, x, y, flags, p);
- }
-
- public float measureText(int start, int end, Paint p) {
- return p.measureText(mChars, start + mStart, end - start);
- }
-
- public int getTextWidths(int start, int end, float[] widths, Paint p) {
- return p.getTextWidths(mChars, start + mStart, end - start, widths);
- }
-
- public float getTextRunAdvances(int start, int end, int contextStart,
- int contextEnd, int flags, float[] advances, int advancesIndex,
- Paint p) {
- int count = end - start;
- int contextCount = contextEnd - contextStart;
- return p.getTextRunAdvances(mChars, start + mStart, count,
- contextStart + mStart, contextCount, flags, advances,
- advancesIndex);
- }
-
- public float getTextRunAdvances(int start, int end, int contextStart,
- int contextEnd, int flags, float[] advances, int advancesIndex,
- Paint p, int reserved) {
- int count = end - start;
- int contextCount = contextEnd - contextStart;
- return p.getTextRunAdvances(mChars, start + mStart, count,
- contextStart + mStart, contextCount, flags, advances,
- advancesIndex, reserved);
- }
-
- public int getTextRunCursor(int contextStart, int contextEnd, int flags,
- int offset, int cursorOpt, Paint p) {
- int contextCount = contextEnd - contextStart;
- return p.getTextRunCursor(mChars, contextStart + mStart,
- contextCount, flags, offset + mStart, cursorOpt);
- }
- }
-
/**
* Like {@link #setText(CharSequence, android.widget.TextView.BufferType)},
* except that the cursor position (if any) is retained in the new text.
@@ -3474,7 +3340,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// Invalidate display list if hint will be used
- if (mText.length() == 0 && mHint != null) mTextDisplayListIsValid = false;
+ if (mEditor != null && mText.length() == 0 && mHint != null) {
+ getEditor().mTextDisplayListIsValid = false;
+ }
}
/**
@@ -3520,8 +3388,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_inputType
*/
public void setInputType(int type) {
- final boolean wasPassword = isPasswordInputType(mInputType);
- final boolean wasVisiblePassword = isVisiblePasswordInputType(mInputType);
+ final boolean wasPassword = isPasswordInputType(getInputType());
+ final boolean wasVisiblePassword = isVisiblePasswordInputType(getInputType());
setInputType(type, false);
final boolean isPassword = isPasswordInputType(type);
final boolean isVisiblePassword = isVisiblePasswordInputType(type);
@@ -3605,7 +3473,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_inputType
*/
public void setRawInputType(int type) {
- mInputType = type;
+ if (type == InputType.TYPE_NULL && mEditor == null) return; //TYPE_NULL is the default value
+ createEditorIfNeeded("non null input type");
+ getEditor().mInputType = type;
}
private void setInputType(int type, boolean direct) {
@@ -3646,20 +3516,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
input = TextKeyListener.getInstance();
}
setRawInputType(type);
- if (direct) mInput = input;
- else {
+ if (direct) {
+ createEditorIfNeeded("setInputType");
+ getEditor().mKeyListener = input;
+ } else {
setKeyListenerOnly(input);
}
}
/**
- * Get the type of the content.
+ * Get the type of the editable content.
*
* @see #setInputType(int)
* @see android.text.InputType
*/
public int getInputType() {
- return mInputType;
+ return mEditor == null ? EditorInfo.TYPE_NULL : getEditor().mInputType;
}
/**
@@ -3671,10 +3543,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_imeOptions
*/
public void setImeOptions(int imeOptions) {
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
+ createEditorIfNeeded("IME options specified");
+ if (getEditor().mInputContentType == null) {
+ getEditor().mInputContentType = new InputContentType();
}
- mInputContentType.imeOptions = imeOptions;
+ getEditor().mInputContentType.imeOptions = imeOptions;
}
/**
@@ -3684,8 +3557,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see android.view.inputmethod.EditorInfo
*/
public int getImeOptions() {
- return mInputContentType != null
- ? mInputContentType.imeOptions : EditorInfo.IME_NULL;
+ return mEditor != null && getEditor().mInputContentType != null
+ ? getEditor().mInputContentType.imeOptions : EditorInfo.IME_NULL;
}
/**
@@ -3699,11 +3572,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_imeActionId
*/
public void setImeActionLabel(CharSequence label, int actionId) {
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
+ createEditorIfNeeded("IME action label specified");
+ if (getEditor().mInputContentType == null) {
+ getEditor().mInputContentType = new InputContentType();
}
- mInputContentType.imeActionLabel = label;
- mInputContentType.imeActionId = actionId;
+ getEditor().mInputContentType.imeActionLabel = label;
+ getEditor().mInputContentType.imeActionId = actionId;
}
/**
@@ -3713,8 +3587,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see android.view.inputmethod.EditorInfo
*/
public CharSequence getImeActionLabel() {
- return mInputContentType != null
- ? mInputContentType.imeActionLabel : null;
+ return mEditor != null && getEditor().mInputContentType != null
+ ? getEditor().mInputContentType.imeActionLabel : null;
}
/**
@@ -3724,8 +3598,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see android.view.inputmethod.EditorInfo
*/
public int getImeActionId() {
- return mInputContentType != null
- ? mInputContentType.imeActionId : 0;
+ return mEditor != null && getEditor().mInputContentType != null
+ ? getEditor().mInputContentType.imeActionId : 0;
}
/**
@@ -3737,12 +3611,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* modifier will, however, allow the user to insert a newline character.
*/
public void setOnEditorActionListener(OnEditorActionListener l) {
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
+ createEditorIfNeeded("Editor action listener set");
+ if (getEditor().mInputContentType == null) {
+ getEditor().mInputContentType = new InputContentType();
}
- mInputContentType.onEditorActionListener = l;
+ getEditor().mInputContentType.onEditorActionListener = l;
}
-
+
/**
* Called when an attached input method calls
* {@link InputConnection#performEditorAction(int)
@@ -3764,7 +3639,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see #setOnEditorActionListener
*/
public void onEditorAction(int actionCode) {
- final InputContentType ict = mInputContentType;
+ final InputContentType ict = mEditor == null ? null : getEditor().mInputContentType;
if (ict != null) {
if (ict.onEditorActionListener != null) {
if (ict.onEditorActionListener.onEditorAction(this,
@@ -3835,8 +3710,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_privateImeOptions
*/
public void setPrivateImeOptions(String type) {
- if (mInputContentType == null) mInputContentType = new InputContentType();
- mInputContentType.privateImeOptions = type;
+ createEditorIfNeeded("Private IME option set");
+ if (getEditor().mInputContentType == null)
+ getEditor().mInputContentType = new InputContentType();
+ getEditor().mInputContentType.privateImeOptions = type;
}
/**
@@ -3846,8 +3723,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see EditorInfo#privateImeOptions
*/
public String getPrivateImeOptions() {
- return mInputContentType != null
- ? mInputContentType.privateImeOptions : null;
+ return mEditor != null && getEditor().mInputContentType != null
+ ? getEditor().mInputContentType.privateImeOptions : null;
}
/**
@@ -3861,12 +3738,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @see EditorInfo#extras
* @attr ref android.R.styleable#TextView_editorExtras
*/
- public void setInputExtras(int xmlResId)
- throws XmlPullParserException, IOException {
+ public void setInputExtras(int xmlResId) throws XmlPullParserException, IOException {
+ createEditorIfNeeded("Input extra set");
XmlResourceParser parser = getResources().getXml(xmlResId);
- if (mInputContentType == null) mInputContentType = new InputContentType();
- mInputContentType.extras = new Bundle();
- getResources().parseBundleExtras(parser, mInputContentType.extras);
+ if (getEditor().mInputContentType == null)
+ getEditor().mInputContentType = new InputContentType();
+ getEditor().mInputContentType.extras = new Bundle();
+ getResources().parseBundleExtras(parser, getEditor().mInputContentType.extras);
}
/**
@@ -3880,15 +3758,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_editorExtras
*/
public Bundle getInputExtras(boolean create) {
- if (mInputContentType == null) {
+ if (mEditor == null && !create) return null;
+ createEditorIfNeeded("get Input extra");
+ if (getEditor().mInputContentType == null) {
if (!create) return null;
- mInputContentType = new InputContentType();
+ getEditor().mInputContentType = new InputContentType();
}
- if (mInputContentType.extras == null) {
+ if (getEditor().mInputContentType.extras == null) {
if (!create) return null;
- mInputContentType.extras = new Bundle();
+ getEditor().mInputContentType.extras = new Bundle();
}
- return mInputContentType.extras;
+ return getEditor().mInputContentType.extras;
}
/**
@@ -3897,7 +3777,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* or if it the error was cleared by the widget after user input.
*/
public CharSequence getError() {
- return mError;
+ return mEditor == null ? null : getEditor().mError;
}
/**
@@ -3931,10 +3811,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* be cleared (and you should provide a <code>null</code> icon as well).
*/
public void setError(CharSequence error, Drawable icon) {
+ createEditorIfNeeded("setError");
error = TextUtils.stringOrSpannedString(error);
- mError = error;
- mErrorWasChanged = true;
+ getEditor().mError = error;
+ getEditor().mErrorWasChanged = true;
final Drawables dr = mDrawables;
if (dr != null) {
switch (getResolvedLayoutDirection()) {
@@ -3953,12 +3834,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (error == null) {
- if (mPopup != null) {
- if (mPopup.isShowing()) {
- mPopup.dismiss();
+ if (getEditor().mErrorPopup != null) {
+ if (getEditor().mErrorPopup.isShowing()) {
+ getEditor().mErrorPopup.dismiss();
}
- mPopup = null;
+ getEditor().mErrorPopup = null;
}
} else {
if (isFocused()) {
@@ -3969,83 +3850,29 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void showError() {
if (getWindowToken() == null) {
- mShowErrorAfterAttach = true;
+ getEditor().mShowErrorAfterAttach = true;
return;
}
- if (mPopup == null) {
+ if (getEditor().mErrorPopup == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
final TextView err = (TextView) inflater.inflate(
com.android.internal.R.layout.textview_hint, null);
final float scale = getResources().getDisplayMetrics().density;
- mPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f), (int) (50 * scale + 0.5f));
- mPopup.setFocusable(false);
+ getEditor().mErrorPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f), (int) (50 * scale + 0.5f));
+ getEditor().mErrorPopup.setFocusable(false);
// The user is entering text, so the input method is needed. We
// don't want the popup to be displayed on top of it.
- mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
+ getEditor().mErrorPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
}
- TextView tv = (TextView) mPopup.getContentView();
- chooseSize(mPopup, mError, tv);
- tv.setText(mError);
+ TextView tv = (TextView) getEditor().mErrorPopup.getContentView();
+ chooseSize(getEditor().mErrorPopup, getEditor().mError, tv);
+ tv.setText(getEditor().mError);
- mPopup.showAsDropDown(this, getErrorX(), getErrorY());
- mPopup.fixDirection(mPopup.isAboveAnchor());
- }
-
- private static class ErrorPopup extends PopupWindow {
- private boolean mAbove = false;
- private final TextView mView;
- private int mPopupInlineErrorBackgroundId = 0;
- private int mPopupInlineErrorAboveBackgroundId = 0;
-
- ErrorPopup(TextView v, int width, int height) {
- super(v, width, height);
- mView = v;
- // Make sure the TextView has a background set as it will be used the first time it is
- // shown and positionned. Initialized with below background, which should have
- // dimensions identical to the above version for this to work (and is more likely).
- mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
- com.android.internal.R.styleable.Theme_errorMessageBackground);
- mView.setBackgroundResource(mPopupInlineErrorBackgroundId);
- }
-
- void fixDirection(boolean above) {
- mAbove = above;
-
- if (above) {
- mPopupInlineErrorAboveBackgroundId =
- getResourceId(mPopupInlineErrorAboveBackgroundId,
- com.android.internal.R.styleable.Theme_errorMessageAboveBackground);
- } else {
- mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
- com.android.internal.R.styleable.Theme_errorMessageBackground);
- }
-
- mView.setBackgroundResource(above ? mPopupInlineErrorAboveBackgroundId :
- mPopupInlineErrorBackgroundId);
- }
-
- private int getResourceId(int currentId, int index) {
- if (currentId == 0) {
- TypedArray styledAttributes = mView.getContext().obtainStyledAttributes(
- R.styleable.Theme);
- currentId = styledAttributes.getResourceId(index, 0);
- styledAttributes.recycle();
- }
- return currentId;
- }
-
- @Override
- public void update(int x, int y, int w, int h, boolean force) {
- super.update(x, y, w, h, force);
-
- boolean above = isAboveAnchor();
- if (above != mAbove) {
- fixDirection(above);
- }
- }
+ getEditor().mErrorPopup.showAsDropDown(this, getErrorX(), getErrorY());
+ getEditor().mErrorPopup.fixDirection(getEditor().mErrorPopup.isAboveAnchor());
}
/**
@@ -4060,7 +3887,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final float scale = getResources().getDisplayMetrics().density;
final Drawables dr = mDrawables;
- return getWidth() - mPopup.getWidth() - getPaddingRight() -
+ return getWidth() - getEditor().mErrorPopup.getWidth() - getPaddingRight() -
(dr != null ? dr.mDrawableSizeRight : 0) / 2 + (int) (25 * scale + 0.5f);
}
@@ -4090,13 +3917,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void hideError() {
- if (mPopup != null) {
- if (mPopup.isShowing()) {
- mPopup.dismiss();
+ if (getEditor().mErrorPopup != null) {
+ if (getEditor().mErrorPopup.isShowing()) {
+ getEditor().mErrorPopup.dismiss();
}
}
- mShowErrorAfterAttach = false;
+ getEditor().mShowErrorAfterAttach = false;
}
private void chooseSize(PopupWindow pop, CharSequence text, TextView tv) {
@@ -4125,12 +3952,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
protected boolean setFrame(int l, int t, int r, int b) {
boolean result = super.setFrame(l, t, r, b);
- if (mPopup != null) {
- TextView tv = (TextView) mPopup.getContentView();
- chooseSize(mPopup, mError, tv);
- mPopup.update(this, getErrorX(), getErrorY(),
- mPopup.getWidth(), mPopup.getHeight());
- }
+ if (mEditor != null) getEditor().setFrame();
restartMarqueeIfNeeded();
@@ -4146,7 +3968,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* Sets the list of input filters that will be used if the buffer is
- * Editable. Has no effect otherwise.
+ * Editable. Has no effect otherwise.
*
* @attr ref android.R.styleable#TextView_maxLength
*/
@@ -4167,11 +3989,11 @@ 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 (mInput instanceof InputFilter) {
+ if (mEditor != null && getEditor().mKeyListener instanceof InputFilter) {
InputFilter[] nf = new InputFilter[filters.length + 1];
System.arraycopy(filters, 0, nf, 0, filters.length);
- nf[filters.length] = (InputFilter) mInput;
+ nf[filters.length] = (InputFilter) getEditor().mKeyListener;
e.setFilters(nf);
} else {
@@ -4257,8 +4079,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int horizontalPadding = getCompoundPaddingLeft();
final int verticalPadding = getExtendedPaddingTop() + getVerticalOffset(true);
- if (mCursorCount == 0) {
- synchronized (sTempRect) {
+ if (getEditor().mCursorCount == 0) {
+ synchronized (TEMP_RECTF) {
/*
* The reason for this concern about the thickness of the
* cursor and doing the floor/ceil on the coordinates is that
@@ -4275,16 +4097,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
thick /= 2.0f;
- mHighlightPath.computeBounds(sTempRect, false);
+ // mHighlightPath is guaranteed to be non null at that point.
+ mHighlightPath.computeBounds(TEMP_RECTF, false);
- invalidate((int) FloatMath.floor(horizontalPadding + sTempRect.left - thick),
- (int) FloatMath.floor(verticalPadding + sTempRect.top - thick),
- (int) FloatMath.ceil(horizontalPadding + sTempRect.right + thick),
- (int) FloatMath.ceil(verticalPadding + sTempRect.bottom + thick));
+ invalidate((int) FloatMath.floor(horizontalPadding + TEMP_RECTF.left - thick),
+ (int) FloatMath.floor(verticalPadding + TEMP_RECTF.top - thick),
+ (int) FloatMath.ceil(horizontalPadding + TEMP_RECTF.right + thick),
+ (int) FloatMath.ceil(verticalPadding + TEMP_RECTF.bottom + thick));
}
} else {
- for (int i = 0; i < mCursorCount; i++) {
- Rect bounds = mCursorDrawable[i].getBounds();
+ for (int i = 0; i < getEditor().mCursorCount; i++) {
+ Rect bounds = getEditor().mCursorDrawable[i].getBounds();
invalidate(bounds.left + horizontalPadding, bounds.top + verticalPadding,
bounds.right + horizontalPadding, bounds.bottom + verticalPadding);
}
@@ -4337,9 +4160,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int bottom = mLayout.getLineBottom(lineEnd);
- if (invalidateCursor) {
- for (int i = 0; i < mCursorCount; i++) {
- Rect bounds = mCursorDrawable[i].getBounds();
+ // mEditor can be null in case selection is set programmatically.
+ if (invalidateCursor && mEditor != null) {
+ for (int i = 0; i < getEditor().mCursorCount; i++) {
+ Rect bounds = getEditor().mCursorDrawable[i].getBounds();
top = Math.min(top, bounds.top);
bottom = Math.max(bottom, bounds.bottom);
}
@@ -4389,8 +4213,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
int curs = getSelectionEnd();
// Do not create the controller if it is not already created.
- if (mSelectionModifierCursorController != null &&
- mSelectionModifierCursorController.isSelectionStartDragged()) {
+ if (mEditor != null && getEditor().mSelectionModifierCursorController != null &&
+ getEditor().mSelectionModifierCursorController.isSelectionStartDragged()) {
curs = getSelectionStart();
}
@@ -4399,8 +4223,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* it already was before the text changed. I'm not sure
* of a good way to tell from here if it was.
*/
- if (curs < 0 &&
- (mGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
+ if (curs < 0 && (mGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
curs = mText.length();
}
@@ -4414,9 +4237,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// This has to be checked here since:
// - onFocusChanged cannot start it when focus is given to a view with selected text (after
// a screen rotation) since layout is not yet initialized at that point.
- if (mCreatedWithASelection) {
+ if (mEditor != null && getEditor().mCreatedWithASelection) {
startSelectionActionMode();
- mCreatedWithASelection = false;
+ getEditor().mCreatedWithASelection = false;
}
// Phone specific code (there is no ExtractEditText on tablets).
@@ -4438,25 +4261,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTemporaryDetach = false;
- if (mShowErrorAfterAttach) {
+ if (mEditor != null && getEditor().mShowErrorAfterAttach) {
showError();
- mShowErrorAfterAttach = false;
- }
-
- final ViewTreeObserver observer = getViewTreeObserver();
- // No need to create the controller.
- // The get method will add the listener on controller creation.
- if (mInsertionPointCursorController != null) {
- observer.addOnTouchModeChangeListener(mInsertionPointCursorController);
- }
- if (mSelectionModifierCursorController != null) {
- observer.addOnTouchModeChangeListener(mSelectionModifierCursorController);
+ getEditor().mShowErrorAfterAttach = false;
}
// Resolve drawables as the layout direction has been resolved
resolveDrawables();
- updateSpellCheckSpans(0, mText.length(), true /* create the spell checker if needed */);
+ if (mEditor != null) getEditor().onAttachedToWindow();
}
@Override
@@ -4468,40 +4281,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mPreDrawRegistered = false;
}
- if (mError != null) {
- hideError();
- }
-
- if (mBlink != null) {
- mBlink.removeCallbacks(mBlink);
- }
-
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.onDetached();
- }
-
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.onDetached();
- }
-
- if (mShowSuggestionRunnable != null) {
- removeCallbacks(mShowSuggestionRunnable);
- }
-
- hideControllers();
-
resetResolvedDrawables();
- if (mTextDisplayList != null) {
- mTextDisplayList.invalidate();
- }
-
- if (mSpellChecker != null) {
- mSpellChecker.closeSession();
- // Forces the creation of a new SpellChecker next time this window is created.
- // Will handle the cases where the settings has been changed in the meantime.
- mSpellChecker = null;
- }
+ if (mEditor != null) getEditor().onDetachedFromWindow();
}
@Override
@@ -4648,13 +4430,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (dr.mDrawableStart != null) dr.mDrawableStart.mutate().setAlpha(alpha);
if (dr.mDrawableEnd != null) dr.mDrawableEnd.mutate().setAlpha(alpha);
}
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
}
return true;
}
if (mCurrentAlpha != 255) {
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
}
mCurrentAlpha = 255;
return false;
@@ -4678,12 +4460,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_textIsSelectable
*/
public boolean isTextSelectable() {
- return mTextIsSelectable;
+ return mEditor == null ? false : getEditor().mTextIsSelectable;
}
/**
* Sets whether or not (default) the content of this view is selectable by the user.
- *
+ *
* Note that this methods affect the {@link #setFocusable(boolean)},
* {@link #setFocusableInTouchMode(boolean)} {@link #setClickable(boolean)} and
* {@link #setLongClickable(boolean)} states and you may want to restore these if they were
@@ -4694,16 +4476,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @param selectable Whether or not the content of this TextView should be selectable.
*/
public void setTextIsSelectable(boolean selectable) {
- if (mTextIsSelectable == selectable) return;
+ if (!selectable && mEditor == null) return; // false is default value with no edit data
- mTextIsSelectable = selectable;
+ createEditorIfNeeded("setTextIsSelectable");
+ if (getEditor().mTextIsSelectable == selectable) return;
+ getEditor().mTextIsSelectable = selectable;
setFocusableInTouchMode(selectable);
setFocusable(selectable);
setClickable(selectable);
setLongClickable(selectable);
- // mInputType is already EditorInfo.TYPE_NULL and mInput is null;
+ // mInputType should already be EditorInfo.TYPE_NULL and mInput should be null
setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
setText(getText(), selectable ? BufferType.SPANNABLE : BufferType.NORMAL);
@@ -4723,7 +4507,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mergeDrawableStates(drawableState, MULTILINE_STATE_SET);
}
- if (mTextIsSelectable) {
+ if (isTextSelectable()) {
// Disable pressed state, which was introduced when TextView was made clickable.
// Prevents text color change.
// setClickable(false) would have a similar effect, but it also disables focus changes
@@ -4742,6 +4526,55 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return drawableState;
}
+ private Path getUpdatedHighlightPath() {
+ Path highlight = null;
+ Paint highlightPaint = mHighlightPaint;
+
+ final int selStart = getSelectionStart();
+ final int selEnd = getSelectionEnd();
+ if (mMovement != null && (isFocused() || isPressed()) && selStart >= 0) {
+ if (selStart == selEnd) {
+ if (mEditor != null && isCursorVisible() &&
+ (SystemClock.uptimeMillis() - getEditor().mShowCursor) % (2 * BLINK) < BLINK) {
+ if (mHighlightPathBogus) {
+ if (mHighlightPath == null) mHighlightPath = new Path();
+ mHighlightPath.reset();
+ mLayout.getCursorPath(selStart, mHighlightPath, mText);
+ getEditor().updateCursorsPositions();
+ mHighlightPathBogus = false;
+ }
+
+ // XXX should pass to skin instead of drawing directly
+ highlightPaint.setColor(mCurTextColor);
+ if (mCurrentAlpha != 255) {
+ highlightPaint.setAlpha(
+ (mCurrentAlpha * Color.alpha(mCurTextColor)) / 255);
+ }
+ highlightPaint.setStyle(Paint.Style.STROKE);
+ highlight = mHighlightPath;
+ }
+ } else {
+ if (mHighlightPathBogus) {
+ if (mHighlightPath == null) mHighlightPath = new Path();
+ mHighlightPath.reset();
+ mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
+ mHighlightPathBogus = false;
+ }
+
+ // XXX should pass to skin instead of drawing directly
+ highlightPaint.setColor(mHighlightColor);
+ if (mCurrentAlpha != 255) {
+ highlightPaint.setAlpha(
+ (mCurrentAlpha * Color.alpha(mHighlightColor)) / 255);
+ }
+ highlightPaint.setStyle(Paint.Style.FILL);
+
+ highlight = mHighlightPath;
+ }
+ }
+ return highlight;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
@@ -4822,7 +4655,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
Layout layout = mLayout;
- int cursorcolor = color;
if (mHint != null && mText.length() == 0) {
if (mHintTextColor != null) {
@@ -4870,14 +4702,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int voffsetCursor = 0;
// translate in by our padding
- {
- /* shortcircuit calling getVerticaOffset() */
- if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
- voffsetText = getVerticalOffset(false);
- voffsetCursor = getVerticalOffset(true);
- }
- canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);
+ /* shortcircuit calling getVerticaOffset() */
+ if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) {
+ voffsetText = getVerticalOffset(false);
+ voffsetCursor = getVerticalOffset(true);
}
+ canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);
final int layoutDirection = getResolvedLayoutDirection();
final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
@@ -4894,208 +4724,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- Path highlight = null;
- int selStart = -1, selEnd = -1;
- boolean drawCursor = false;
-
- // If there is no movement method, then there can be no selection.
- // Check that first and attempt to skip everything having to do with
- // the cursor.
- // XXX This is not strictly true -- a program could set the
- // selection manually if it really wanted to.
- if (mMovement != null && (isFocused() || isPressed())) {
- selStart = getSelectionStart();
- selEnd = getSelectionEnd();
-
- if (selStart >= 0) {
- if (mHighlightPath == null) mHighlightPath = new Path();
-
- if (selStart == selEnd) {
- if (isCursorVisible() &&
- (SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
- if (mHighlightPathBogus) {
- mHighlightPath.reset();
- mLayout.getCursorPath(selStart, mHighlightPath, mText);
- updateCursorsPositions();
- mHighlightPathBogus = false;
- }
-
- // XXX should pass to skin instead of drawing directly
- mHighlightPaint.setColor(cursorcolor);
- if (mCurrentAlpha != 255) {
- mHighlightPaint.setAlpha(
- (mCurrentAlpha * Color.alpha(cursorcolor)) / 255);
- }
- mHighlightPaint.setStyle(Paint.Style.STROKE);
- highlight = mHighlightPath;
- drawCursor = mCursorCount > 0;
- }
- } else if (textCanBeSelected()) {
- if (mHighlightPathBogus) {
- mHighlightPath.reset();
- mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
- mHighlightPathBogus = false;
- }
-
- // XXX should pass to skin instead of drawing directly
- mHighlightPaint.setColor(mHighlightColor);
- if (mCurrentAlpha != 255) {
- mHighlightPaint.setAlpha(
- (mCurrentAlpha * Color.alpha(mHighlightColor)) / 255);
- }
- mHighlightPaint.setStyle(Paint.Style.FILL);
-
- highlight = mHighlightPath;
- }
- }
- }
-
- final InputMethodState ims = mInputMethodState;
final int cursorOffsetVertical = voffsetCursor - voffsetText;
- if (ims != null && ims.mBatchEditNesting == 0) {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- if (imm.isActive(this)) {
- boolean reported = false;
- if (ims.mContentChanged || ims.mSelectionModeChanged) {
- // We are in extract mode and the content has changed
- // in some way... just report complete new text to the
- // input method.
- reported = reportExtractedText();
- }
- if (!reported && highlight != null) {
- int candStart = -1;
- int candEnd = -1;
- if (mText instanceof Spannable) {
- Spannable sp = (Spannable)mText;
- candStart = EditableInputConnection.getComposingSpanStart(sp);
- candEnd = EditableInputConnection.getComposingSpanEnd(sp);
- }
- imm.updateSelection(this, selStart, selEnd, candStart, candEnd);
- }
- }
-
- if (imm.isWatchingCursor(this) && highlight != null) {
- highlight.computeBounds(ims.mTmpRectF, true);
- ims.mTmpOffset[0] = ims.mTmpOffset[1] = 0;
-
- canvas.getMatrix().mapPoints(ims.mTmpOffset);
- ims.mTmpRectF.offset(ims.mTmpOffset[0], ims.mTmpOffset[1]);
-
- ims.mTmpRectF.offset(0, cursorOffsetVertical);
-
- ims.mCursorRectInWindow.set((int)(ims.mTmpRectF.left + 0.5),
- (int)(ims.mTmpRectF.top + 0.5),
- (int)(ims.mTmpRectF.right + 0.5),
- (int)(ims.mTmpRectF.bottom + 0.5));
-
- imm.updateCursor(this,
- ims.mCursorRectInWindow.left, ims.mCursorRectInWindow.top,
- ims.mCursorRectInWindow.right, ims.mCursorRectInWindow.bottom);
- }
- }
- }
-
- if (mCorrectionHighlighter != null) {
- mCorrectionHighlighter.draw(canvas, cursorOffsetVertical);
- }
-
- if (drawCursor) {
- drawCursor(canvas, cursorOffsetVertical);
- // Rely on the drawable entirely, do not draw the cursor line.
- // Has to be done after the IMM related code above which relies on the highlight.
- highlight = null;
- }
-
- if (canHaveDisplayList() && canvas.isHardwareAccelerated()) {
- final int width = mRight - mLeft;
- final int height = mBottom - mTop;
-
- if (mTextDisplayList == null || !mTextDisplayList.isValid() ||
- !mTextDisplayListIsValid) {
- if (mTextDisplayList == null) {
- mTextDisplayList = getHardwareRenderer().createDisplayList("Text");
- }
- final HardwareCanvas hardwareCanvas = mTextDisplayList.start();
- try {
- hardwareCanvas.setViewport(width, height);
- // The dirty rect should always be null for a display list
- hardwareCanvas.onPreDraw(null);
- hardwareCanvas.translate(-mScrollX, -mScrollY);
- layout.draw(hardwareCanvas, highlight, mHighlightPaint, cursorOffsetVertical);
- hardwareCanvas.translate(mScrollX, mScrollY);
- } finally {
- hardwareCanvas.onPostDraw();
- mTextDisplayList.end();
- mTextDisplayListIsValid = true;
- }
- }
- canvas.translate(mScrollX, mScrollY);
- ((HardwareCanvas) canvas).drawDisplayList(mTextDisplayList, width, height, null,
- DisplayList.FLAG_CLIP_CHILDREN);
- canvas.translate(-mScrollX, -mScrollY);
+ Path highlight = getUpdatedHighlightPath();
+ if (mEditor != null) {
+ getEditor().onDraw(canvas, layout, highlight, cursorOffsetVertical);
} else {
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
- }
- if (mMarquee != null && mMarquee.shouldDrawGhost()) {
- canvas.translate((int) mMarquee.getGhostOffset(), 0.0f);
- layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
+ if (mMarquee != null && mMarquee.shouldDrawGhost()) {
+ canvas.translate((int) mMarquee.getGhostOffset(), 0.0f);
+ layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
+ }
}
canvas.restore();
}
- private void updateCursorsPositions() {
- if (mCursorDrawableRes == 0) {
- mCursorCount = 0;
- return;
- }
-
- final int offset = getSelectionStart();
- final int line = mLayout.getLineForOffset(offset);
- final int top = mLayout.getLineTop(line);
- final int bottom = mLayout.getLineTop(line + 1);
-
- mCursorCount = mLayout.isLevelBoundary(offset) ? 2 : 1;
-
- int middle = bottom;
- if (mCursorCount == 2) {
- // Similar to what is done in {@link Layout.#getCursorPath(int, Path, CharSequence)}
- middle = (top + bottom) >> 1;
- }
-
- updateCursorPosition(0, top, middle, mLayout.getPrimaryHorizontal(offset));
-
- if (mCursorCount == 2) {
- updateCursorPosition(1, middle, bottom, mLayout.getSecondaryHorizontal(offset));
- }
- }
-
- private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
- if (mCursorDrawable[cursorIndex] == null)
- mCursorDrawable[cursorIndex] = mContext.getResources().getDrawable(mCursorDrawableRes);
-
- if (mTempRect == null) mTempRect = new Rect();
-
- mCursorDrawable[cursorIndex].getPadding(mTempRect);
- final int width = mCursorDrawable[cursorIndex].getIntrinsicWidth();
- horizontal = Math.max(0.5f, horizontal - 0.5f);
- final int left = (int) (horizontal) - mTempRect.left;
- mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
- bottom + mTempRect.bottom);
- }
-
- private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
- final boolean translate = cursorOffsetVertical != 0;
- if (translate) canvas.translate(0, cursorOffsetVertical);
- for (int i = 0; i < mCursorCount; i++) {
- mCursorDrawable[i].draw(canvas);
- }
- if (translate) canvas.translate(0, -cursorOffsetVertical);
- }
-
@Override
public void getFocusedRect(Rect r) {
if (mLayout == null) {
@@ -5125,18 +4770,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
r.left = (int) mLayout.getPrimaryHorizontal(selStart);
r.right = (int) mLayout.getPrimaryHorizontal(selEnd);
} else {
- // Selection extends across multiple lines -- the focused
- // rect covers the entire width.
- if (mHighlightPath == null) mHighlightPath = new Path();
+ // Selection extends across multiple lines -- make the focused
+ // rect cover the entire width.
if (mHighlightPathBogus) {
+ if (mHighlightPath == null) mHighlightPath = new Path();
mHighlightPath.reset();
mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
mHighlightPathBogus = false;
}
- synchronized (sTempRect) {
- mHighlightPath.computeBounds(sTempRect, true);
- r.left = (int)sTempRect.left-1;
- r.right = (int)sTempRect.right+1;
+ synchronized (TEMP_RECTF) {
+ mHighlightPath.computeBounds(TEMP_RECTF, true);
+ r.left = (int)TEMP_RECTF.left-1;
+ r.right = (int)TEMP_RECTF.right+1;
}
}
}
@@ -5148,6 +4793,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
paddingTop += getVerticalOffset(false);
}
r.offset(paddingLeft, paddingTop);
+ int paddingBottom = getExtendedPaddingBottom();
+ r.bottom += paddingBottom;
}
/**
@@ -5232,7 +4879,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- boolean isInSelectionMode = mSelectionActionMode != null;
+ boolean isInSelectionMode = mEditor != null && getEditor().mSelectionActionMode != null;
if (isInSelectionMode) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
@@ -5290,14 +4937,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// but adding that is a more complicated change.
KeyEvent up = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
if (which == 1) {
- mInput.onKeyUp(this, (Editable)mText, keyCode, up);
+ // mEditor and getEditor().mInput are not null from doKeyDown
+ getEditor().mKeyListener.onKeyUp(this, (Editable)mText, keyCode, up);
while (--repeatCount > 0) {
- mInput.onKeyDown(this, (Editable)mText, keyCode, down);
- mInput.onKeyUp(this, (Editable)mText, keyCode, up);
+ getEditor().mKeyListener.onKeyDown(this, (Editable)mText, keyCode, down);
+ getEditor().mKeyListener.onKeyUp(this, (Editable)mText, keyCode, up);
}
hideErrorIfUnchanged();
} else if (which == 2) {
+ // mMovement is not null from doKeyDown
mMovement.onKeyUp(this, (Spannable)mText, keyCode, up);
while (--repeatCount > 0) {
mMovement.onKeyDown(this, (Spannable)mText, keyCode, down);
@@ -5315,7 +4964,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* lines but where it doesn't make sense to insert newlines.
*/
private boolean shouldAdvanceFocusOnEnter() {
- if (mInput == null) {
+ if (getKeyListener() == null) {
return false;
}
@@ -5323,8 +4972,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return true;
}
- if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
- int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
+ if (mEditor != null && (getEditor().mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
+ int variation = getEditor().mInputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|| variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT) {
return true;
@@ -5339,9 +4988,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* of inserting the character. Insert tabs only in multi-line editors.
*/
private boolean shouldAdvanceFocusOnTab() {
- if (mInput != null && !mSingleLine) {
- if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
- int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
+ if (getKeyListener() != null && !mSingleLine) {
+ if (mEditor != null && (getEditor().mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
+ int variation = getEditor().mInputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
|| variation == EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) {
return false;
@@ -5363,13 +5012,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// running in a "modern" cupcake environment, so don't need
// to worry about the application trying to capture
// enter key events.
- if (mInputContentType != null) {
+ if (mEditor != null && getEditor().mInputContentType != null) {
// If there is an action listener, given them a
// chance to consume the event.
- if (mInputContentType.onEditorActionListener != null &&
- mInputContentType.onEditorActionListener.onEditorAction(
+ if (getEditor().mInputContentType.onEditorActionListener != null &&
+ getEditor().mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
- mInputContentType.enterDown = true;
+ getEditor().mInputContentType.enterDown = true;
// We are consuming the enter key for them.
return -1;
}
@@ -5406,21 +5055,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Has to be done on key down (and not on key up) to correctly be intercepted.
case KeyEvent.KEYCODE_BACK:
- if (mSelectionActionMode != null) {
+ if (mEditor != null && getEditor().mSelectionActionMode != null) {
stopSelectionActionMode();
return -1;
}
break;
}
- if (mInput != null) {
+ if (mEditor != null && getEditor().mKeyListener != null) {
resetErrorChangedFlag();
boolean doDown = true;
if (otherEvent != null) {
try {
beginBatchEdit();
- final boolean handled = mInput.onKeyOther(this, (Editable) mText, otherEvent);
+ final boolean handled = getEditor().mKeyListener.onKeyOther(this, (Editable) mText, otherEvent);
hideErrorIfUnchanged();
doDown = false;
if (handled) {
@@ -5436,7 +5085,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (doDown) {
beginBatchEdit();
- final boolean handled = mInput.onKeyDown(this, (Editable) mText, keyCode, event);
+ final boolean handled = getEditor().mKeyListener.onKeyDown(this, (Editable) mText, keyCode, event);
endBatchEdit();
hideErrorIfUnchanged();
if (handled) return 1;
@@ -5482,14 +5131,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* that error showing. Otherwise, we take down whatever
* error was showing when the user types something.
*/
- mErrorWasChanged = false;
+ if (mEditor != null) getEditor().mErrorWasChanged = false;
}
/**
* @hide
*/
public void hideErrorIfUnchanged() {
- if (mError != null && !mErrorWasChanged) {
+ if (mEditor != null && getEditor().mError != null && !getEditor().mErrorWasChanged) {
setError(null, null);
}
}
@@ -5527,11 +5176,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case KeyEvent.KEYCODE_ENTER:
if (event.hasNoModifiers()) {
- if (mInputContentType != null
- && mInputContentType.onEditorActionListener != null
- && mInputContentType.enterDown) {
- mInputContentType.enterDown = false;
- if (mInputContentType.onEditorActionListener.onEditorAction(
+ if (mEditor != null && getEditor().mInputContentType != null
+ && getEditor().mInputContentType.onEditorActionListener != null
+ && getEditor().mInputContentType.enterDown) {
+ getEditor().mInputContentType.enterDown = false;
+ if (getEditor().mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
return true;
}
@@ -5582,8 +5231,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
}
- if (mInput != null)
- if (mInput.onKeyUp(this, (Editable) mText, keyCode, event))
+ if (mEditor != null && getEditor().mKeyListener != null)
+ if (getEditor().mKeyListener.onKeyUp(this, (Editable) mText, keyCode, event))
return true;
if (mMovement != null && mLayout != null)
@@ -5595,22 +5244,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean onCheckIsTextEditor() {
- return mInputType != EditorInfo.TYPE_NULL;
+ return mEditor != null && getEditor().mInputType != EditorInfo.TYPE_NULL;
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ createEditorIfNeeded("onCreateInputConnection");
if (onCheckIsTextEditor() && isEnabled()) {
- if (mInputMethodState == null) {
- mInputMethodState = new InputMethodState();
- }
- outAttrs.inputType = mInputType;
- if (mInputContentType != null) {
- outAttrs.imeOptions = mInputContentType.imeOptions;
- outAttrs.privateImeOptions = mInputContentType.privateImeOptions;
- outAttrs.actionLabel = mInputContentType.imeActionLabel;
- outAttrs.actionId = mInputContentType.imeActionId;
- outAttrs.extras = mInputContentType.extras;
+ if (getEditor().mInputMethodState == null) {
+ getEditor().mInputMethodState = new InputMethodState();
+ }
+ outAttrs.inputType = getInputType();
+ if (getEditor().mInputContentType != null) {
+ outAttrs.imeOptions = getEditor().mInputContentType.imeOptions;
+ outAttrs.privateImeOptions = getEditor().mInputContentType.privateImeOptions;
+ outAttrs.actionLabel = getEditor().mInputContentType.imeActionLabel;
+ outAttrs.actionId = getEditor().mInputContentType.imeActionId;
+ outAttrs.extras = getEditor().mInputContentType.extras;
} else {
outAttrs.imeOptions = EditorInfo.IME_NULL;
}
@@ -5644,7 +5294,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
InputConnection ic = new EditableInputConnection(this);
outAttrs.initialSelStart = getSelectionStart();
outAttrs.initialSelEnd = getSelectionEnd();
- outAttrs.initialCapsMode = ic.getCursorCapsMode(mInputType);
+ outAttrs.initialCapsMode = ic.getCursorCapsMode(getInputType());
return ic;
}
}
@@ -5736,13 +5386,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
boolean reportExtractedText() {
- final InputMethodState ims = mInputMethodState;
+ final InputMethodState ims = getEditor().mInputMethodState;
if (ims != null) {
final boolean contentChanged = ims.mContentChanged;
if (contentChanged || ims.mSelectionModeChanged) {
ims.mContentChanged = false;
ims.mSelectionModeChanged = false;
- final ExtractedTextRequest req = mInputMethodState.mExtracting;
+ final ExtractedTextRequest req = ims.mExtracting;
if (req != null) {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) {
@@ -5758,8 +5408,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
+ ims.mTmpExtracted.partialStartOffset
+ " end=" + ims.mTmpExtracted.partialEndOffset
+ ": " + ims.mTmpExtracted.text);
- imm.updateExtractedText(this, req.token,
- mInputMethodState.mTmpExtracted);
+ imm.updateExtractedText(this, req.token, ims.mTmpExtracted);
ims.mChangedStart = EXTRACT_UNKNOWN;
ims.mChangedEnd = EXTRACT_UNKNOWN;
ims.mChangedDelta = 0;
@@ -5836,8 +5485,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
public void setExtracting(ExtractedTextRequest req) {
- if (mInputMethodState != null) {
- mInputMethodState.mExtracting = req;
+ if (getEditor().mInputMethodState != null) {
+ getEditor().mInputMethodState.mExtracting = req;
}
// This would stop a possible selection mode, but no such mode is started in case
// extracted mode will start. Some text is selected though, and will trigger an action mode
@@ -5868,109 +5517,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @param info The auto correct info about the text that was corrected.
*/
public void onCommitCorrection(CorrectionInfo info) {
- if (mCorrectionHighlighter == null) {
- mCorrectionHighlighter = new CorrectionHighlighter();
+ if (mEditor == null) return;
+ if (getEditor().mCorrectionHighlighter == null) {
+ getEditor().mCorrectionHighlighter = new CorrectionHighlighter();
} else {
- mCorrectionHighlighter.invalidate(false);
+ getEditor().mCorrectionHighlighter.invalidate(false);
}
- mCorrectionHighlighter.highlight(info);
- }
-
- private class CorrectionHighlighter {
- private final Path mPath = new Path();
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private int mStart, mEnd;
- private long mFadingStartTime;
- private final static int FADE_OUT_DURATION = 400;
-
- public CorrectionHighlighter() {
- mPaint.setCompatibilityScaling(getResources().getCompatibilityInfo().applicationScale);
- mPaint.setStyle(Paint.Style.FILL);
- }
-
- public void highlight(CorrectionInfo info) {
- mStart = info.getOffset();
- mEnd = mStart + info.getNewText().length();
- mFadingStartTime = SystemClock.uptimeMillis();
-
- if (mStart < 0 || mEnd < 0) {
- stopAnimation();
- }
- }
-
- public void draw(Canvas canvas, int cursorOffsetVertical) {
- if (updatePath() && updatePaint()) {
- if (cursorOffsetVertical != 0) {
- canvas.translate(0, cursorOffsetVertical);
- }
-
- canvas.drawPath(mPath, mPaint);
-
- if (cursorOffsetVertical != 0) {
- canvas.translate(0, -cursorOffsetVertical);
- }
- invalidate(true); // TODO invalidate cursor region only
- } else {
- stopAnimation();
- invalidate(false); // TODO invalidate cursor region only
- }
- }
-
- private boolean updatePaint() {
- final long duration = SystemClock.uptimeMillis() - mFadingStartTime;
- if (duration > FADE_OUT_DURATION) return false;
-
- final float coef = 1.0f - (float) duration / FADE_OUT_DURATION;
- final int highlightColorAlpha = Color.alpha(mHighlightColor);
- final int color = (mHighlightColor & 0x00FFFFFF) +
- ((int) (highlightColorAlpha * coef) << 24);
- mPaint.setColor(color);
- return true;
- }
-
- private boolean updatePath() {
- final Layout layout = TextView.this.mLayout;
- if (layout == null) return false;
-
- // Update in case text is edited while the animation is run
- final int length = mText.length();
- int start = Math.min(length, mStart);
- int end = Math.min(length, mEnd);
-
- mPath.reset();
- TextView.this.mLayout.getSelectionPath(start, end, mPath);
- return true;
- }
-
- private void invalidate(boolean delayed) {
- if (TextView.this.mLayout == null) return;
-
- synchronized (sTempRect) {
- mPath.computeBounds(sTempRect, false);
-
- int left = getCompoundPaddingLeft();
- int top = getExtendedPaddingTop() + getVerticalOffset(true);
-
- if (delayed) {
- TextView.this.postInvalidateDelayed(16, // 60 Hz update
- left + (int) sTempRect.left, top + (int) sTempRect.top,
- left + (int) sTempRect.right, top + (int) sTempRect.bottom);
- } else {
- TextView.this.postInvalidate((int) sTempRect.left, (int) sTempRect.top,
- (int) sTempRect.right, (int) sTempRect.bottom);
- }
- }
- }
-
- private void stopAnimation() {
- TextView.this.mCorrectionHighlighter = null;
- }
+ getEditor().mCorrectionHighlighter.highlight(info);
}
public void beginBatchEdit() {
- mInBatchEditControllers = true;
- final InputMethodState ims = mInputMethodState;
+ if (mEditor == null) return;
+ getEditor().mInBatchEditControllers = true;
+ final InputMethodState ims = getEditor().mInputMethodState;
if (ims != null) {
int nesting = ++ims.mBatchEditNesting;
if (nesting == 1) {
@@ -5992,8 +5552,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
public void endBatchEdit() {
- mInBatchEditControllers = false;
- final InputMethodState ims = mInputMethodState;
+ if (mEditor == null) return;
+ getEditor().mInBatchEditControllers = false;
+ final InputMethodState ims = getEditor().mInputMethodState;
if (ims != null) {
int nesting = --ims.mBatchEditNesting;
if (nesting == 0) {
@@ -6003,7 +5564,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
void ensureEndedBatchEdit() {
- final InputMethodState ims = mInputMethodState;
+ final InputMethodState ims = getEditor().mInputMethodState;
if (ims != null && ims.mBatchEditNesting != 0) {
ims.mBatchEditNesting = 0;
finishBatchEdit(ims);
@@ -6046,7 +5607,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void onBeginBatchEdit() {
// intentionally empty
}
-
+
/**
* Called by the framework in response to a request to end a batch
* of edit operations through a call to link {@link #endBatchEdit}.
@@ -6111,8 +5672,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.resetResolvedLayoutDirection();
if (mLayoutAlignment != null &&
- (mTextAlign == TextAlign.VIEW_START ||
- mTextAlign == TextAlign.VIEW_END)) {
+ (mTextAlign == TEXT_ALIGN.VIEW_START ||
+ mTextAlign == TEXT_ALIGN.VIEW_END)) {
mLayoutAlignment = null;
}
}
@@ -6120,7 +5681,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private Layout.Alignment getLayoutAlignment() {
if (mLayoutAlignment == null) {
Layout.Alignment alignment;
- TextAlign textAlign = mTextAlign;
+ TEXT_ALIGN textAlign = mTextAlign;
switch (textAlign) {
case INHERIT:
// fall through to gravity temporarily
@@ -6198,7 +5759,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
Layout.Alignment alignment = getLayoutAlignment();
- boolean shouldEllipsize = mEllipsize != null && mInput == null;
+ boolean shouldEllipsize = mEllipsize != null && getKeyListener() == null;
final boolean switchEllipsize = mEllipsize == TruncateAt.MARQUEE &&
mMarqueeFadeMode != MARQUEE_FADE_NORMAL;
TruncateAt effectiveEllipsize = mEllipsize;
@@ -6315,7 +5876,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mText instanceof Spannable) {
result = new DynamicLayout(mText, mTransformed, mTextPaint, wantWidth,
alignment, mTextDir, mSpacingMult,
- mSpacingAdd, mIncludePad, mInput == null ? effectiveEllipsize : null,
+ mSpacingAdd, mIncludePad, getKeyListener() == null ? effectiveEllipsize : null,
ellipsisWidth);
} else {
if (boring == UNKNOWN_BORING) {
@@ -6776,7 +6337,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- if (changed) mTextDisplayListIsValid = false;
+ if (changed && mEditor != null) getEditor().mTextDisplayListIsValid = false;
}
/**
@@ -7002,11 +6563,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// This offsets because getInterestingRect() is in terms of viewport coordinates, but
// requestRectangleOnScreen() is in terms of content coordinates.
- if (mTempRect == null) mTempRect = new Rect();
// The offsets here are to ensure the rectangle we are using is
// within our view bounds, in case the cursor is on the far left
// or right. If it isn't withing the bounds, then this request
// will be ignored.
+ if (mTempRect == null) mTempRect = new Rect();
mTempRect.set(x - 2, top, x + 2, bottom);
getInterestingRect(mTempRect, line);
mTempRect.offset(mScrollX, mScrollY);
@@ -7226,11 +6787,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @param singleLine
*/
private void setInputTypeSingleLine(boolean singleLine) {
- if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
+ if (mEditor != null && (getEditor().mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
if (singleLine) {
- mInputType &= ~EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+ getEditor().mInputType &= ~EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
} else {
- mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+ getEditor().mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
}
}
}
@@ -7309,7 +6870,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
@android.view.RemotableViewMethod
public void setSelectAllOnFocus(boolean selectAllOnFocus) {
- mSelectAllOnFocus = selectAllOnFocus;
+ createEditorIfNeeded("setSelectAllOnFocus");
+ getEditor().mSelectAllOnFocus = selectAllOnFocus;
if (selectAllOnFocus && !(mText instanceof Spannable)) {
setText(mText, BufferType.SPANNABLE);
@@ -7323,8 +6885,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
@android.view.RemotableViewMethod
public void setCursorVisible(boolean visible) {
- if (mCursorVisible != visible) {
- mCursorVisible = visible;
+ if (visible && mEditor == null) return; // visible is the default value with no edit data
+ createEditorIfNeeded("setCursorVisible");
+ if (getEditor().mCursorVisible != visible) {
+ getEditor().mCursorVisible = visible;
invalidate();
makeBlink();
@@ -7335,7 +6899,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private boolean isCursorVisible() {
- return mCursorVisible && isTextEditable();
+ // The default value is true, even when there is no associated Editor
+ return mEditor == null ? true : (getEditor().mCursorVisible && isTextEditable());
}
private boolean canMarquee() {
@@ -7347,7 +6912,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void startMarquee() {
// Do not ellipsize EditText
- if (mInput != null) return;
+ if (getKeyListener() != null) return;
if (compressText(getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight())) {
return;
@@ -7397,142 +6962,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- private static final class Marquee extends Handler {
- // TODO: Add an option to configure this
- private static final float MARQUEE_DELTA_MAX = 0.07f;
- private static final int MARQUEE_DELAY = 1200;
- private static final int MARQUEE_RESTART_DELAY = 1200;
- private static final int MARQUEE_RESOLUTION = 1000 / 30;
- private static final int MARQUEE_PIXELS_PER_SECOND = 30;
-
- private static final byte MARQUEE_STOPPED = 0x0;
- private static final byte MARQUEE_STARTING = 0x1;
- private static final byte MARQUEE_RUNNING = 0x2;
-
- private static final int MESSAGE_START = 0x1;
- private static final int MESSAGE_TICK = 0x2;
- private static final int MESSAGE_RESTART = 0x3;
-
- private final WeakReference<TextView> mView;
-
- private byte mStatus = MARQUEE_STOPPED;
- private final float mScrollUnit;
- private float mMaxScroll;
- float mMaxFadeScroll;
- private float mGhostStart;
- private float mGhostOffset;
- private float mFadeStop;
- private int mRepeatLimit;
-
- float mScroll;
-
- Marquee(TextView v) {
- final float density = v.getContext().getResources().getDisplayMetrics().density;
- mScrollUnit = (MARQUEE_PIXELS_PER_SECOND * density) / MARQUEE_RESOLUTION;
- mView = new WeakReference<TextView>(v);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_START:
- mStatus = MARQUEE_RUNNING;
- tick();
- break;
- case MESSAGE_TICK:
- tick();
- break;
- case MESSAGE_RESTART:
- if (mStatus == MARQUEE_RUNNING) {
- if (mRepeatLimit >= 0) {
- mRepeatLimit--;
- }
- start(mRepeatLimit);
- }
- break;
- }
- }
-
- void tick() {
- if (mStatus != MARQUEE_RUNNING) {
- return;
- }
-
- removeMessages(MESSAGE_TICK);
-
- final TextView textView = mView.get();
- if (textView != null && (textView.isFocused() || textView.isSelected())) {
- mScroll += mScrollUnit;
- if (mScroll > mMaxScroll) {
- mScroll = mMaxScroll;
- sendEmptyMessageDelayed(MESSAGE_RESTART, MARQUEE_RESTART_DELAY);
- } else {
- sendEmptyMessageDelayed(MESSAGE_TICK, MARQUEE_RESOLUTION);
- }
- textView.invalidate();
- }
- }
-
- void stop() {
- mStatus = MARQUEE_STOPPED;
- removeMessages(MESSAGE_START);
- removeMessages(MESSAGE_RESTART);
- removeMessages(MESSAGE_TICK);
- resetScroll();
- }
-
- private void resetScroll() {
- mScroll = 0.0f;
- final TextView textView = mView.get();
- if (textView != null) textView.invalidate();
- }
-
- void start(int repeatLimit) {
- if (repeatLimit == 0) {
- stop();
- return;
- }
- mRepeatLimit = repeatLimit;
- final TextView textView = mView.get();
- if (textView != null && textView.mLayout != null) {
- mStatus = MARQUEE_STARTING;
- mScroll = 0.0f;
- final int textWidth = textView.getWidth() - textView.getCompoundPaddingLeft() -
- textView.getCompoundPaddingRight();
- final float lineWidth = textView.mLayout.getLineWidth(0);
- final float gap = textWidth / 3.0f;
- mGhostStart = lineWidth - textWidth + gap;
- mMaxScroll = mGhostStart + textWidth;
- mGhostOffset = lineWidth + gap;
- mFadeStop = lineWidth + textWidth / 6.0f;
- mMaxFadeScroll = mGhostStart + lineWidth + lineWidth;
-
- textView.invalidate();
- sendEmptyMessageDelayed(MESSAGE_START, MARQUEE_DELAY);
- }
- }
-
- float getGhostOffset() {
- return mGhostOffset;
- }
-
- boolean shouldDrawLeftFade() {
- return mScroll <= mFadeStop;
- }
-
- boolean shouldDrawGhost() {
- return mStatus == MARQUEE_RUNNING && mScroll > mGhostStart;
- }
-
- boolean isRunning() {
- return mStatus == MARQUEE_RUNNING;
- }
-
- boolean isStopped() {
- return mStatus == MARQUEE_STOPPED;
- }
- }
-
/**
* This method is called when the text is changed, in case any subclasses
* would like to know.
@@ -7561,7 +6990,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
protected void onSelectionChanged(int selStart, int selEnd) {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
}
/**
@@ -7640,13 +7069,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- updateSpellCheckSpans(start, start + after, false);
- mTextDisplayListIsValid = false;
-
- // Hide the controllers as soon as text is modified (typing, procedural...)
- // We do not hide the span controllers, since they can be added when a new text is
- // inserted into the text view (voice IME).
- hideCursorControllers();
+ if (mEditor != null) getEditor().sendOnTextChanged(start, after);
}
/**
@@ -7668,7 +7091,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* through a thunk.
*/
void handleTextChanged(CharSequence buffer, int start, int before, int after) {
- final InputMethodState ims = mInputMethodState;
+ final InputMethodState ims = mEditor == null ? null : getEditor().mInputMethodState;
if (ims == null || ims.mBatchEditNesting == 0) {
updateAfterEdit();
}
@@ -7687,7 +7110,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
sendOnTextChanged(buffer, start, before, after);
onTextChanged(buffer, start, before, after);
}
-
+
/**
* Not private so it can be called from an inner class without going
* through a thunk.
@@ -7698,18 +7121,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean selChanged = false;
int newSelStart=-1, newSelEnd=-1;
-
- final InputMethodState ims = mInputMethodState;
-
+
+ final InputMethodState ims = mEditor == null ? null : getEditor().mInputMethodState;
+
if (what == Selection.SELECTION_END) {
- mHighlightPathBogus = true;
selChanged = true;
newSelEnd = newStart;
- if (!isFocused()) {
- mSelectionMoved = true;
- }
-
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
registerForPreDraw();
@@ -7718,14 +7136,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (what == Selection.SELECTION_START) {
- mHighlightPathBogus = true;
selChanged = true;
newSelStart = newStart;
- if (!isFocused()) {
- mSelectionMoved = true;
- }
-
if (oldStart >= 0 || newStart >= 0) {
int end = Selection.getSelectionEnd(buf);
invalidateCursor(end, oldStart, newStart);
@@ -7733,6 +7146,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (selChanged) {
+ mHighlightPathBogus = true;
+ if (mEditor != null && !isFocused()) getEditor().mSelectionMoved = true;
+
if ((buf.getSpanFlags(what)&Spanned.SPAN_INTERMEDIATE) == 0) {
if (newSelStart < 0) {
newSelStart = Selection.getSelectionStart(buf);
@@ -7753,7 +7169,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} else {
ims.mContentChanged = true;
}
- mTextDisplayListIsValid = false;
+ if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
@@ -7801,8 +7217,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- if (mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
- mSpellChecker.removeSpellCheckSpan((SpellCheckSpan) what);
+ if (mEditor != null && getEditor().mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
+ getEditor().mSpellChecker.removeSpellCheckSpan((SpellCheckSpan) what);
}
}
@@ -7811,289 +7227,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
private void updateSpellCheckSpans(int start, int end, boolean createSpellChecker) {
if (isTextEditable() && isSuggestionsEnabled() && !(this instanceof ExtractEditText)) {
- if (mSpellChecker == null && createSpellChecker) {
- mSpellChecker = new SpellChecker(this);
- }
- if (mSpellChecker != null) {
- mSpellChecker.spellCheck(start, end);
- }
- }
- }
-
- /**
- * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
- * pop-up should be displayed.
- */
- private class EasyEditSpanController {
-
- private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs
-
- private EasyEditPopupWindow mPopupWindow;
-
- private EasyEditSpan mEasyEditSpan;
-
- private Runnable mHidePopup;
-
- private void hide() {
- if (mPopupWindow != null) {
- mPopupWindow.hide();
- TextView.this.removeCallbacks(mHidePopup);
- }
- removeSpans(mText);
- mEasyEditSpan = null;
- }
-
- /**
- * Monitors the changes in the text.
- *
- * <p>{@link ChangeWatcher#onSpanAdded(Spannable, Object, int, int)} cannot be used,
- * as the notifications are not sent when a spannable (with spans) is inserted.
- */
- public void onTextChange(CharSequence buffer) {
- adjustSpans(mText);
-
- if (getWindowVisibility() != View.VISIBLE) {
- // The window is not visible yet, ignore the text change.
- return;
- }
-
- if (mLayout == null) {
- // The view has not been layout yet, ignore the text change
- return;
- }
-
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (!(TextView.this instanceof ExtractEditText)
- && imm != null && imm.isFullscreenMode()) {
- // The input is in extract mode. We do not have to handle the easy edit in the
- // original TextView, as the ExtractEditText will do
- return;
- }
-
- // Remove the current easy edit span, as the text changed, and remove the pop-up
- // (if any)
- if (mEasyEditSpan != null) {
- if (mText instanceof Spannable) {
- ((Spannable) mText).removeSpan(mEasyEditSpan);
- }
- mEasyEditSpan = null;
- }
- if (mPopupWindow != null && mPopupWindow.isShowing()) {
- mPopupWindow.hide();
- }
-
- // Display the new easy edit span (if any).
- if (buffer instanceof Spanned) {
- mEasyEditSpan = getSpan((Spanned) buffer);
- if (mEasyEditSpan != null) {
- if (mPopupWindow == null) {
- mPopupWindow = new EasyEditPopupWindow();
- mHidePopup = new Runnable() {
- @Override
- public void run() {
- hide();
- }
- };
- }
- mPopupWindow.show(mEasyEditSpan);
- TextView.this.removeCallbacks(mHidePopup);
- TextView.this.postDelayed(mHidePopup, DISPLAY_TIMEOUT_MS);
- }
+ if (getEditor().mSpellChecker == null && createSpellChecker) {
+ getEditor().mSpellChecker = new SpellChecker(this);
}
- }
-
- /**
- * Adjusts the spans by removing all of them except the last one.
- */
- private void adjustSpans(CharSequence buffer) {
- // This method enforces that only one easy edit span is attached to the text.
- // A better way to enforce this would be to listen for onSpanAdded, but this method
- // cannot be used in this scenario as no notification is triggered when a text with
- // spans is inserted into a text.
- if (buffer instanceof Spannable) {
- Spannable spannable = (Spannable) buffer;
- EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(),
- EasyEditSpan.class);
- for (int i = 0; i < spans.length - 1; i++) {
- spannable.removeSpan(spans[i]);
- }
- }
- }
-
- /**
- * Removes all the {@link EasyEditSpan} currently attached.
- */
- private void removeSpans(CharSequence buffer) {
- if (buffer instanceof Spannable) {
- Spannable spannable = (Spannable) buffer;
- EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(),
- EasyEditSpan.class);
- for (int i = 0; i < spans.length; i++) {
- spannable.removeSpan(spans[i]);
- }
- }
- }
-
- private EasyEditSpan getSpan(Spanned spanned) {
- EasyEditSpan[] easyEditSpans = spanned.getSpans(0, spanned.length(),
- EasyEditSpan.class);
- if (easyEditSpans.length == 0) {
- return null;
- } else {
- return easyEditSpans[0];
+ if (getEditor().mSpellChecker != null) {
+ getEditor().mSpellChecker.spellCheck(start, end);
}
}
}
/**
- * Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled
- * by {@link EasyEditSpanController}.
- */
- private class EasyEditPopupWindow extends PinnedPopupWindow
- implements OnClickListener {
- private static final int POPUP_TEXT_LAYOUT =
- com.android.internal.R.layout.text_edit_action_popup_text;
- private TextView mDeleteTextView;
- private EasyEditSpan mEasyEditSpan;
-
- @Override
- protected void createPopupWindow() {
- mPopupWindow = new PopupWindow(TextView.this.mContext, null,
- com.android.internal.R.attr.textSelectHandleWindowStyle);
- mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
- mPopupWindow.setClippingEnabled(true);
- }
-
- @Override
- protected void initContentView() {
- LinearLayout linearLayout = new LinearLayout(TextView.this.getContext());
- linearLayout.setOrientation(LinearLayout.HORIZONTAL);
- mContentView = linearLayout;
- mContentView.setBackgroundResource(
- com.android.internal.R.drawable.text_edit_side_paste_window);
-
- LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
- getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- LayoutParams wrapContent = new LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mDeleteTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
- mDeleteTextView.setLayoutParams(wrapContent);
- mDeleteTextView.setText(com.android.internal.R.string.delete);
- mDeleteTextView.setOnClickListener(this);
- mContentView.addView(mDeleteTextView);
- }
-
- public void show(EasyEditSpan easyEditSpan) {
- mEasyEditSpan = easyEditSpan;
- super.show();
- }
-
- @Override
- public void onClick(View view) {
- if (view == mDeleteTextView) {
- Editable editable = (Editable) mText;
- int start = editable.getSpanStart(mEasyEditSpan);
- int end = editable.getSpanEnd(mEasyEditSpan);
- if (start >= 0 && end >= 0) {
- deleteText_internal(start, end);
- }
- }
- }
-
- @Override
- protected int getTextOffset() {
- // Place the pop-up at the end of the span
- Editable editable = (Editable) mText;
- return editable.getSpanEnd(mEasyEditSpan);
- }
-
- @Override
- protected int getVerticalLocalPosition(int line) {
- return mLayout.getLineBottom(line);
- }
-
- @Override
- protected int clipVertically(int positionY) {
- // As we display the pop-up below the span, no vertical clipping is required.
- return positionY;
- }
- }
-
- private class ChangeWatcher implements TextWatcher, SpanWatcher {
-
- private CharSequence mBeforeText;
-
- private EasyEditSpanController mEasyEditSpanController;
-
- private ChangeWatcher() {
- mEasyEditSpanController = new EasyEditSpanController();
- }
-
- public void beforeTextChanged(CharSequence buffer, int start,
- int before, int after) {
- if (DEBUG_EXTRACT) Log.v(LOG_TAG, "beforeTextChanged start=" + start
- + " before=" + before + " after=" + after + ": " + buffer);
-
- if (AccessibilityManager.getInstance(mContext).isEnabled()
- && !isPasswordInputType(mInputType)
- && !hasPasswordTransformationMethod()) {
- mBeforeText = buffer.toString();
- }
-
- TextView.this.sendBeforeTextChanged(buffer, start, before, after);
- }
-
- public void onTextChanged(CharSequence buffer, int start,
- int before, int after) {
- if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onTextChanged start=" + start
- + " before=" + before + " after=" + after + ": " + buffer);
- TextView.this.handleTextChanged(buffer, start, before, after);
-
- mEasyEditSpanController.onTextChange(buffer);
-
- if (AccessibilityManager.getInstance(mContext).isEnabled() &&
- (isFocused() || isSelected() && isShown())) {
- sendAccessibilityEventTypeViewTextChanged(mBeforeText, start, before, after);
- mBeforeText = null;
- }
- }
-
- public void afterTextChanged(Editable buffer) {
- if (DEBUG_EXTRACT) Log.v(LOG_TAG, "afterTextChanged: " + buffer);
- TextView.this.sendAfterTextChanged(buffer);
-
- if (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0) {
- MetaKeyKeyListener.stopSelecting(TextView.this, buffer);
- }
- }
-
- public void onSpanChanged(Spannable buf,
- Object what, int s, int e, int st, int en) {
- if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onSpanChanged s=" + s + " e=" + e
- + " st=" + st + " en=" + en + " what=" + what + ": " + buf);
- TextView.this.spanChange(buf, what, s, st, e, en);
- }
-
- public void onSpanAdded(Spannable buf, Object what, int s, int e) {
- if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onSpanAdded s=" + s + " e=" + e
- + " what=" + what + ": " + buf);
- TextView.this.spanChange(buf, what, -1, s, -1, e);
- }
-
- public void onSpanRemoved(Spannable buf, Object what, int s, int e) {
- if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onSpanRemoved s=" + s + " e=" + e
- + " what=" + what + ": " + buf);
- TextView.this.spanChange(buf, what, s, -1, e, -1);
- }
-
- private void hideControllers() {
- mEasyEditSpanController.hide();
- }
- }
-
- /**
* @hide
*/
@Override
@@ -8113,7 +7256,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Because of View recycling in ListView, there is no easy way to know when a TextView with
// selection becomes visible again. Until a better solution is found, stop text selection
// mode (if any) as soon as this TextView is recycled.
- hideControllers();
+ if (mEditor != null) hideControllers();
}
@Override
@@ -8131,95 +7274,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.onFocusChanged(focused, direction, previouslyFocusedRect);
return;
}
-
- mShowCursor = SystemClock.uptimeMillis();
- ensureEndedBatchEdit();
+ if (mEditor != null) getEditor().onFocusChanged(focused, direction);
if (focused) {
- int selStart = getSelectionStart();
- int selEnd = getSelectionEnd();
-
- // SelectAllOnFocus fields are highlighted and not selected. Do not start text selection
- // mode for these, unless there was a specific selection already started.
- final boolean isFocusHighlighted = mSelectAllOnFocus && selStart == 0 &&
- selEnd == mText.length();
- mCreatedWithASelection = mFrozenWithFocus && hasSelection() && !isFocusHighlighted;
-
- if (!mFrozenWithFocus || (selStart < 0 || selEnd < 0)) {
- // If a tap was used to give focus to that view, move cursor at tap position.
- // Has to be done before onTakeFocus, which can be overloaded.
- final int lastTapPosition = getLastTapPosition();
- if (lastTapPosition >= 0) {
- Selection.setSelection((Spannable) mText, lastTapPosition);
- }
-
- if (mMovement != null) {
- mMovement.onTakeFocus(this, (Spannable) mText, direction);
- }
-
- // The DecorView does not have focus when the 'Done' ExtractEditText button is
- // pressed. Since it is the ViewAncestor's mView, it requests focus before
- // ExtractEditText clears focus, which gives focus to the ExtractEditText.
- // This special case ensure that we keep current selection in that case.
- // It would be better to know why the DecorView does not have focus at that time.
- if (((this instanceof ExtractEditText) || mSelectionMoved) &&
- selStart >= 0 && selEnd >= 0) {
- /*
- * Someone intentionally set the selection, so let them
- * do whatever it is that they wanted to do instead of
- * the default on-focus behavior. We reset the selection
- * here instead of just skipping the onTakeFocus() call
- * because some movement methods do something other than
- * just setting the selection in theirs and we still
- * need to go through that path.
- */
- Selection.setSelection((Spannable) mText, selStart, selEnd);
- }
-
- if (mSelectAllOnFocus) {
- selectAll();
- }
-
- mTouchFocusSelected = true;
- }
-
- mFrozenWithFocus = false;
- mSelectionMoved = false;
-
if (mText instanceof Spannable) {
Spannable sp = (Spannable) mText;
MetaKeyKeyListener.resetMetaState(sp);
}
-
- makeBlink();
-
- if (mError != null) {
- showError();
- }
- } else {
- if (mError != null) {
- hideError();
- }
- // Don't leave us in the middle of a batch edit.
- onEndBatchEdit();
-
- if (this instanceof ExtractEditText) {
- // terminateTextSelectionMode removes selection, which we want to keep when
- // ExtractEditText goes out of focus.
- final int selStart = getSelectionStart();
- final int selEnd = getSelectionEnd();
- hideControllers();
- Selection.setSelection((Spannable) mText, selStart, selEnd);
- } else {
- hideControllers();
- downgradeEasyCorrectionSpans();
- }
-
- // No need to create the controller
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.resetTouchOffsets();
- }
}
startStopMarquee(focused);
@@ -8231,48 +7293,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
- private int getLastTapPosition() {
- // No need to create the controller at that point, no last tap position saved
- if (mSelectionModifierCursorController != null) {
- int lastTapPosition = mSelectionModifierCursorController.getMinTouchOffset();
- if (lastTapPosition >= 0) {
- // Safety check, should not be possible.
- if (lastTapPosition > mText.length()) {
- Log.e(LOG_TAG, "Invalid tap focus position (" + lastTapPosition + " vs "
- + mText.length() + ")");
- lastTapPosition = mText.length();
- }
- return lastTapPosition;
- }
- }
-
- return -1;
- }
-
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
- if (hasWindowFocus) {
- if (mBlink != null) {
- mBlink.uncancel();
- makeBlink();
- }
- } else {
- if (mBlink != null) {
- mBlink.cancel();
- }
- // Don't leave us in the middle of a batch edit.
- onEndBatchEdit();
- if (mInputContentType != null) {
- mInputContentType.enterDown = false;
- }
-
- hideControllers();
- if (mSuggestionsPopupWindow != null) {
- mSuggestionsPopupWindow.onParentLostFocus();
- }
- }
+ if (mEditor != null) getEditor().onWindowFocusChanged(hasWindowFocus);
startStopMarquee(hasWindowFocus);
}
@@ -8280,7 +7305,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (visibility != VISIBLE) {
+ if (mEditor != null && visibility != VISIBLE) {
hideControllers();
}
}
@@ -8315,23 +7340,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
- if (hasSelectionController()) {
- getSelectionController().onTouchEvent(event);
- }
-
- if (mShowSuggestionRunnable != null) {
- removeCallbacks(mShowSuggestionRunnable);
- }
-
- if (action == MotionEvent.ACTION_DOWN) {
- mLastDownPositionX = event.getX();
- mLastDownPositionY = event.getY();
-
- // Reset this state; it will be re-set if super.onTouchEvent
- // causes focus to move to the view.
- mTouchFocusSelected = false;
- mIgnoreActionUpEvent = false;
- }
+ if (mEditor != null) getEditor().onTouchEvent(event);
final boolean superResult = super.onTouchEvent(event);
@@ -8340,13 +7349,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* move the selection away from whatever the menu action was
* trying to affect.
*/
- if (mDiscardNextActionUp && action == MotionEvent.ACTION_UP) {
- mDiscardNextActionUp = false;
+ if (mEditor != null && getEditor().mDiscardNextActionUp && action == MotionEvent.ACTION_UP) {
+ getEditor().mDiscardNextActionUp = false;
return superResult;
}
final boolean touchIsFinished = (action == MotionEvent.ACTION_UP) &&
- !mIgnoreActionUpEvent && isFocused();
+ (mEditor == null || !getEditor().mIgnoreActionUpEvent) && isFocused();
if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
&& mText instanceof Spannable && mLayout != null) {
@@ -8356,7 +7365,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
}
- if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable) {
+ final boolean textIsSelectable = isTextSelectable();
+ if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && textIsSelectable) {
// The LinkMovementMethod which should handle taps on links has not been installed
// on non editable text that support text selection.
// We reproduce its behavior here to open links for these.
@@ -8369,34 +7379,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- if (touchIsFinished && (isTextEditable() || mTextIsSelectable)) {
+ if (touchIsFinished && (isTextEditable() || textIsSelectable)) {
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (!mTextIsSelectable) {
+ if (!textIsSelectable) {
handled |= imm != null && imm.showSoftInput(this, 0);
}
- boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
+ boolean selectAllGotFocus = getEditor().mSelectAllOnFocus && didTouchFocusSelect();
hideControllers();
if (!selectAllGotFocus && mText.length() > 0) {
// Move cursor
final int offset = getOffsetForPosition(event.getX(), event.getY());
Selection.setSelection((Spannable) mText, offset);
- if (mSpellChecker != null) {
+ if (getEditor().mSpellChecker != null) {
// When the cursor moves, the word that was typed may need spell check
- mSpellChecker.onSelectionChanged();
+ getEditor().mSpellChecker.onSelectionChanged();
}
if (!extractedTextModeWillBeStarted()) {
if (isCursorInsideEasyCorrectionSpan()) {
- if (mShowSuggestionRunnable == null) {
- mShowSuggestionRunnable = new Runnable() {
- public void run() {
- showSuggestions();
- }
- };
- }
- postDelayed(mShowSuggestionRunnable,
+ getEditor().mShowSuggestionRunnable = new Runnable() {
+ public void run() {
+ showSuggestions();
+ }
+ };
+ // removeCallbacks is performed on every touch
+ postDelayed(getEditor().mShowSuggestionRunnable,
ViewConfiguration.getDoubleTapTimeout());
} else if (hasInsertionController()) {
getInsertionController().show();
@@ -8479,6 +7488,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void prepareCursorControllers() {
+ if (mEditor == null) return;
+
boolean windowSupportsHandles = false;
ViewGroup.LayoutParams params = getRootView().getLayoutParams();
@@ -8488,23 +7499,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|| windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}
- mInsertionControllerEnabled = windowSupportsHandles && isCursorVisible() && mLayout != null;
- mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() &&
+ getEditor().mInsertionControllerEnabled = windowSupportsHandles && isCursorVisible() && mLayout != null;
+ getEditor().mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() &&
mLayout != null;
- if (!mInsertionControllerEnabled) {
+ if (!getEditor().mInsertionControllerEnabled) {
hideInsertionPointCursorController();
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.onDetached();
- mInsertionPointCursorController = null;
+ if (getEditor().mInsertionPointCursorController != null) {
+ getEditor().mInsertionPointCursorController.onDetached();
+ getEditor().mInsertionPointCursorController = null;
}
}
- if (!mSelectionControllerEnabled) {
+ if (!getEditor().mSelectionControllerEnabled) {
stopSelectionActionMode();
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.onDetached();
- mSelectionModifierCursorController = null;
+ if (getEditor().mSelectionModifierCursorController != null) {
+ getEditor().mSelectionModifierCursorController.onDetached();
+ getEditor().mSelectionModifierCursorController = null;
}
}
}
@@ -8524,19 +7535,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* of interest.
*/
public boolean didTouchFocusSelect() {
- return mTouchFocusSelected;
+ return mEditor != null && getEditor().mTouchFocusSelected;
}
@Override
public void cancelLongPress() {
super.cancelLongPress();
- mIgnoreActionUpEvent = true;
+ if (mEditor != null) getEditor().mIgnoreActionUpEvent = true;
}
@Override
public boolean onTrackballEvent(MotionEvent event) {
- if (mMovement != null && mText instanceof Spannable &&
- mLayout != null) {
+ if (mMovement != null && mText instanceof Spannable && mLayout != null) {
if (mMovement.onTrackballEvent(this, (Spannable) mText, event)) {
return true;
}
@@ -8549,49 +7559,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mScroller = s;
}
- private static class Blink extends Handler implements Runnable {
- private final WeakReference<TextView> mView;
- private boolean mCancelled;
-
- public Blink(TextView v) {
- mView = new WeakReference<TextView>(v);
- }
-
- public void run() {
- if (mCancelled) {
- return;
- }
-
- removeCallbacks(Blink.this);
-
- TextView tv = mView.get();
-
- if (tv != null && tv.shouldBlink()) {
- if (tv.mLayout != null) {
- tv.invalidateCursorPath();
- }
-
- postAtTime(this, SystemClock.uptimeMillis() + BLINK);
- }
- }
-
- void cancel() {
- if (!mCancelled) {
- removeCallbacks(Blink.this);
- mCancelled = true;
- }
- }
-
- void uncancel() {
- mCancelled = false;
- }
- }
-
/**
* @return True when the TextView isFocused and has a valid zero-length selection (cursor).
*/
private boolean shouldBlink() {
- if (!isCursorVisible() || !isFocused()) return false;
+ if (mEditor == null || !isCursorVisible() || !isFocused()) return false;
final int start = getSelectionStart();
if (start < 0) return false;
@@ -8604,12 +7576,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void makeBlink() {
if (shouldBlink()) {
- mShowCursor = SystemClock.uptimeMillis();
- if (mBlink == null) mBlink = new Blink(this);
- mBlink.removeCallbacks(mBlink);
- mBlink.postAtTime(mBlink, mShowCursor + BLINK);
+ getEditor().mShowCursor = SystemClock.uptimeMillis();
+ if (getEditor().mBlink == null) getEditor().mBlink = new Blink(this);
+ getEditor().mBlink.removeCallbacks(getEditor().mBlink);
+ getEditor().mBlink.postAtTime(getEditor().mBlink, getEditor().mShowCursor + BLINK);
} else {
- if (mBlink != null) mBlink.removeCallbacks(mBlink);
+ if (mEditor != null && getEditor().mBlink != null) getEditor().mBlink.removeCallbacks(getEditor().mBlink);
}
}
@@ -8808,7 +7780,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// If you change this condition, make sure prepareCursorController is called anywhere
// the value of this condition might be changed.
if (mMovement == null || !mMovement.canSelectArbitrarily()) return false;
- return isTextEditable() || (mTextIsSelectable && mText instanceof Spannable && isEnabled());
+ return isTextEditable() || (isTextSelectable() && mText instanceof Spannable && isEnabled());
}
private boolean canCut() {
@@ -8816,7 +7788,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return false;
}
- if (mText.length() > 0 && hasSelection() && mText instanceof Editable && mInput != null) {
+ if (mText.length() > 0 && hasSelection() && mText instanceof Editable && mEditor != null && getEditor().mKeyListener != null) {
return true;
}
@@ -8837,7 +7809,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private boolean canPaste() {
return (mText instanceof Editable &&
- mInput != null &&
+ mEditor != null && getEditor().mKeyListener != null &&
getSelectionStart() >= 0 &&
getSelectionEnd() >= 0 &&
((ClipboardManager)getContext().getSystemService(Context.CLIPBOARD_SERVICE)).
@@ -8878,8 +7850,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return selectAll();
}
- int klass = mInputType & InputType.TYPE_MASK_CLASS;
- int variation = mInputType & InputType.TYPE_MASK_VARIATION;
+ int inputType = getInputType();
+ int klass = inputType & InputType.TYPE_MASK_CLASS;
+ int variation = inputType & InputType.TYPE_MASK_VARIATION;
// Specific text field types: select the entire text for these
if (klass == InputType.TYPE_CLASS_NUMBER ||
@@ -8949,17 +7922,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
void onLocaleChanged() {
// Will be re-created on demand in getWordIterator with the proper new locale
- mWordIterator = null;
+ getEditor().mWordIterator = null;
}
/**
* @hide
*/
public WordIterator getWordIterator() {
- if (mWordIterator == null) {
- mWordIterator = new WordIterator(getTextServicesLocale());
+ if (getEditor().mWordIterator == null) {
+ getEditor().mWordIterator = new WordIterator(getTextServicesLocale());
}
- return mWordIterator;
+ return getEditor().mWordIterator;
}
private long getCharRange(int offset) {
@@ -9213,17 +8186,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return new DragShadowBuilder(shadowView);
}
- private static class DragLocalState {
- public TextView sourceTextView;
- public int start, end;
-
- public DragLocalState(TextView sourceTextView, int start, int end) {
- this.sourceTextView = sourceTextView;
- this.start = start;
- this.end = end;
- }
- }
-
@Override
public boolean performLongClick() {
boolean handled = false;
@@ -9234,9 +8196,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// Long press in empty space moves cursor and shows the Paste affordance if available.
- if (!handled && !isPositionOnText(mLastDownPositionX, mLastDownPositionY) &&
- mInsertionControllerEnabled) {
- final int offset = getOffsetForPosition(mLastDownPositionX, mLastDownPositionY);
+ if (!handled && mEditor != null && !isPositionOnText(getEditor().mLastDownPositionX, getEditor().mLastDownPositionY) &&
+ getEditor().mInsertionControllerEnabled) {
+ final int offset = getOffsetForPosition(getEditor().mLastDownPositionX, getEditor().mLastDownPositionY);
stopSelectionActionMode();
Selection.setSelection((Spannable) mText, offset);
getInsertionController().showWithActionPopup();
@@ -9244,7 +8206,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
vibrate = false;
}
- if (!handled && mSelectionActionMode != null) {
+ if (!handled && mEditor != null && getEditor().mSelectionActionMode != null) {
if (touchPositionIsInSelection()) {
// Start a drag
final int start = getSelectionStart();
@@ -9263,7 +8225,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// Start a new selection
- if (!handled) {
+ if (!handled && mEditor != null) {
vibrate = handled = startSelectionActionMode();
}
@@ -9271,8 +8233,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
- if (handled) {
- mDiscardNextActionUp = true;
+ if (handled && mEditor != null) {
+ getEditor().mDiscardNextActionUp = true;
}
return handled;
@@ -9301,10 +8263,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private PositionListener getPositionListener() {
- if (mPositionListener == null) {
- mPositionListener = new PositionListener();
+ if (getEditor().mPositionListener == null) {
+ getEditor().mPositionListener = new PositionListener();
}
- return mPositionListener;
+ return getEditor().mPositionListener;
}
private interface TextViewPositionListener {
@@ -9312,6 +8274,1420 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean parentPositionChanged, boolean parentScrolled);
}
+ private boolean isPositionVisible(int positionX, int positionY) {
+ synchronized (TEMP_POSITION) {
+ final float[] position = TEMP_POSITION;
+ position[0] = positionX;
+ position[1] = positionY;
+ View view = this;
+
+ while (view != null) {
+ if (view != this) {
+ // Local scroll is already taken into account in positionX/Y
+ position[0] -= view.getScrollX();
+ position[1] -= view.getScrollY();
+ }
+
+ if (position[0] < 0 || position[1] < 0 ||
+ position[0] > view.getWidth() || position[1] > view.getHeight()) {
+ return false;
+ }
+
+ if (!view.getMatrix().isIdentity()) {
+ view.getMatrix().mapPoints(position);
+ }
+
+ position[0] += view.getLeft();
+ position[1] += view.getTop();
+
+ final ViewParent parent = view.getParent();
+ if (parent instanceof View) {
+ view = (View) parent;
+ } else {
+ // We've reached the ViewRoot, stop iterating
+ view = null;
+ }
+ }
+ }
+
+ // We've been able to walk up the view hierarchy and the position was never clipped
+ return true;
+ }
+
+ private boolean isOffsetVisible(int offset) {
+ final int line = mLayout.getLineForOffset(offset);
+ final int lineBottom = mLayout.getLineBottom(line);
+ final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
+ return isPositionVisible(primaryHorizontal + viewportToContentHorizontalOffset(),
+ lineBottom + viewportToContentVerticalOffset());
+ }
+
+ @Override
+ protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
+ super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
+ if (mEditor != null && getEditor().mPositionListener != null) {
+ getEditor().mPositionListener.onScrollChanged();
+ }
+ }
+
+ /**
+ * Removes the suggestion spans.
+ */
+ CharSequence removeSuggestionSpans(CharSequence text) {
+ if (text instanceof Spanned) {
+ Spannable spannable;
+ if (text instanceof Spannable) {
+ spannable = (Spannable) text;
+ } else {
+ spannable = new SpannableString(text);
+ text = spannable;
+ }
+
+ SuggestionSpan[] spans = spannable.getSpans(0, text.length(), SuggestionSpan.class);
+ for (int i = 0; i < spans.length; i++) {
+ spannable.removeSpan(spans[i]);
+ }
+ }
+ return text;
+ }
+
+ void showSuggestions() {
+ if (getEditor().mSuggestionsPopupWindow == null) {
+ getEditor().mSuggestionsPopupWindow = new SuggestionsPopupWindow();
+ }
+ hideControllers();
+ getEditor().mSuggestionsPopupWindow.show();
+ }
+
+ boolean areSuggestionsShown() {
+ return getEditor().mSuggestionsPopupWindow != null && getEditor().mSuggestionsPopupWindow.isShowing();
+ }
+
+ /**
+ * Return whether or not suggestions are enabled on this TextView. The suggestions are generated
+ * by the IME or by the spell checker as the user types. This is done by adding
+ * {@link SuggestionSpan}s to the text.
+ *
+ * When suggestions are enabled (default), this list of suggestions will be displayed when the
+ * user asks for them on these parts of the text. This value depends on the inputType of this
+ * TextView.
+ *
+ * The class of the input type must be {@link InputType#TYPE_CLASS_TEXT}.
+ *
+ * In addition, the type variation must be one of
+ * {@link InputType#TYPE_TEXT_VARIATION_NORMAL},
+ * {@link InputType#TYPE_TEXT_VARIATION_EMAIL_SUBJECT},
+ * {@link InputType#TYPE_TEXT_VARIATION_LONG_MESSAGE},
+ * {@link InputType#TYPE_TEXT_VARIATION_SHORT_MESSAGE} or
+ * {@link InputType#TYPE_TEXT_VARIATION_WEB_EDIT_TEXT}.
+ *
+ * And finally, the {@link InputType#TYPE_TEXT_FLAG_NO_SUGGESTIONS} flag must <i>not</i> be set.
+ *
+ * @return true if the suggestions popup window is enabled, based on the inputType.
+ */
+ public boolean isSuggestionsEnabled() {
+ if (mEditor == null) return false;
+ if ((getEditor().mInputType & InputType.TYPE_MASK_CLASS) != InputType.TYPE_CLASS_TEXT) return false;
+ if ((getEditor().mInputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) > 0) return false;
+
+ final int variation = getEditor().mInputType & EditorInfo.TYPE_MASK_VARIATION;
+ return (variation == EditorInfo.TYPE_TEXT_VARIATION_NORMAL ||
+ variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT ||
+ variation == EditorInfo.TYPE_TEXT_VARIATION_LONG_MESSAGE ||
+ variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE ||
+ variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
+ }
+
+ /**
+ * If provided, this ActionMode.Callback will be used to create the ActionMode when text
+ * selection is initiated in this View.
+ *
+ * The standard implementation populates the menu with a subset of Select All, Cut, Copy and
+ * Paste actions, depending on what this View supports.
+ *
+ * A custom implementation can add new entries in the default menu in its
+ * {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
+ * default actions can also be removed from the menu using {@link Menu#removeItem(int)} and
+ * passing {@link android.R.id#selectAll}, {@link android.R.id#cut}, {@link android.R.id#copy}
+ * or {@link android.R.id#paste} ids as parameters.
+ *
+ * Returning false from
+ * {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
+ * the action mode from being started.
+ *
+ * Action click events should be handled by the custom implementation of
+ * {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
+ *
+ * Note that text selection mode is not started when a TextView receives focus and the
+ * {@link android.R.attr#selectAllOnFocus} flag has been set. The content is highlighted in
+ * that case, to allow for quick replacement.
+ */
+ public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
+ createEditorIfNeeded("custom selection action mode set");
+ getEditor().mCustomSelectionActionModeCallback = actionModeCallback;
+ }
+
+ /**
+ * Retrieves the value set in {@link #setCustomSelectionActionModeCallback}. Default is null.
+ *
+ * @return The current custom selection callback.
+ */
+ public ActionMode.Callback getCustomSelectionActionModeCallback() {
+ return mEditor == null ? null : getEditor().mCustomSelectionActionModeCallback;
+ }
+
+ /**
+ *
+ * @return true if the selection mode was actually started.
+ */
+ private boolean startSelectionActionMode() {
+ if (getEditor().mSelectionActionMode != null) {
+ // Selection action mode is already started
+ return false;
+ }
+
+ if (!canSelectText() || !requestFocus()) {
+ Log.w(LOG_TAG, "TextView does not support text selection. Action mode cancelled.");
+ return false;
+ }
+
+ if (!hasSelection()) {
+ // There may already be a selection on device rotation
+ if (!selectCurrentWord()) {
+ // No word found under cursor or text selection not permitted.
+ return false;
+ }
+ }
+
+ boolean willExtract = extractedTextModeWillBeStarted();
+
+ // Do not start the action mode when extracted text will show up full screen, which would
+ // immediately hide the newly created action bar and would be visually distracting.
+ if (!willExtract) {
+ ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
+ getEditor().mSelectionActionMode = startActionMode(actionModeCallback);
+ }
+
+ final boolean selectionStarted = getEditor().mSelectionActionMode != null || willExtract;
+ if (selectionStarted && !isTextSelectable()) {
+ // Show the IME to be able to replace text, except when selecting non editable text.
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ imm.showSoftInput(this, 0, null);
+ }
+ }
+
+ return selectionStarted;
+ }
+
+ private boolean extractedTextModeWillBeStarted() {
+ if (!(this instanceof ExtractEditText)) {
+ final InputMethodManager imm = InputMethodManager.peekInstance();
+ return imm != null && imm.isFullscreenMode();
+ }
+ return false;
+ }
+
+ /**
+ * @hide
+ */
+ protected void stopSelectionActionMode() {
+ if (getEditor().mSelectionActionMode != null) {
+ // This will hide the mSelectionModifierCursorController
+ getEditor().mSelectionActionMode.finish();
+ }
+ }
+
+ /**
+ * Paste clipboard content between min and max positions.
+ */
+ private void paste(int min, int max) {
+ ClipboardManager clipboard =
+ (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ ClipData clip = clipboard.getPrimaryClip();
+ if (clip != null) {
+ boolean didFirst = false;
+ for (int i=0; i<clip.getItemCount(); i++) {
+ CharSequence paste = clip.getItemAt(i).coerceToText(getContext());
+ if (paste != null) {
+ if (!didFirst) {
+ long minMax = prepareSpacesAroundPaste(min, max, paste);
+ min = extractRangeStartFromLong(minMax);
+ max = extractRangeEndFromLong(minMax);
+ Selection.setSelection((Spannable) mText, max);
+ ((Editable) mText).replace(min, max, paste);
+ didFirst = true;
+ } else {
+ ((Editable) mText).insert(getSelectionEnd(), "\n");
+ ((Editable) mText).insert(getSelectionEnd(), paste);
+ }
+ }
+ }
+ stopSelectionActionMode();
+ LAST_CUT_OR_COPY_TIME = 0;
+ }
+ }
+
+ private void setPrimaryClip(ClipData clip) {
+ ClipboardManager clipboard = (ClipboardManager) getContext().
+ getSystemService(Context.CLIPBOARD_SERVICE);
+ clipboard.setPrimaryClip(clip);
+ LAST_CUT_OR_COPY_TIME = SystemClock.uptimeMillis();
+ }
+
+ private void hideInsertionPointCursorController() {
+ // No need to create the controller to hide it.
+ if (getEditor().mInsertionPointCursorController != null) {
+ getEditor().mInsertionPointCursorController.hide();
+ }
+ }
+
+ /**
+ * Hides the insertion controller and stops text selection mode, hiding the selection controller
+ */
+ private void hideControllers() {
+ hideCursorControllers();
+ hideSpanControllers();
+ }
+
+ private void hideSpanControllers() {
+ if (mChangeWatcher != null) {
+ mChangeWatcher.hideControllers();
+ }
+ }
+
+ private void hideCursorControllers() {
+ if (getEditor().mSuggestionsPopupWindow != null && !getEditor().mSuggestionsPopupWindow.isShowingUp()) {
+ // Should be done before hide insertion point controller since it triggers a show of it
+ getEditor().mSuggestionsPopupWindow.hide();
+ }
+ hideInsertionPointCursorController();
+ stopSelectionActionMode();
+ }
+
+ /**
+ * Get the character offset closest to the specified absolute position. A typical use case is to
+ * pass the result of {@link MotionEvent#getX()} and {@link MotionEvent#getY()} to this method.
+ *
+ * @param x The horizontal absolute position of a point on screen
+ * @param y The vertical absolute position of a point on screen
+ * @return the character offset for the character whose position is closest to the specified
+ * position. Returns -1 if there is no layout.
+ */
+ public int getOffsetForPosition(float x, float y) {
+ if (getLayout() == null) return -1;
+ final int line = getLineAtCoordinate(y);
+ final int offset = getOffsetAtCoordinate(line, x);
+ return offset;
+ }
+
+ private float convertToLocalHorizontalCoordinate(float x) {
+ x -= getTotalPaddingLeft();
+ // Clamp the position to inside of the view.
+ x = Math.max(0.0f, x);
+ x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
+ x += getScrollX();
+ return x;
+ }
+
+ private int getLineAtCoordinate(float y) {
+ y -= getTotalPaddingTop();
+ // Clamp the position to inside of the view.
+ y = Math.max(0.0f, y);
+ y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
+ y += getScrollY();
+ return getLayout().getLineForVertical((int) y);
+ }
+
+ private int getOffsetAtCoordinate(int line, float x) {
+ x = convertToLocalHorizontalCoordinate(x);
+ return getLayout().getOffsetForHorizontal(line, x);
+ }
+
+ /** Returns true if the screen coordinates position (x,y) corresponds to a character displayed
+ * in the view. Returns false when the position is in the empty space of left/right of text.
+ */
+ private boolean isPositionOnText(float x, float y) {
+ if (getLayout() == null) return false;
+
+ final int line = getLineAtCoordinate(y);
+ x = convertToLocalHorizontalCoordinate(x);
+
+ if (x < getLayout().getLineLeft(line)) return false;
+ if (x > getLayout().getLineRight(line)) return false;
+ return true;
+ }
+
+ @Override
+ public boolean onDragEvent(DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ return mEditor != null && hasInsertionController();
+
+ case DragEvent.ACTION_DRAG_ENTERED:
+ TextView.this.requestFocus();
+ return true;
+
+ case DragEvent.ACTION_DRAG_LOCATION:
+ final int offset = getOffsetForPosition(event.getX(), event.getY());
+ Selection.setSelection((Spannable)mText, offset);
+ return true;
+
+ case DragEvent.ACTION_DROP:
+ onDrop(event);
+ return true;
+
+ case DragEvent.ACTION_DRAG_ENDED:
+ case DragEvent.ACTION_DRAG_EXITED:
+ default:
+ return true;
+ }
+ }
+
+ private void onDrop(DragEvent event) {
+ StringBuilder content = new StringBuilder("");
+ ClipData clipData = event.getClipData();
+ final int itemCount = clipData.getItemCount();
+ for (int i=0; i < itemCount; i++) {
+ Item item = clipData.getItemAt(i);
+ content.append(item.coerceToText(TextView.this.mContext));
+ }
+
+ final int offset = getOffsetForPosition(event.getX(), event.getY());
+
+ Object localState = event.getLocalState();
+ DragLocalState dragLocalState = null;
+ if (localState instanceof DragLocalState) {
+ dragLocalState = (DragLocalState) localState;
+ }
+ boolean dragDropIntoItself = dragLocalState != null &&
+ dragLocalState.sourceTextView == this;
+
+ if (dragDropIntoItself) {
+ if (offset >= dragLocalState.start && offset < dragLocalState.end) {
+ // A drop inside the original selection discards the drop.
+ return;
+ }
+ }
+
+ final int originalLength = mText.length();
+ long minMax = prepareSpacesAroundPaste(offset, offset, content);
+ int min = extractRangeStartFromLong(minMax);
+ int max = extractRangeEndFromLong(minMax);
+
+ Selection.setSelection((Spannable) mText, max);
+ replaceText_internal(min, max, content);
+
+ if (dragDropIntoItself) {
+ int dragSourceStart = dragLocalState.start;
+ int dragSourceEnd = dragLocalState.end;
+ if (max <= dragSourceStart) {
+ // Inserting text before selection has shifted positions
+ final int shift = mText.length() - originalLength;
+ dragSourceStart += shift;
+ dragSourceEnd += shift;
+ }
+
+ // Delete original selection
+ deleteText_internal(dragSourceStart, dragSourceEnd);
+
+ // Make sure we do not leave two adjacent spaces.
+ if ((dragSourceStart == 0 ||
+ Character.isSpaceChar(mTransformed.charAt(dragSourceStart - 1))) &&
+ (dragSourceStart == mText.length() ||
+ Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) {
+ final int pos = dragSourceStart == mText.length() ?
+ dragSourceStart - 1 : dragSourceStart;
+ deleteText_internal(pos, pos + 1);
+ }
+ }
+ }
+
+ /**
+ * @return True if this view supports insertion handles.
+ */
+ boolean hasInsertionController() {
+ return getEditor().mInsertionControllerEnabled;
+ }
+
+ /**
+ * @return True if this view supports selection handles.
+ */
+ boolean hasSelectionController() {
+ return getEditor().mSelectionControllerEnabled;
+ }
+
+ InsertionPointCursorController getInsertionController() {
+ if (!getEditor().mInsertionControllerEnabled) {
+ return null;
+ }
+
+ if (getEditor().mInsertionPointCursorController == null) {
+ getEditor().mInsertionPointCursorController = new InsertionPointCursorController();
+
+ final ViewTreeObserver observer = getViewTreeObserver();
+ observer.addOnTouchModeChangeListener(getEditor().mInsertionPointCursorController);
+ }
+
+ return getEditor().mInsertionPointCursorController;
+ }
+
+ SelectionModifierCursorController getSelectionController() {
+ if (!getEditor().mSelectionControllerEnabled) {
+ return null;
+ }
+
+ if (getEditor().mSelectionModifierCursorController == null) {
+ getEditor().mSelectionModifierCursorController = new SelectionModifierCursorController();
+
+ final ViewTreeObserver observer = getViewTreeObserver();
+ observer.addOnTouchModeChangeListener(getEditor().mSelectionModifierCursorController);
+ }
+
+ return getEditor().mSelectionModifierCursorController;
+ }
+
+ boolean isInBatchEditMode() {
+ if (mEditor == null) return false;
+ final InputMethodState ims = getEditor().mInputMethodState;
+ if (ims != null) {
+ return ims.mBatchEditNesting > 0;
+ }
+ return getEditor().mInBatchEditControllers;
+ }
+
+ @Override
+ public void onResolveTextDirection() {
+ if (hasPasswordTransformationMethod()) {
+ mTextDir = TextDirectionHeuristics.LOCALE;
+ return;
+ }
+
+ // Always need to resolve layout direction first
+ final boolean defaultIsRtl = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL);
+
+ // Now, we can select the heuristic
+ int textDir = getResolvedTextDirection();
+ switch (textDir) {
+ default:
+ case TEXT_DIRECTION_FIRST_STRONG:
+ mTextDir = (defaultIsRtl ? TextDirectionHeuristics.FIRSTSTRONG_RTL :
+ TextDirectionHeuristics.FIRSTSTRONG_LTR);
+ break;
+ case TEXT_DIRECTION_ANY_RTL:
+ mTextDir = TextDirectionHeuristics.ANYRTL_LTR;
+ break;
+ case TEXT_DIRECTION_LTR:
+ mTextDir = TextDirectionHeuristics.LTR;
+ break;
+ case TEXT_DIRECTION_RTL:
+ mTextDir = TextDirectionHeuristics.RTL;
+ break;
+ case TEXT_DIRECTION_LOCALE:
+ mTextDir = TextDirectionHeuristics.LOCALE;
+ break;
+ }
+ }
+
+ /**
+ * Subclasses will need to override this method to implement their own way of resolving
+ * drawables depending on the layout direction.
+ *
+ * A call to the super method will be required from the subclasses implementation.
+ */
+ protected void resolveDrawables() {
+ // No need to resolve twice
+ if (mResolvedDrawables) {
+ return;
+ }
+ // No drawable to resolve
+ if (mDrawables == null) {
+ return;
+ }
+ // No relative drawable to resolve
+ if (mDrawables.mDrawableStart == null && mDrawables.mDrawableEnd == null) {
+ mResolvedDrawables = true;
+ return;
+ }
+
+ Drawables dr = mDrawables;
+ switch(getResolvedLayoutDirection()) {
+ case LAYOUT_DIRECTION_RTL:
+ if (dr.mDrawableStart != null) {
+ dr.mDrawableRight = dr.mDrawableStart;
+
+ dr.mDrawableSizeRight = dr.mDrawableSizeStart;
+ dr.mDrawableHeightRight = dr.mDrawableHeightStart;
+ }
+ if (dr.mDrawableEnd != null) {
+ dr.mDrawableLeft = dr.mDrawableEnd;
+
+ dr.mDrawableSizeLeft = dr.mDrawableSizeEnd;
+ dr.mDrawableHeightLeft = dr.mDrawableHeightEnd;
+ }
+ break;
+
+ case LAYOUT_DIRECTION_LTR:
+ default:
+ if (dr.mDrawableStart != null) {
+ dr.mDrawableLeft = dr.mDrawableStart;
+
+ dr.mDrawableSizeLeft = dr.mDrawableSizeStart;
+ dr.mDrawableHeightLeft = dr.mDrawableHeightStart;
+ }
+ if (dr.mDrawableEnd != null) {
+ dr.mDrawableRight = dr.mDrawableEnd;
+
+ dr.mDrawableSizeRight = dr.mDrawableSizeEnd;
+ dr.mDrawableHeightRight = dr.mDrawableHeightEnd;
+ }
+ break;
+ }
+ mResolvedDrawables = true;
+ }
+
+ protected void resetResolvedDrawables() {
+ mResolvedDrawables = false;
+ }
+
+ /**
+ * @hide
+ */
+ protected void viewClicked(InputMethodManager imm) {
+ if (imm != null) {
+ imm.viewClicked(this);
+ }
+ }
+
+ /**
+ * Deletes the range of text [start, end[.
+ * @hide
+ */
+ protected void deleteText_internal(int start, int end) {
+ ((Editable) mText).delete(start, end);
+ }
+
+ /**
+ * Replaces the range of text [start, end[ by replacement text
+ * @hide
+ */
+ protected void replaceText_internal(int start, int end, CharSequence text) {
+ ((Editable) mText).replace(start, end, text);
+ }
+
+ /**
+ * Sets a span on the specified range of text
+ * @hide
+ */
+ protected void setSpan_internal(Object span, int start, int end, int flags) {
+ ((Editable) mText).setSpan(span, start, end, flags);
+ }
+
+ /**
+ * Moves the cursor to the specified offset position in text
+ * @hide
+ */
+ protected void setCursorPosition_internal(int start, int end) {
+ Selection.setSelection(((Editable) mText), start, end);
+ }
+
+ /**
+ * An Editor should be created as soon as any of the editable-specific fields (grouped
+ * inside the Editor object) is assigned to a non-default value.
+ * This method will create the Editor if needed.
+ *
+ * A standard TextView (as well as buttons, checkboxes...) should not qualify and hence will
+ * have a null Editor, unlike an EditText. Inconsistent in-between states will have an
+ * Editor for backward compatibility, as soon as one of these fields is assigned.
+ *
+ * Also note that for performance reasons, the mEditor is created when needed, but not
+ * reset when no more edit-specific fields are needed.
+ */
+ private void createEditorIfNeeded(String reason) {
+ if (mEditor == null) {
+ if (!(this instanceof EditText)) {
+ Log.e(LOG_TAG + " EDITOR", "Creating Editor on TextView. " + reason);
+ }
+ mEditor = new Editor();
+ } else {
+ if (!(this instanceof EditText)) {
+ Log.d(LOG_TAG + " EDITOR", "Redundant Editor creation. " + reason);
+ }
+ }
+ }
+
+ private Editor getEditor() {
+ if (mEditor == null) {
+ //createEditorIfNeeded("Problem: mEditor is not initialized!");
+ Log.e(LOG_TAG, "mEditor not initialized. Please send a bug report to debunne@");
+ }
+ return mEditor;
+ }
+
+ /**
+ * User interface state that is stored by TextView for implementing
+ * {@link View#onSaveInstanceState}.
+ */
+ public static class SavedState extends BaseSavedState {
+ int selStart;
+ int selEnd;
+ CharSequence text;
+ boolean frozenWithFocus;
+ CharSequence error;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(selStart);
+ out.writeInt(selEnd);
+ out.writeInt(frozenWithFocus ? 1 : 0);
+ TextUtils.writeToParcel(text, out, flags);
+
+ if (error == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ TextUtils.writeToParcel(error, out, flags);
+ }
+ }
+
+ @Override
+ public String toString() {
+ String str = "TextView.SavedState{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " start=" + selStart + " end=" + selEnd;
+ if (text != null) {
+ str += " text=" + text;
+ }
+ return str + "}";
+ }
+
+ @SuppressWarnings("hiding")
+ 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];
+ }
+ };
+
+ private SavedState(Parcel in) {
+ super(in);
+ selStart = in.readInt();
+ selEnd = in.readInt();
+ frozenWithFocus = (in.readInt() != 0);
+ text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+
+ if (in.readInt() != 0) {
+ error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ }
+ }
+ }
+
+ private static class CharWrapper implements CharSequence, GetChars, GraphicsOperations {
+ private char[] mChars;
+ private int mStart, mLength;
+
+ public CharWrapper(char[] chars, int start, int len) {
+ mChars = chars;
+ mStart = start;
+ mLength = len;
+ }
+
+ /* package */ void set(char[] chars, int start, int len) {
+ mChars = chars;
+ mStart = start;
+ mLength = len;
+ }
+
+ public int length() {
+ return mLength;
+ }
+
+ public char charAt(int off) {
+ return mChars[off + mStart];
+ }
+
+ @Override
+ public String toString() {
+ return new String(mChars, mStart, mLength);
+ }
+
+ public CharSequence subSequence(int start, int end) {
+ if (start < 0 || end < 0 || start > mLength || end > mLength) {
+ throw new IndexOutOfBoundsException(start + ", " + end);
+ }
+
+ return new String(mChars, start + mStart, end - start);
+ }
+
+ public void getChars(int start, int end, char[] buf, int off) {
+ if (start < 0 || end < 0 || start > mLength || end > mLength) {
+ throw new IndexOutOfBoundsException(start + ", " + end);
+ }
+
+ System.arraycopy(mChars, start + mStart, buf, off, end - start);
+ }
+
+ public void drawText(Canvas c, int start, int end,
+ float x, float y, Paint p) {
+ c.drawText(mChars, start + mStart, end - start, x, y, p);
+ }
+
+ public void drawTextRun(Canvas c, int start, int end,
+ int contextStart, int contextEnd, float x, float y, int flags, Paint p) {
+ int count = end - start;
+ int contextCount = contextEnd - contextStart;
+ c.drawTextRun(mChars, start + mStart, count, contextStart + mStart,
+ contextCount, x, y, flags, p);
+ }
+
+ public float measureText(int start, int end, Paint p) {
+ return p.measureText(mChars, start + mStart, end - start);
+ }
+
+ public int getTextWidths(int start, int end, float[] widths, Paint p) {
+ return p.getTextWidths(mChars, start + mStart, end - start, widths);
+ }
+
+ public float getTextRunAdvances(int start, int end, int contextStart,
+ int contextEnd, int flags, float[] advances, int advancesIndex,
+ Paint p) {
+ int count = end - start;
+ int contextCount = contextEnd - contextStart;
+ return p.getTextRunAdvances(mChars, start + mStart, count,
+ contextStart + mStart, contextCount, flags, advances,
+ advancesIndex);
+ }
+
+ public float getTextRunAdvances(int start, int end, int contextStart,
+ int contextEnd, int flags, float[] advances, int advancesIndex,
+ Paint p, int reserved) {
+ int count = end - start;
+ int contextCount = contextEnd - contextStart;
+ return p.getTextRunAdvances(mChars, start + mStart, count,
+ contextStart + mStart, contextCount, flags, advances,
+ advancesIndex, reserved);
+ }
+
+ public int getTextRunCursor(int contextStart, int contextEnd, int flags,
+ int offset, int cursorOpt, Paint p) {
+ int contextCount = contextEnd - contextStart;
+ return p.getTextRunCursor(mChars, contextStart + mStart,
+ contextCount, flags, offset + mStart, cursorOpt);
+ }
+ }
+
+ private static class ErrorPopup extends PopupWindow {
+ private boolean mAbove = false;
+ private final TextView mView;
+ private int mPopupInlineErrorBackgroundId = 0;
+ private int mPopupInlineErrorAboveBackgroundId = 0;
+
+ ErrorPopup(TextView v, int width, int height) {
+ super(v, width, height);
+ mView = v;
+ // Make sure the TextView has a background set as it will be used the first time it is
+ // shown and positionned. Initialized with below background, which should have
+ // dimensions identical to the above version for this to work (and is more likely).
+ mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
+ com.android.internal.R.styleable.Theme_errorMessageBackground);
+ mView.setBackgroundResource(mPopupInlineErrorBackgroundId);
+ }
+
+ void fixDirection(boolean above) {
+ mAbove = above;
+
+ if (above) {
+ mPopupInlineErrorAboveBackgroundId =
+ getResourceId(mPopupInlineErrorAboveBackgroundId,
+ com.android.internal.R.styleable.Theme_errorMessageAboveBackground);
+ } else {
+ mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
+ com.android.internal.R.styleable.Theme_errorMessageBackground);
+ }
+
+ mView.setBackgroundResource(above ? mPopupInlineErrorAboveBackgroundId :
+ mPopupInlineErrorBackgroundId);
+ }
+
+ private int getResourceId(int currentId, int index) {
+ if (currentId == 0) {
+ TypedArray styledAttributes = mView.getContext().obtainStyledAttributes(
+ R.styleable.Theme);
+ currentId = styledAttributes.getResourceId(index, 0);
+ styledAttributes.recycle();
+ }
+ return currentId;
+ }
+
+ @Override
+ public void update(int x, int y, int w, int h, boolean force) {
+ super.update(x, y, w, h, force);
+
+ boolean above = isAboveAnchor();
+ if (above != mAbove) {
+ fixDirection(above);
+ }
+ }
+ }
+
+ private class CorrectionHighlighter {
+ private final Path mPath = new Path();
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ private int mStart, mEnd;
+ private long mFadingStartTime;
+ private final static int FADE_OUT_DURATION = 400;
+
+ public CorrectionHighlighter() {
+ mPaint.setCompatibilityScaling(getResources().getCompatibilityInfo().applicationScale);
+ mPaint.setStyle(Paint.Style.FILL);
+ }
+
+ public void highlight(CorrectionInfo info) {
+ mStart = info.getOffset();
+ mEnd = mStart + info.getNewText().length();
+ mFadingStartTime = SystemClock.uptimeMillis();
+
+ if (mStart < 0 || mEnd < 0) {
+ stopAnimation();
+ }
+ }
+
+ public void draw(Canvas canvas, int cursorOffsetVertical) {
+ if (updatePath() && updatePaint()) {
+ if (cursorOffsetVertical != 0) {
+ canvas.translate(0, cursorOffsetVertical);
+ }
+
+ canvas.drawPath(mPath, mPaint);
+
+ if (cursorOffsetVertical != 0) {
+ canvas.translate(0, -cursorOffsetVertical);
+ }
+ invalidate(true); // TODO invalidate cursor region only
+ } else {
+ stopAnimation();
+ invalidate(false); // TODO invalidate cursor region only
+ }
+ }
+
+ private boolean updatePaint() {
+ final long duration = SystemClock.uptimeMillis() - mFadingStartTime;
+ if (duration > FADE_OUT_DURATION) return false;
+
+ final float coef = 1.0f - (float) duration / FADE_OUT_DURATION;
+ final int highlightColorAlpha = Color.alpha(mHighlightColor);
+ final int color = (mHighlightColor & 0x00FFFFFF) +
+ ((int) (highlightColorAlpha * coef) << 24);
+ mPaint.setColor(color);
+ return true;
+ }
+
+ private boolean updatePath() {
+ final Layout layout = TextView.this.mLayout;
+ if (layout == null) return false;
+
+ // Update in case text is edited while the animation is run
+ final int length = mText.length();
+ int start = Math.min(length, mStart);
+ int end = Math.min(length, mEnd);
+
+ mPath.reset();
+ TextView.this.mLayout.getSelectionPath(start, end, mPath);
+ return true;
+ }
+
+ private void invalidate(boolean delayed) {
+ if (TextView.this.mLayout == null) return;
+
+ synchronized (TEMP_RECTF) {
+ mPath.computeBounds(TEMP_RECTF, false);
+
+ int left = getCompoundPaddingLeft();
+ int top = getExtendedPaddingTop() + getVerticalOffset(true);
+
+ if (delayed) {
+ TextView.this.postInvalidateDelayed(16, // 60 Hz update
+ left + (int) TEMP_RECTF.left, top + (int) TEMP_RECTF.top,
+ left + (int) TEMP_RECTF.right, top + (int) TEMP_RECTF.bottom);
+ } else {
+ TextView.this.postInvalidate((int) TEMP_RECTF.left, (int) TEMP_RECTF.top,
+ (int) TEMP_RECTF.right, (int) TEMP_RECTF.bottom);
+ }
+ }
+ }
+
+ private void stopAnimation() {
+ TextView.this.getEditor().mCorrectionHighlighter = null;
+ }
+ }
+
+ private static final class Marquee extends Handler {
+ // TODO: Add an option to configure this
+ private static final float MARQUEE_DELTA_MAX = 0.07f;
+ private static final int MARQUEE_DELAY = 1200;
+ private static final int MARQUEE_RESTART_DELAY = 1200;
+ private static final int MARQUEE_RESOLUTION = 1000 / 30;
+ private static final int MARQUEE_PIXELS_PER_SECOND = 30;
+
+ private static final byte MARQUEE_STOPPED = 0x0;
+ private static final byte MARQUEE_STARTING = 0x1;
+ private static final byte MARQUEE_RUNNING = 0x2;
+
+ private static final int MESSAGE_START = 0x1;
+ private static final int MESSAGE_TICK = 0x2;
+ private static final int MESSAGE_RESTART = 0x3;
+
+ private final WeakReference<TextView> mView;
+
+ private byte mStatus = MARQUEE_STOPPED;
+ private final float mScrollUnit;
+ private float mMaxScroll;
+ float mMaxFadeScroll;
+ private float mGhostStart;
+ private float mGhostOffset;
+ private float mFadeStop;
+ private int mRepeatLimit;
+
+ float mScroll;
+
+ Marquee(TextView v) {
+ final float density = v.getContext().getResources().getDisplayMetrics().density;
+ mScrollUnit = (MARQUEE_PIXELS_PER_SECOND * density) / MARQUEE_RESOLUTION;
+ mView = new WeakReference<TextView>(v);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_START:
+ mStatus = MARQUEE_RUNNING;
+ tick();
+ break;
+ case MESSAGE_TICK:
+ tick();
+ break;
+ case MESSAGE_RESTART:
+ if (mStatus == MARQUEE_RUNNING) {
+ if (mRepeatLimit >= 0) {
+ mRepeatLimit--;
+ }
+ start(mRepeatLimit);
+ }
+ break;
+ }
+ }
+
+ void tick() {
+ if (mStatus != MARQUEE_RUNNING) {
+ return;
+ }
+
+ removeMessages(MESSAGE_TICK);
+
+ final TextView textView = mView.get();
+ if (textView != null && (textView.isFocused() || textView.isSelected())) {
+ mScroll += mScrollUnit;
+ if (mScroll > mMaxScroll) {
+ mScroll = mMaxScroll;
+ sendEmptyMessageDelayed(MESSAGE_RESTART, MARQUEE_RESTART_DELAY);
+ } else {
+ sendEmptyMessageDelayed(MESSAGE_TICK, MARQUEE_RESOLUTION);
+ }
+ textView.invalidate();
+ }
+ }
+
+ void stop() {
+ mStatus = MARQUEE_STOPPED;
+ removeMessages(MESSAGE_START);
+ removeMessages(MESSAGE_RESTART);
+ removeMessages(MESSAGE_TICK);
+ resetScroll();
+ }
+
+ private void resetScroll() {
+ mScroll = 0.0f;
+ final TextView textView = mView.get();
+ if (textView != null) textView.invalidate();
+ }
+
+ void start(int repeatLimit) {
+ if (repeatLimit == 0) {
+ stop();
+ return;
+ }
+ mRepeatLimit = repeatLimit;
+ final TextView textView = mView.get();
+ if (textView != null && textView.mLayout != null) {
+ mStatus = MARQUEE_STARTING;
+ mScroll = 0.0f;
+ final int textWidth = textView.getWidth() - textView.getCompoundPaddingLeft() -
+ textView.getCompoundPaddingRight();
+ final float lineWidth = textView.mLayout.getLineWidth(0);
+ final float gap = textWidth / 3.0f;
+ mGhostStart = lineWidth - textWidth + gap;
+ mMaxScroll = mGhostStart + textWidth;
+ mGhostOffset = lineWidth + gap;
+ mFadeStop = lineWidth + textWidth / 6.0f;
+ mMaxFadeScroll = mGhostStart + lineWidth + lineWidth;
+
+ textView.invalidate();
+ sendEmptyMessageDelayed(MESSAGE_START, MARQUEE_DELAY);
+ }
+ }
+
+ float getGhostOffset() {
+ return mGhostOffset;
+ }
+
+ boolean shouldDrawLeftFade() {
+ return mScroll <= mFadeStop;
+ }
+
+ boolean shouldDrawGhost() {
+ return mStatus == MARQUEE_RUNNING && mScroll > mGhostStart;
+ }
+
+ boolean isRunning() {
+ return mStatus == MARQUEE_RUNNING;
+ }
+
+ boolean isStopped() {
+ return mStatus == MARQUEE_STOPPED;
+ }
+ }
+
+ /**
+ * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
+ * pop-up should be displayed.
+ */
+ private class EasyEditSpanController {
+
+ private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs
+
+ private EasyEditPopupWindow mPopupWindow;
+
+ private EasyEditSpan mEasyEditSpan;
+
+ private Runnable mHidePopup;
+
+ private void hide() {
+ if (mPopupWindow != null) {
+ mPopupWindow.hide();
+ TextView.this.removeCallbacks(mHidePopup);
+ }
+ removeSpans(mText);
+ mEasyEditSpan = null;
+ }
+
+ /**
+ * Monitors the changes in the text.
+ *
+ * <p>{@link ChangeWatcher#onSpanAdded(Spannable, Object, int, int)} cannot be used,
+ * as the notifications are not sent when a spannable (with spans) is inserted.
+ */
+ public void onTextChange(CharSequence buffer) {
+ adjustSpans(mText);
+
+ if (getWindowVisibility() != View.VISIBLE) {
+ // The window is not visible yet, ignore the text change.
+ return;
+ }
+
+ if (mLayout == null) {
+ // The view has not been layout yet, ignore the text change
+ return;
+ }
+
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (!(TextView.this instanceof ExtractEditText)
+ && imm != null && imm.isFullscreenMode()) {
+ // The input is in extract mode. We do not have to handle the easy edit in the
+ // original TextView, as the ExtractEditText will do
+ return;
+ }
+
+ // Remove the current easy edit span, as the text changed, and remove the pop-up
+ // (if any)
+ if (mEasyEditSpan != null) {
+ if (mText instanceof Spannable) {
+ ((Spannable) mText).removeSpan(mEasyEditSpan);
+ }
+ mEasyEditSpan = null;
+ }
+ if (mPopupWindow != null && mPopupWindow.isShowing()) {
+ mPopupWindow.hide();
+ }
+
+ // Display the new easy edit span (if any).
+ if (buffer instanceof Spanned) {
+ mEasyEditSpan = getSpan((Spanned) buffer);
+ if (mEasyEditSpan != null) {
+ if (mPopupWindow == null) {
+ mPopupWindow = new EasyEditPopupWindow();
+ mHidePopup = new Runnable() {
+ @Override
+ public void run() {
+ hide();
+ }
+ };
+ }
+ mPopupWindow.show(mEasyEditSpan);
+ TextView.this.removeCallbacks(mHidePopup);
+ TextView.this.postDelayed(mHidePopup, DISPLAY_TIMEOUT_MS);
+ }
+ }
+ }
+
+ /**
+ * Adjusts the spans by removing all of them except the last one.
+ */
+ private void adjustSpans(CharSequence buffer) {
+ // This method enforces that only one easy edit span is attached to the text.
+ // A better way to enforce this would be to listen for onSpanAdded, but this method
+ // cannot be used in this scenario as no notification is triggered when a text with
+ // spans is inserted into a text.
+ if (buffer instanceof Spannable) {
+ Spannable spannable = (Spannable) buffer;
+ EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(),
+ EasyEditSpan.class);
+ for (int i = 0; i < spans.length - 1; i++) {
+ spannable.removeSpan(spans[i]);
+ }
+ }
+ }
+
+ /**
+ * Removes all the {@link EasyEditSpan} currently attached.
+ */
+ private void removeSpans(CharSequence buffer) {
+ if (buffer instanceof Spannable) {
+ Spannable spannable = (Spannable) buffer;
+ EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(),
+ EasyEditSpan.class);
+ for (int i = 0; i < spans.length; i++) {
+ spannable.removeSpan(spans[i]);
+ }
+ }
+ }
+
+ private EasyEditSpan getSpan(Spanned spanned) {
+ EasyEditSpan[] easyEditSpans = spanned.getSpans(0, spanned.length(),
+ EasyEditSpan.class);
+ if (easyEditSpans.length == 0) {
+ return null;
+ } else {
+ return easyEditSpans[0];
+ }
+ }
+ }
+
+ /**
+ * Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled
+ * by {@link EasyEditSpanController}.
+ */
+ private class EasyEditPopupWindow extends PinnedPopupWindow
+ implements OnClickListener {
+ private static final int POPUP_TEXT_LAYOUT =
+ com.android.internal.R.layout.text_edit_action_popup_text;
+ private TextView mDeleteTextView;
+ private EasyEditSpan mEasyEditSpan;
+
+ @Override
+ protected void createPopupWindow() {
+ mPopupWindow = new PopupWindow(TextView.this.mContext, null,
+ com.android.internal.R.attr.textSelectHandleWindowStyle);
+ mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+ mPopupWindow.setClippingEnabled(true);
+ }
+
+ @Override
+ protected void initContentView() {
+ LinearLayout linearLayout = new LinearLayout(TextView.this.getContext());
+ linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+ mContentView = linearLayout;
+ mContentView.setBackgroundResource(
+ com.android.internal.R.drawable.text_edit_side_paste_window);
+
+ LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
+ getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ LayoutParams wrapContent = new LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mDeleteTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
+ mDeleteTextView.setLayoutParams(wrapContent);
+ mDeleteTextView.setText(com.android.internal.R.string.delete);
+ mDeleteTextView.setOnClickListener(this);
+ mContentView.addView(mDeleteTextView);
+ }
+
+ public void show(EasyEditSpan easyEditSpan) {
+ mEasyEditSpan = easyEditSpan;
+ super.show();
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == mDeleteTextView) {
+ Editable editable = (Editable) mText;
+ int start = editable.getSpanStart(mEasyEditSpan);
+ int end = editable.getSpanEnd(mEasyEditSpan);
+ if (start >= 0 && end >= 0) {
+ deleteText_internal(start, end);
+ }
+ }
+ }
+
+ @Override
+ protected int getTextOffset() {
+ // Place the pop-up at the end of the span
+ Editable editable = (Editable) mText;
+ return editable.getSpanEnd(mEasyEditSpan);
+ }
+
+ @Override
+ protected int getVerticalLocalPosition(int line) {
+ return mLayout.getLineBottom(line);
+ }
+
+ @Override
+ protected int clipVertically(int positionY) {
+ // As we display the pop-up below the span, no vertical clipping is required.
+ return positionY;
+ }
+ }
+
+ private class ChangeWatcher implements TextWatcher, SpanWatcher {
+
+ private CharSequence mBeforeText;
+
+ private EasyEditSpanController mEasyEditSpanController;
+
+ private ChangeWatcher() {
+ mEasyEditSpanController = new EasyEditSpanController();
+ }
+
+ public void beforeTextChanged(CharSequence buffer, int start,
+ int before, int after) {
+ if (DEBUG_EXTRACT) Log.v(LOG_TAG, "beforeTextChanged start=" + start
+ + " before=" + before + " after=" + after + ": " + buffer);
+
+ if (AccessibilityManager.getInstance(mContext).isEnabled()
+ && !isPasswordInputType(getInputType())
+ && !hasPasswordTransformationMethod()) {
+ mBeforeText = buffer.toString();
+ }
+
+ TextView.this.sendBeforeTextChanged(buffer, start, before, after);
+ }
+
+ public void onTextChanged(CharSequence buffer, int start,
+ int before, int after) {
+ if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onTextChanged start=" + start
+ + " before=" + before + " after=" + after + ": " + buffer);
+ TextView.this.handleTextChanged(buffer, start, before, after);
+
+ mEasyEditSpanController.onTextChange(buffer);
+
+ if (AccessibilityManager.getInstance(mContext).isEnabled() &&
+ (isFocused() || isSelected() && isShown())) {
+ sendAccessibilityEventTypeViewTextChanged(mBeforeText, start, before, after);
+ mBeforeText = null;
+ }
+ }
+
+ public void afterTextChanged(Editable buffer) {
+ if (DEBUG_EXTRACT) Log.v(LOG_TAG, "afterTextChanged: " + buffer);
+ TextView.this.sendAfterTextChanged(buffer);
+
+ if (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0) {
+ MetaKeyKeyListener.stopSelecting(TextView.this, buffer);
+ }
+ }
+
+ public void onSpanChanged(Spannable buf,
+ Object what, int s, int e, int st, int en) {
+ if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onSpanChanged s=" + s + " e=" + e
+ + " st=" + st + " en=" + en + " what=" + what + ": " + buf);
+ TextView.this.spanChange(buf, what, s, st, e, en);
+ }
+
+ public void onSpanAdded(Spannable buf, Object what, int s, int e) {
+ if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onSpanAdded s=" + s + " e=" + e
+ + " what=" + what + ": " + buf);
+ TextView.this.spanChange(buf, what, -1, s, -1, e);
+ }
+
+ public void onSpanRemoved(Spannable buf, Object what, int s, int e) {
+ if (DEBUG_EXTRACT) Log.v(LOG_TAG, "onSpanRemoved s=" + s + " e=" + e
+ + " what=" + what + ": " + buf);
+ TextView.this.spanChange(buf, what, s, -1, e, -1);
+ }
+
+ private void hideControllers() {
+ mEasyEditSpanController.hide();
+ }
+ }
+
+ private static class Blink extends Handler implements Runnable {
+ private final WeakReference<TextView> mView;
+ private boolean mCancelled;
+
+ public Blink(TextView v) {
+ mView = new WeakReference<TextView>(v);
+ }
+
+ public void run() {
+ if (mCancelled) {
+ return;
+ }
+
+ removeCallbacks(Blink.this);
+
+ TextView tv = mView.get();
+
+ if (tv != null && tv.shouldBlink()) {
+ if (tv.mLayout != null) {
+ tv.invalidateCursorPath();
+ }
+
+ postAtTime(this, SystemClock.uptimeMillis() + BLINK);
+ }
+ }
+
+ void cancel() {
+ if (!mCancelled) {
+ removeCallbacks(Blink.this);
+ mCancelled = true;
+ }
+ }
+
+ void uncancel() {
+ mCancelled = false;
+ }
+ }
+
+ private static class DragLocalState {
+ public TextView sourceTextView;
+ public int start, end;
+
+ public DragLocalState(TextView sourceTextView, int start, int end) {
+ this.sourceTextView = sourceTextView;
+ this.start = start;
+ this.end = end;
+ }
+ }
+
private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
// 3 handles
// 3 ActionPopup [replace, suggestion, easyedit] (suggestionsPopup first hides the others)
@@ -9324,6 +9700,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mPositionX, mPositionY;
private int mNumberOfListeners;
private boolean mScrollHasChanged;
+ final int[] mTempCoords = new int[2];
public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
if (mNumberOfListeners == 0) {
@@ -9402,62 +9779,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- private boolean isPositionVisible(int positionX, int positionY) {
- synchronized (sTmpPosition) {
- final float[] position = sTmpPosition;
- position[0] = positionX;
- position[1] = positionY;
- View view = this;
-
- while (view != null) {
- if (view != this) {
- // Local scroll is already taken into account in positionX/Y
- position[0] -= view.getScrollX();
- position[1] -= view.getScrollY();
- }
-
- if (position[0] < 0 || position[1] < 0 ||
- position[0] > view.getWidth() || position[1] > view.getHeight()) {
- return false;
- }
-
- if (!view.getMatrix().isIdentity()) {
- view.getMatrix().mapPoints(position);
- }
-
- position[0] += view.getLeft();
- position[1] += view.getTop();
-
- final ViewParent parent = view.getParent();
- if (parent instanceof View) {
- view = (View) parent;
- } else {
- // We've reached the ViewRoot, stop iterating
- view = null;
- }
- }
- }
-
- // We've been able to walk up the view hierarchy and the position was never clipped
- return true;
- }
-
- private boolean isOffsetVisible(int offset) {
- final int line = mLayout.getLineForOffset(offset);
- final int lineBottom = mLayout.getLineBottom(line);
- final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
- return isPositionVisible(primaryHorizontal + viewportToContentHorizontalOffset(),
- lineBottom + viewportToContentVerticalOffset());
- }
-
- @Override
- protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
- super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
- if (mPositionListener != null) {
- mPositionListener.onScrollChanged();
- }
- }
-
private abstract class PinnedPopupWindow implements TextViewPositionListener {
protected PopupWindow mPopupWindow;
protected ViewGroup mContentView;
@@ -9585,7 +9906,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
TextView.this.getPositionListener().removeSubscriber(SuggestionsPopupWindow.this);
// Safe cast since show() checks that mText is an Editable
- ((Spannable) mText).removeSpan(mSuggestionRangeSpan);
+ ((Spannable) mText).removeSpan(getEditor().mSuggestionRangeSpan);
setCursorVisible(mCursorWasVisibleBeforeSuggestions);
if (hasInsertionController()) {
@@ -9595,7 +9916,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
public SuggestionsPopupWindow() {
- mCursorWasVisibleBeforeSuggestions = mCursorVisible;
+ mCursorWasVisibleBeforeSuggestions = getEditor().mCursorVisible;
mSuggestionSpanComparator = new SuggestionSpanComparator();
mSpansLengths = new HashMap<SuggestionSpan, Integer>();
}
@@ -9733,7 +10054,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (!(mText instanceof Editable)) return;
if (updateSuggestions()) {
- mCursorWasVisibleBeforeSuggestions = mCursorVisible;
+ mCursorWasVisibleBeforeSuggestions = getEditor().mCursorVisible;
setCursorVisible(false);
mIsShowingUp = true;
super.show();
@@ -9888,17 +10209,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mNumberOfSuggestions++;
- if (mSuggestionRangeSpan == null) mSuggestionRangeSpan = new SuggestionRangeSpan();
+ if (getEditor().mSuggestionRangeSpan == null) getEditor().mSuggestionRangeSpan = new SuggestionRangeSpan();
if (underlineColor == 0) {
// Fallback on the default highlight color when the first span does not provide one
- mSuggestionRangeSpan.setBackgroundColor(mHighlightColor);
+ getEditor().mSuggestionRangeSpan.setBackgroundColor(mHighlightColor);
} else {
final float BACKGROUND_TRANSPARENCY = 0.4f;
final int newAlpha = (int) (Color.alpha(underlineColor) * BACKGROUND_TRANSPARENCY);
- mSuggestionRangeSpan.setBackgroundColor(
+ getEditor().mSuggestionRangeSpan.setBackgroundColor(
(underlineColor & 0x00FFFFFF) + (newAlpha << 24));
}
- spannable.setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
+ spannable.setSpan(getEditor().mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mSuggestionsAdapter.notifyDataSetChanged();
@@ -9931,8 +10252,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
SuggestionInfo suggestionInfo = mSuggestionInfos[position];
if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
- final int spanUnionStart = editable.getSpanStart(mSuggestionRangeSpan);
- int spanUnionEnd = editable.getSpanEnd(mSuggestionRangeSpan);
+ final int spanUnionStart = editable.getSpanStart(getEditor().mSuggestionRangeSpan);
+ int spanUnionEnd = editable.getSpanEnd(getEditor().mSuggestionRangeSpan);
if (spanUnionStart >= 0 && spanUnionEnd > spanUnionStart) {
// Do not leave two adjacent spaces after deletion, or one at beginning of text
if (spanUnionEnd < editable.length() &&
@@ -10032,209 +10353,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
- * Removes the suggestion spans.
- */
- CharSequence removeSuggestionSpans(CharSequence text) {
- if (text instanceof Spanned) {
- Spannable spannable;
- if (text instanceof Spannable) {
- spannable = (Spannable) text;
- } else {
- spannable = new SpannableString(text);
- text = spannable;
- }
-
- SuggestionSpan[] spans = spannable.getSpans(0, text.length(), SuggestionSpan.class);
- for (int i = 0; i < spans.length; i++) {
- spannable.removeSpan(spans[i]);
- }
- }
- return text;
- }
-
- void showSuggestions() {
- if (mSuggestionsPopupWindow == null) {
- mSuggestionsPopupWindow = new SuggestionsPopupWindow();
- }
- hideControllers();
- mSuggestionsPopupWindow.show();
- }
-
- boolean areSuggestionsShown() {
- return mSuggestionsPopupWindow != null && mSuggestionsPopupWindow.isShowing();
- }
-
- /**
- * Return whether or not suggestions are enabled on this TextView. The suggestions are generated
- * by the IME or by the spell checker as the user types. This is done by adding
- * {@link SuggestionSpan}s to the text.
- *
- * When suggestions are enabled (default), this list of suggestions will be displayed when the
- * user asks for them on these parts of the text. This value depends on the inputType of this
- * TextView.
- *
- * The class of the input type must be {@link InputType#TYPE_CLASS_TEXT}.
- *
- * In addition, the type variation must be one of
- * {@link InputType#TYPE_TEXT_VARIATION_NORMAL},
- * {@link InputType#TYPE_TEXT_VARIATION_EMAIL_SUBJECT},
- * {@link InputType#TYPE_TEXT_VARIATION_LONG_MESSAGE},
- * {@link InputType#TYPE_TEXT_VARIATION_SHORT_MESSAGE} or
- * {@link InputType#TYPE_TEXT_VARIATION_WEB_EDIT_TEXT}.
- *
- * And finally, the {@link InputType#TYPE_TEXT_FLAG_NO_SUGGESTIONS} flag must <i>not</i> be set.
- *
- * @return true if the suggestions popup window is enabled, based on the inputType.
- */
- public boolean isSuggestionsEnabled() {
- if ((mInputType & InputType.TYPE_MASK_CLASS) != InputType.TYPE_CLASS_TEXT) return false;
- if ((mInputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) > 0) return false;
-
- final int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
- return (variation == EditorInfo.TYPE_TEXT_VARIATION_NORMAL ||
- variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT ||
- variation == EditorInfo.TYPE_TEXT_VARIATION_LONG_MESSAGE ||
- variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE ||
- variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT);
- }
-
- /**
- * If provided, this ActionMode.Callback will be used to create the ActionMode when text
- * selection is initiated in this View.
- *
- * The standard implementation populates the menu with a subset of Select All, Cut, Copy and
- * Paste actions, depending on what this View supports.
- *
- * A custom implementation can add new entries in the default menu in its
- * {@link android.view.ActionMode.Callback#onPrepareActionMode(ActionMode, Menu)} method. The
- * default actions can also be removed from the menu using {@link Menu#removeItem(int)} and
- * passing {@link android.R.id#selectAll}, {@link android.R.id#cut}, {@link android.R.id#copy}
- * or {@link android.R.id#paste} ids as parameters.
- *
- * Returning false from
- * {@link android.view.ActionMode.Callback#onCreateActionMode(ActionMode, Menu)} will prevent
- * the action mode from being started.
- *
- * Action click events should be handled by the custom implementation of
- * {@link android.view.ActionMode.Callback#onActionItemClicked(ActionMode, MenuItem)}.
- *
- * Note that text selection mode is not started when a TextView receives focus and the
- * {@link android.R.attr#selectAllOnFocus} flag has been set. The content is highlighted in
- * that case, to allow for quick replacement.
- */
- public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
- mCustomSelectionActionModeCallback = actionModeCallback;
- }
-
- /**
- * Retrieves the value set in {@link #setCustomSelectionActionModeCallback}. Default is null.
- *
- * @return The current custom selection callback.
- */
- public ActionMode.Callback getCustomSelectionActionModeCallback() {
- return mCustomSelectionActionModeCallback;
- }
-
- /**
- *
- * @return true if the selection mode was actually started.
- */
- private boolean startSelectionActionMode() {
- if (mSelectionActionMode != null) {
- // Selection action mode is already started
- return false;
- }
-
- if (!canSelectText() || !requestFocus()) {
- Log.w(LOG_TAG, "TextView does not support text selection. Action mode cancelled.");
- return false;
- }
-
- if (!hasSelection()) {
- // There may already be a selection on device rotation
- if (!selectCurrentWord()) {
- // No word found under cursor or text selection not permitted.
- return false;
- }
- }
-
- boolean willExtract = extractedTextModeWillBeStarted();
-
- // Do not start the action mode when extracted text will show up full screen, which would
- // immediately hide the newly created action bar and would be visually distracting.
- if (!willExtract) {
- ActionMode.Callback actionModeCallback = new SelectionActionModeCallback();
- mSelectionActionMode = startActionMode(actionModeCallback);
- }
-
- final boolean selectionStarted = mSelectionActionMode != null || willExtract;
- if (selectionStarted && !mTextIsSelectable) {
- // Show the IME to be able to replace text, except when selecting non editable text.
- final InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- imm.showSoftInput(this, 0, null);
- }
- }
-
- return selectionStarted;
- }
-
- private boolean extractedTextModeWillBeStarted() {
- if (!(this instanceof ExtractEditText)) {
- final InputMethodManager imm = InputMethodManager.peekInstance();
- return imm != null && imm.isFullscreenMode();
- }
- return false;
- }
-
- /**
- * @hide
- */
- protected void stopSelectionActionMode() {
- if (mSelectionActionMode != null) {
- // This will hide the mSelectionModifierCursorController
- mSelectionActionMode.finish();
- }
- }
-
- /**
- * Paste clipboard content between min and max positions.
- */
- private void paste(int min, int max) {
- ClipboardManager clipboard =
- (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clip = clipboard.getPrimaryClip();
- if (clip != null) {
- boolean didFirst = false;
- for (int i=0; i<clip.getItemCount(); i++) {
- CharSequence paste = clip.getItemAt(i).coerceToText(getContext());
- if (paste != null) {
- if (!didFirst) {
- long minMax = prepareSpacesAroundPaste(min, max, paste);
- min = extractRangeStartFromLong(minMax);
- max = extractRangeEndFromLong(minMax);
- Selection.setSelection((Spannable) mText, max);
- ((Editable) mText).replace(min, max, paste);
- didFirst = true;
- } else {
- ((Editable) mText).insert(getSelectionEnd(), "\n");
- ((Editable) mText).insert(getSelectionEnd(), paste);
- }
- }
- }
- stopSelectionActionMode();
- sLastCutOrCopyTime = 0;
- }
- }
-
- private void setPrimaryClip(ClipData clip) {
- ClipboardManager clipboard = (ClipboardManager) getContext().
- getSystemService(Context.CLIPBOARD_SERVICE);
- clipboard.setPrimaryClip(clip);
- sLastCutOrCopyTime = SystemClock.uptimeMillis();
- }
-
- /**
* An ActionMode Callback class that is used to provide actions while in text selection mode.
*
* The default callback provides a subset of Select All, Cut, Copy and Paste actions, depending
@@ -10250,9 +10368,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean allowText = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
- mode.setTitle(allowText ?
- mContext.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
+ mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
mode.setSubtitle(null);
+ mode.setTitleOptionalHint(true);
int selectAllIconId = 0; // No icon by default
if (!allowText) {
@@ -10296,8 +10414,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
styledAttributes.recycle();
- if (mCustomSelectionActionModeCallback != null) {
- if (!mCustomSelectionActionModeCallback.onCreateActionMode(mode, menu)) {
+ if (getEditor().mCustomSelectionActionModeCallback != null) {
+ if (!getEditor().mCustomSelectionActionModeCallback.onCreateActionMode(mode, menu)) {
// The custom mode can choose to cancel the action mode
return false;
}
@@ -10313,16 +10431,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- if (mCustomSelectionActionModeCallback != null) {
- return mCustomSelectionActionModeCallback.onPrepareActionMode(mode, menu);
+ if (getEditor().mCustomSelectionActionModeCallback != null) {
+ return getEditor().mCustomSelectionActionModeCallback.onPrepareActionMode(mode, menu);
}
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- if (mCustomSelectionActionModeCallback != null &&
- mCustomSelectionActionModeCallback.onActionItemClicked(mode, item)) {
+ if (getEditor().mCustomSelectionActionModeCallback != null &&
+ getEditor().mCustomSelectionActionModeCallback.onActionItemClicked(mode, item)) {
return true;
}
return onTextContextMenuItem(item.getItemId());
@@ -10330,16 +10448,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public void onDestroyActionMode(ActionMode mode) {
- if (mCustomSelectionActionModeCallback != null) {
- mCustomSelectionActionModeCallback.onDestroyActionMode(mode);
+ if (getEditor().mCustomSelectionActionModeCallback != null) {
+ getEditor().mCustomSelectionActionModeCallback.onDestroyActionMode(mode);
}
Selection.setSelection((Spannable) mText, getSelectionEnd());
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.hide();
+ if (getEditor().mSelectionModifierCursorController != null) {
+ getEditor().mSelectionModifierCursorController.hide();
}
- mSelectionActionMode = null;
+ getEditor().mSelectionActionMode = null;
}
}
@@ -10353,7 +10471,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
protected void createPopupWindow() {
mPopupWindow = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
- mPopupWindow.setClippingEnabled(true);
+ mPopupWindow.setClippingEnabled(true);
}
@Override
@@ -10753,7 +10871,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void show() {
super.show();
- final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
+ final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - LAST_CUT_OR_COPY_TIME;
if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
showActionPopupWindow(0);
}
@@ -10767,13 +10885,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void hideAfterDelay() {
- removeHiderCallback();
if (mHider == null) {
mHider = new Runnable() {
public void run() {
hide();
}
};
+ } else {
+ removeHiderCallback();
}
TextView.this.postDelayed(mHider, DELAY_BEFORE_HANDLE_FADES_OUT);
}
@@ -10994,12 +11113,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private InsertionHandleView getHandle() {
- if (mSelectHandleCenter == null) {
- mSelectHandleCenter = mContext.getResources().getDrawable(
+ if (getEditor().mSelectHandleCenter == null) {
+ getEditor().mSelectHandleCenter = mContext.getResources().getDrawable(
mTextSelectHandleRes);
}
if (mHandle == null) {
- mHandle = new InsertionHandleView(mSelectHandleCenter);
+ mHandle = new InsertionHandleView(getEditor().mSelectHandleCenter);
}
return mHandle;
}
@@ -11040,12 +11159,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void initDrawables() {
- if (mSelectHandleLeft == null) {
- mSelectHandleLeft = mContext.getResources().getDrawable(
+ if (getEditor().mSelectHandleLeft == null) {
+ getEditor().mSelectHandleLeft = mContext.getResources().getDrawable(
mTextSelectHandleLeftRes);
}
- if (mSelectHandleRight == null) {
- mSelectHandleRight = mContext.getResources().getDrawable(
+ if (getEditor().mSelectHandleRight == null) {
+ getEditor().mSelectHandleRight = mContext.getResources().getDrawable(
mTextSelectHandleRightRes);
}
}
@@ -11053,10 +11172,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void initHandles() {
// Lazy object creation has to be done before updatePosition() is called.
if (mStartHandle == null) {
- mStartHandle = new SelectionStartHandleView(mSelectHandleLeft, mSelectHandleRight);
+ mStartHandle = new SelectionStartHandleView(getEditor().mSelectHandleLeft, getEditor().mSelectHandleRight);
}
if (mEndHandle == null) {
- mEndHandle = new SelectionEndHandleView(mSelectHandleRight, mSelectHandleLeft);
+ mEndHandle = new SelectionEndHandleView(getEditor().mSelectHandleRight, getEditor().mSelectHandleLeft);
}
mStartHandle.show();
@@ -11101,7 +11220,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (stayedInArea && isPositionOnText(x, y)) {
startSelectionActionMode();
- mDiscardNextActionUp = true;
+ getEditor().mDiscardNextActionUp = true;
}
}
}
@@ -11190,461 +11309,484 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- private void hideInsertionPointCursorController() {
- // No need to create the controller to hide it.
- if (mInsertionPointCursorController != null) {
- mInsertionPointCursorController.hide();
- }
+ static class InputContentType {
+ int imeOptions = EditorInfo.IME_NULL;
+ String privateImeOptions;
+ CharSequence imeActionLabel;
+ int imeActionId;
+ Bundle extras;
+ OnEditorActionListener onEditorActionListener;
+ boolean enterDown;
}
- /**
- * Hides the insertion controller and stops text selection mode, hiding the selection controller
- */
- private void hideControllers() {
- hideCursorControllers();
- hideSpanControllers();
+ static class InputMethodState {
+ Rect mCursorRectInWindow = new Rect();
+ RectF mTmpRectF = new RectF();
+ float[] mTmpOffset = new float[2];
+ ExtractedTextRequest mExtracting;
+ final ExtractedText mTmpExtracted = new ExtractedText();
+ int mBatchEditNesting;
+ boolean mCursorChanged;
+ boolean mSelectionModeChanged;
+ boolean mContentChanged;
+ int mChangedStart, mChangedEnd, mChangedDelta;
}
- private void hideSpanControllers() {
- if (mChangeWatcher != null) {
- mChangeWatcher.hideControllers();
- }
- }
+ private class Editor {
+ // Cursor Controllers.
+ InsertionPointCursorController mInsertionPointCursorController;
+ SelectionModifierCursorController mSelectionModifierCursorController;
+ ActionMode mSelectionActionMode;
+ boolean mInsertionControllerEnabled;
+ boolean mSelectionControllerEnabled;
- private void hideCursorControllers() {
- if (mSuggestionsPopupWindow != null && !mSuggestionsPopupWindow.isShowingUp()) {
- // Should be done before hide insertion point controller since it triggers a show of it
- mSuggestionsPopupWindow.hide();
- }
- hideInsertionPointCursorController();
- stopSelectionActionMode();
- }
+ // Used to highlight a word when it is corrected by the IME
+ CorrectionHighlighter mCorrectionHighlighter;
- /**
- * Get the character offset closest to the specified absolute position. A typical use case is to
- * pass the result of {@link MotionEvent#getX()} and {@link MotionEvent#getY()} to this method.
- *
- * @param x The horizontal absolute position of a point on screen
- * @param y The vertical absolute position of a point on screen
- * @return the character offset for the character whose position is closest to the specified
- * position. Returns -1 if there is no layout.
- */
- public int getOffsetForPosition(float x, float y) {
- if (getLayout() == null) return -1;
- final int line = getLineAtCoordinate(y);
- final int offset = getOffsetAtCoordinate(line, x);
- return offset;
- }
+ InputContentType mInputContentType;
+ InputMethodState mInputMethodState;
- private float convertToLocalHorizontalCoordinate(float x) {
- x -= getTotalPaddingLeft();
- // Clamp the position to inside of the view.
- x = Math.max(0.0f, x);
- x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
- x += getScrollX();
- return x;
- }
+ DisplayList mTextDisplayList;
+ boolean mTextDisplayListIsValid;
- private int getLineAtCoordinate(float y) {
- y -= getTotalPaddingTop();
- // Clamp the position to inside of the view.
- y = Math.max(0.0f, y);
- y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
- y += getScrollY();
- return getLayout().getLineForVertical((int) y);
- }
+ boolean mFrozenWithFocus;
+ boolean mSelectionMoved;
+ boolean mTouchFocusSelected;
- private int getOffsetAtCoordinate(int line, float x) {
- x = convertToLocalHorizontalCoordinate(x);
- return getLayout().getOffsetForHorizontal(line, x);
- }
+ KeyListener mKeyListener;
+ int mInputType = EditorInfo.TYPE_NULL;
- /** Returns true if the screen coordinates position (x,y) corresponds to a character displayed
- * in the view. Returns false when the position is in the empty space of left/right of text.
- */
- private boolean isPositionOnText(float x, float y) {
- if (getLayout() == null) return false;
+ boolean mDiscardNextActionUp;
+ boolean mIgnoreActionUpEvent;
- final int line = getLineAtCoordinate(y);
- x = convertToLocalHorizontalCoordinate(x);
+ long mShowCursor;
+ Blink mBlink;
- if (x < getLayout().getLineLeft(line)) return false;
- if (x > getLayout().getLineRight(line)) return false;
- return true;
- }
+ boolean mCursorVisible = true;
+ boolean mSelectAllOnFocus;
+ boolean mTextIsSelectable;
- @Override
- public boolean onDragEvent(DragEvent event) {
- switch (event.getAction()) {
- case DragEvent.ACTION_DRAG_STARTED:
- return hasInsertionController();
+ CharSequence mError;
+ boolean mErrorWasChanged;
+ ErrorPopup mErrorPopup;
+ /**
+ * This flag is set if the TextView tries to display an error before it
+ * is attached to the window (so its position is still unknown).
+ * It causes the error to be shown later, when onAttachedToWindow()
+ * is called.
+ */
+ boolean mShowErrorAfterAttach;
- case DragEvent.ACTION_DRAG_ENTERED:
- TextView.this.requestFocus();
- return true;
+ boolean mInBatchEditControllers;
- case DragEvent.ACTION_DRAG_LOCATION:
- final int offset = getOffsetForPosition(event.getX(), event.getY());
- Selection.setSelection((Spannable)mText, offset);
- return true;
+ SuggestionsPopupWindow mSuggestionsPopupWindow;
+ SuggestionRangeSpan mSuggestionRangeSpan;
+ Runnable mShowSuggestionRunnable;
- case DragEvent.ACTION_DROP:
- onDrop(event);
- return true;
+ final Drawable[] mCursorDrawable = new Drawable[2];
+ int mCursorCount; // Current number of used mCursorDrawable: 0 (resource=0), 1 or 2 (split)
- case DragEvent.ACTION_DRAG_ENDED:
- case DragEvent.ACTION_DRAG_EXITED:
- default:
- return true;
- }
- }
+ Drawable mSelectHandleLeft;
+ Drawable mSelectHandleRight;
+ Drawable mSelectHandleCenter;
- private void onDrop(DragEvent event) {
- StringBuilder content = new StringBuilder("");
- ClipData clipData = event.getClipData();
- final int itemCount = clipData.getItemCount();
- for (int i=0; i < itemCount; i++) {
- Item item = clipData.getItemAt(i);
- content.append(item.coerceToText(TextView.this.mContext));
- }
+ // Global listener that detects changes in the global position of the TextView
+ PositionListener mPositionListener;
- final int offset = getOffsetForPosition(event.getX(), event.getY());
+ float mLastDownPositionX, mLastDownPositionY;
+ Callback mCustomSelectionActionModeCallback;
- Object localState = event.getLocalState();
- DragLocalState dragLocalState = null;
- if (localState instanceof DragLocalState) {
- dragLocalState = (DragLocalState) localState;
- }
- boolean dragDropIntoItself = dragLocalState != null &&
- dragLocalState.sourceTextView == this;
+ // Set when this TextView gained focus with some text selected. Will start selection mode.
+ boolean mCreatedWithASelection;
- if (dragDropIntoItself) {
- if (offset >= dragLocalState.start && offset < dragLocalState.end) {
- // A drop inside the original selection discards the drop.
- return;
+ WordIterator mWordIterator;
+ SpellChecker mSpellChecker;
+
+ void onAttachedToWindow() {
+ final ViewTreeObserver observer = getViewTreeObserver();
+ // No need to create the controller.
+ // The get method will add the listener on controller creation.
+ if (mInsertionPointCursorController != null) {
+ observer.addOnTouchModeChangeListener(mInsertionPointCursorController);
}
+ if (mSelectionModifierCursorController != null) {
+ observer.addOnTouchModeChangeListener(mSelectionModifierCursorController);
+ }
+ updateSpellCheckSpans(0, mText.length(), true /* create the spell checker if needed */);
}
- final int originalLength = mText.length();
- long minMax = prepareSpacesAroundPaste(offset, offset, content);
- int min = extractRangeStartFromLong(minMax);
- int max = extractRangeEndFromLong(minMax);
+ void onDetachedFromWindow() {
+ if (mError != null) {
+ hideError();
+ }
- Selection.setSelection((Spannable) mText, max);
- replaceText_internal(min, max, content);
+ if (mBlink != null) {
+ mBlink.removeCallbacks(mBlink);
+ }
- if (dragDropIntoItself) {
- int dragSourceStart = dragLocalState.start;
- int dragSourceEnd = dragLocalState.end;
- if (max <= dragSourceStart) {
- // Inserting text before selection has shifted positions
- final int shift = mText.length() - originalLength;
- dragSourceStart += shift;
- dragSourceEnd += shift;
+ if (mInsertionPointCursorController != null) {
+ mInsertionPointCursorController.onDetached();
}
- // Delete original selection
- deleteText_internal(dragSourceStart, dragSourceEnd);
+ if (mSelectionModifierCursorController != null) {
+ mSelectionModifierCursorController.onDetached();
+ }
- // Make sure we do not leave two adjacent spaces.
- if ((dragSourceStart == 0 ||
- Character.isSpaceChar(mTransformed.charAt(dragSourceStart - 1))) &&
- (dragSourceStart == mText.length() ||
- Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) {
- final int pos = dragSourceStart == mText.length() ?
- dragSourceStart - 1 : dragSourceStart;
- deleteText_internal(pos, pos + 1);
+ if (mShowSuggestionRunnable != null) {
+ removeCallbacks(mShowSuggestionRunnable);
}
- }
- }
- /**
- * @return True if this view supports insertion handles.
- */
- boolean hasInsertionController() {
- return mInsertionControllerEnabled;
- }
+ if (mTextDisplayList != null) {
+ mTextDisplayList.invalidate();
+ }
- /**
- * @return True if this view supports selection handles.
- */
- boolean hasSelectionController() {
- return mSelectionControllerEnabled;
- }
+ if (mSpellChecker != null) {
+ mSpellChecker.closeSession();
+ // Forces the creation of a new SpellChecker next time this window is created.
+ // Will handle the cases where the settings has been changed in the meantime.
+ mSpellChecker = null;
+ }
- InsertionPointCursorController getInsertionController() {
- if (!mInsertionControllerEnabled) {
- return null;
+ hideControllers();
}
- if (mInsertionPointCursorController == null) {
- mInsertionPointCursorController = new InsertionPointCursorController();
-
- final ViewTreeObserver observer = getViewTreeObserver();
- observer.addOnTouchModeChangeListener(mInsertionPointCursorController);
+ void adjustInputType(boolean password, boolean passwordInputType,
+ boolean webPasswordInputType, boolean numberPasswordInputType) {
+ // mInputType has been set from inputType, possibly modified by mInputMethod.
+ // Specialize mInputType to [web]password if we have a text class and the original input
+ // type was a password.
+ if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
+ if (password || passwordInputType) {
+ mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
+ | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
+ }
+ if (webPasswordInputType) {
+ mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
+ | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
+ }
+ } else if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_NUMBER) {
+ if (numberPasswordInputType) {
+ mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
+ | EditorInfo.TYPE_NUMBER_VARIATION_PASSWORD;
+ }
+ }
}
- return mInsertionPointCursorController;
- }
-
- SelectionModifierCursorController getSelectionController() {
- if (!mSelectionControllerEnabled) {
- return null;
+ void setFrame() {
+ if (mErrorPopup != null) {
+ TextView tv = (TextView) mErrorPopup.getContentView();
+ chooseSize(mErrorPopup, mError, tv);
+ mErrorPopup.update(TextView.this, getErrorX(), getErrorY(),
+ mErrorPopup.getWidth(), mErrorPopup.getHeight());
+ }
}
- if (mSelectionModifierCursorController == null) {
- mSelectionModifierCursorController = new SelectionModifierCursorController();
-
- final ViewTreeObserver observer = getViewTreeObserver();
- observer.addOnTouchModeChangeListener(mSelectionModifierCursorController);
- }
+ void onFocusChanged(boolean focused, int direction) {
+ mShowCursor = SystemClock.uptimeMillis();
+ ensureEndedBatchEdit();
- return mSelectionModifierCursorController;
- }
+ if (focused) {
+ int selStart = getSelectionStart();
+ int selEnd = getSelectionEnd();
- boolean isInBatchEditMode() {
- final InputMethodState ims = mInputMethodState;
- if (ims != null) {
- return ims.mBatchEditNesting > 0;
- }
- return mInBatchEditControllers;
- }
+ // SelectAllOnFocus fields are highlighted and not selected. Do not start text selection
+ // mode for these, unless there was a specific selection already started.
+ final boolean isFocusHighlighted = mSelectAllOnFocus && selStart == 0 &&
+ selEnd == mText.length();
- @Override
- public void onResolveTextDirection() {
- if (hasPasswordTransformationMethod()) {
- mTextDir = TextDirectionHeuristics.LOCALE;
- return;
- }
+ mCreatedWithASelection = mFrozenWithFocus && hasSelection() && !isFocusHighlighted;
- // Always need to resolve layout direction first
- final boolean defaultIsRtl = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL);
+ if (!mFrozenWithFocus || (selStart < 0 || selEnd < 0)) {
+ // If a tap was used to give focus to that view, move cursor at tap position.
+ // Has to be done before onTakeFocus, which can be overloaded.
+ final int lastTapPosition = getLastTapPosition();
+ if (lastTapPosition >= 0) {
+ Selection.setSelection((Spannable) mText, lastTapPosition);
+ }
- // Now, we can select the heuristic
- int textDir = getResolvedTextDirection();
- switch (textDir) {
- default:
- case TEXT_DIRECTION_FIRST_STRONG:
- mTextDir = (defaultIsRtl ? TextDirectionHeuristics.FIRSTSTRONG_RTL :
- TextDirectionHeuristics.FIRSTSTRONG_LTR);
- break;
- case TEXT_DIRECTION_ANY_RTL:
- mTextDir = TextDirectionHeuristics.ANYRTL_LTR;
- break;
- case TEXT_DIRECTION_LTR:
- mTextDir = TextDirectionHeuristics.LTR;
- break;
- case TEXT_DIRECTION_RTL:
- mTextDir = TextDirectionHeuristics.RTL;
- break;
- case TEXT_DIRECTION_LOCALE:
- mTextDir = TextDirectionHeuristics.LOCALE;
- break;
- }
- }
+ // Note this may have to be moved out of the Editor class
+ if (mMovement != null) {
+ mMovement.onTakeFocus(TextView.this, (Spannable) mText, direction);
+ }
- /**
- * Subclasses will need to override this method to implement their own way of resolving
- * drawables depending on the layout direction.
- *
- * A call to the super method will be required from the subclasses implementation.
- */
- protected void resolveDrawables() {
- // No need to resolve twice
- if (mResolvedDrawables) {
- return;
- }
- // No drawable to resolve
- if (mDrawables == null) {
- return;
- }
- // No relative drawable to resolve
- if (mDrawables.mDrawableStart == null && mDrawables.mDrawableEnd == null) {
- mResolvedDrawables = true;
- return;
- }
+ // The DecorView does not have focus when the 'Done' ExtractEditText button is
+ // pressed. Since it is the ViewAncestor's mView, it requests focus before
+ // ExtractEditText clears focus, which gives focus to the ExtractEditText.
+ // This special case ensure that we keep current selection in that case.
+ // It would be better to know why the DecorView does not have focus at that time.
+ if (((TextView.this instanceof ExtractEditText) || mSelectionMoved) &&
+ selStart >= 0 && selEnd >= 0) {
+ /*
+ * Someone intentionally set the selection, so let them
+ * do whatever it is that they wanted to do instead of
+ * the default on-focus behavior. We reset the selection
+ * here instead of just skipping the onTakeFocus() call
+ * because some movement methods do something other than
+ * just setting the selection in theirs and we still
+ * need to go through that path.
+ */
+ Selection.setSelection((Spannable) mText, selStart, selEnd);
+ }
- Drawables dr = mDrawables;
- switch(getResolvedLayoutDirection()) {
- case LAYOUT_DIRECTION_RTL:
- if (dr.mDrawableStart != null) {
- dr.mDrawableRight = dr.mDrawableStart;
+ if (mSelectAllOnFocus) {
+ selectAll();
+ }
- dr.mDrawableSizeRight = dr.mDrawableSizeStart;
- dr.mDrawableHeightRight = dr.mDrawableHeightStart;
+ mTouchFocusSelected = true;
}
- if (dr.mDrawableEnd != null) {
- dr.mDrawableLeft = dr.mDrawableEnd;
- dr.mDrawableSizeLeft = dr.mDrawableSizeEnd;
- dr.mDrawableHeightLeft = dr.mDrawableHeightEnd;
- }
- break;
+ mFrozenWithFocus = false;
+ mSelectionMoved = false;
- case LAYOUT_DIRECTION_LTR:
- default:
- if (dr.mDrawableStart != null) {
- dr.mDrawableLeft = dr.mDrawableStart;
+ if (mError != null) {
+ showError();
+ }
- dr.mDrawableSizeLeft = dr.mDrawableSizeStart;
- dr.mDrawableHeightLeft = dr.mDrawableHeightStart;
+ makeBlink();
+ } else {
+ if (mError != null) {
+ hideError();
+ }
+ // Don't leave us in the middle of a batch edit.
+ onEndBatchEdit();
+
+ if (TextView.this instanceof ExtractEditText) {
+ // terminateTextSelectionMode removes selection, which we want to keep when
+ // ExtractEditText goes out of focus.
+ final int selStart = getSelectionStart();
+ final int selEnd = getSelectionEnd();
+ hideControllers();
+ Selection.setSelection((Spannable) mText, selStart, selEnd);
+ } else {
+ hideControllers();
+ downgradeEasyCorrectionSpans();
}
- if (dr.mDrawableEnd != null) {
- dr.mDrawableRight = dr.mDrawableEnd;
- dr.mDrawableSizeRight = dr.mDrawableSizeEnd;
- dr.mDrawableHeightRight = dr.mDrawableHeightEnd;
+ // No need to create the controller
+ if (mSelectionModifierCursorController != null) {
+ mSelectionModifierCursorController.resetTouchOffsets();
}
- break;
+ }
}
- mResolvedDrawables = true;
- }
- protected void resetResolvedDrawables() {
- mResolvedDrawables = false;
- }
+ void sendOnTextChanged(int start, int after) {
+ updateSpellCheckSpans(start, start + after, false);
+ mTextDisplayListIsValid = false;
- /**
- * @hide
- */
- protected void viewClicked(InputMethodManager imm) {
- if (imm != null) {
- imm.viewClicked(this);
+ // Hide the controllers as soon as text is modified (typing, procedural...)
+ // We do not hide the span controllers, since they can be added when a new text is
+ // inserted into the text view (voice IME).
+ hideCursorControllers();
}
- }
- /**
- * Deletes the range of text [start, end[.
- * @hide
- */
- protected void deleteText_internal(int start, int end) {
- ((Editable) mText).delete(start, end);
- }
+ private int getLastTapPosition() {
+ // No need to create the controller at that point, no last tap position saved
+ if (mSelectionModifierCursorController != null) {
+ int lastTapPosition = mSelectionModifierCursorController.getMinTouchOffset();
+ if (lastTapPosition >= 0) {
+ // Safety check, should not be possible.
+ if (lastTapPosition > mText.length()) {
+ Log.e(LOG_TAG, "Invalid tap focus position (" + lastTapPosition + " vs "
+ + mText.length() + ")");
+ lastTapPosition = mText.length();
+ }
+ return lastTapPosition;
+ }
+ }
- /**
- * Replaces the range of text [start, end[ by replacement text
- * @hide
- */
- protected void replaceText_internal(int start, int end, CharSequence text) {
- ((Editable) mText).replace(start, end, text);
- }
+ return -1;
+ }
- /**
- * Sets a span on the specified range of text
- * @hide
- */
- protected void setSpan_internal(Object span, int start, int end, int flags) {
- ((Editable) mText).setSpan(span, start, end, flags);
- }
+ void onWindowFocusChanged(boolean hasWindowFocus) {
+ if (hasWindowFocus) {
+ if (mBlink != null) {
+ mBlink.uncancel();
+ makeBlink();
+ }
+ } else {
+ if (mBlink != null) {
+ mBlink.cancel();
+ }
+ if (mInputContentType != null) {
+ mInputContentType.enterDown = false;
+ }
+ // Order matters! Must be done before onParentLostFocus to rely on isShowingUp
+ hideControllers();
+ if (mSuggestionsPopupWindow != null) {
+ mSuggestionsPopupWindow.onParentLostFocus();
+ }
- /**
- * Moves the cursor to the specified offset position in text
- * @hide
- */
- protected void setCursorPosition_internal(int start, int end) {
- Selection.setSelection(((Editable) mText), start, end);
- }
+ // Don't leave us in the middle of a batch edit.
+ onEndBatchEdit();
+ }
+ }
- @ViewDebug.ExportedProperty(category = "text")
- private CharSequence mText;
- private CharSequence mTransformed;
- private BufferType mBufferType = BufferType.NORMAL;
+ void onTouchEvent(MotionEvent event) {
+ if (hasSelectionController()) {
+ getSelectionController().onTouchEvent(event);
+ }
- private int mInputType = EditorInfo.TYPE_NULL;
- private CharSequence mHint;
- private Layout mHintLayout;
+ if (mShowSuggestionRunnable != null) {
+ removeCallbacks(mShowSuggestionRunnable);
+ mShowSuggestionRunnable = null;
+ }
- private KeyListener mInput;
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mLastDownPositionX = event.getX();
+ mLastDownPositionY = event.getY();
- private MovementMethod mMovement;
- private TransformationMethod mTransformation;
- private boolean mAllowTransformationLengthChange;
- private ChangeWatcher mChangeWatcher;
+ // Reset this state; it will be re-set if super.onTouchEvent
+ // causes focus to move to the view.
+ mTouchFocusSelected = false;
+ mIgnoreActionUpEvent = false;
+ }
+ }
- private ArrayList<TextWatcher> mListeners = null;
+ void onDraw(Canvas canvas, Layout layout, Path highlight, int cursorOffsetVertical) {
+ final int selectionStart = getSelectionStart();
+ final int selectionEnd = getSelectionEnd();
- // display attributes
- private final TextPaint mTextPaint;
- private boolean mUserSetTextScaleX;
- private final Paint mHighlightPaint;
- private int mHighlightColor = 0x6633B5E5;
- private Layout mLayout;
+ final InputMethodState ims = mInputMethodState;
+ if (ims != null && ims.mBatchEditNesting == 0) {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ if (imm.isActive(TextView.this)) {
+ boolean reported = false;
+ if (ims.mContentChanged || ims.mSelectionModeChanged) {
+ // We are in extract mode and the content has changed
+ // in some way... just report complete new text to the
+ // input method.
+ reported = reportExtractedText();
+ }
+ if (!reported && highlight != null) {
+ int candStart = -1;
+ int candEnd = -1;
+ if (mText instanceof Spannable) {
+ Spannable sp = (Spannable)mText;
+ candStart = EditableInputConnection.getComposingSpanStart(sp);
+ candEnd = EditableInputConnection.getComposingSpanEnd(sp);
+ }
+ imm.updateSelection(TextView.this,
+ selectionStart, selectionEnd, candStart, candEnd);
+ }
+ }
- private long mShowCursor;
- private Blink mBlink;
- private boolean mCursorVisible = true;
+ if (imm.isWatchingCursor(TextView.this) && highlight != null) {
+ highlight.computeBounds(ims.mTmpRectF, true);
+ ims.mTmpOffset[0] = ims.mTmpOffset[1] = 0;
- // Cursor Controllers.
- private InsertionPointCursorController mInsertionPointCursorController;
- private SelectionModifierCursorController mSelectionModifierCursorController;
- private ActionMode mSelectionActionMode;
- private boolean mInsertionControllerEnabled;
- private boolean mSelectionControllerEnabled;
- private boolean mInBatchEditControllers;
+ canvas.getMatrix().mapPoints(ims.mTmpOffset);
+ ims.mTmpRectF.offset(ims.mTmpOffset[0], ims.mTmpOffset[1]);
- private boolean mSelectAllOnFocus = false;
+ ims.mTmpRectF.offset(0, cursorOffsetVertical);
- private int mGravity = Gravity.TOP | Gravity.START;
- private boolean mHorizontallyScrolling;
+ ims.mCursorRectInWindow.set((int)(ims.mTmpRectF.left + 0.5),
+ (int)(ims.mTmpRectF.top + 0.5),
+ (int)(ims.mTmpRectF.right + 0.5),
+ (int)(ims.mTmpRectF.bottom + 0.5));
- private int mAutoLinkMask;
- private boolean mLinksClickable = true;
+ imm.updateCursor(TextView.this,
+ ims.mCursorRectInWindow.left, ims.mCursorRectInWindow.top,
+ ims.mCursorRectInWindow.right, ims.mCursorRectInWindow.bottom);
+ }
+ }
+ }
- private float mSpacingMult = 1.0f;
- private float mSpacingAdd = 0.0f;
- private boolean mTextIsSelectable = false;
+ if (mCorrectionHighlighter != null) {
+ mCorrectionHighlighter.draw(canvas, cursorOffsetVertical);
+ }
+
+ if (highlight != null && selectionStart == selectionEnd && mCursorCount > 0) {
+ drawCursor(canvas, cursorOffsetVertical);
+ // Rely on the drawable entirely, do not draw the cursor line.
+ // Has to be done after the IMM related code above which relies on the highlight.
+ highlight = null;
+ }
- private static final int LINES = 1;
- private static final int EMS = LINES;
- private static final int PIXELS = 2;
+ if (canHaveDisplayList() && canvas.isHardwareAccelerated()) {
+ final int width = mRight - mLeft;
+ final int height = mBottom - mTop;
- private int mMaximum = Integer.MAX_VALUE;
- private int mMaxMode = LINES;
- private int mMinimum = 0;
- private int mMinMode = LINES;
+ if (mTextDisplayList == null || !mTextDisplayList.isValid() ||
+ !mTextDisplayListIsValid) {
+ if (mTextDisplayList == null) {
+ mTextDisplayList = getHardwareRenderer().createDisplayList("Text");
+ }
- private int mOldMaximum = mMaximum;
- private int mOldMaxMode = mMaxMode;
+ final HardwareCanvas hardwareCanvas = mTextDisplayList.start();
+ try {
+ hardwareCanvas.setViewport(width, height);
+ // The dirty rect should always be null for a display list
+ hardwareCanvas.onPreDraw(null);
+ hardwareCanvas.translate(-mScrollX, -mScrollY);
+ layout.draw(hardwareCanvas, highlight, mHighlightPaint, cursorOffsetVertical);
+ hardwareCanvas.translate(mScrollX, mScrollY);
+ } finally {
+ hardwareCanvas.onPostDraw();
+ mTextDisplayList.end();
+ mTextDisplayListIsValid = true;
+ }
+ }
+ canvas.translate(mScrollX, mScrollY);
+ ((HardwareCanvas) canvas).drawDisplayList(mTextDisplayList, width, height, null,
+ DisplayList.FLAG_CLIP_CHILDREN);
+ canvas.translate(-mScrollX, -mScrollY);
+ } else {
+ layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
+ }
- private int mMaxWidth = Integer.MAX_VALUE;
- private int mMaxWidthMode = PIXELS;
- private int mMinWidth = 0;
- private int mMinWidthMode = PIXELS;
+ if (mMarquee != null && mMarquee.shouldDrawGhost()) {
+ canvas.translate((int) mMarquee.getGhostOffset(), 0.0f);
+ layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
+ }
+ }
- private boolean mSingleLine;
- private int mDesiredHeightAtMeasure = -1;
- private boolean mIncludePad = true;
+ private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
+ final boolean translate = cursorOffsetVertical != 0;
+ if (translate) canvas.translate(0, cursorOffsetVertical);
+ for (int i = 0; i < getEditor().mCursorCount; i++) {
+ mCursorDrawable[i].draw(canvas);
+ }
+ if (translate) canvas.translate(0, -cursorOffsetVertical);
+ }
- // tmp primitives, so we don't alloc them on each draw
- private Path mHighlightPath;
- private boolean mHighlightPathBogus = true;
- private static final RectF sTempRect = new RectF();
- private static final float[] sTmpPosition = new float[2];
+ private void updateCursorsPositions() {
+ if (mCursorDrawableRes == 0) {
+ mCursorCount = 0;
+ return;
+ }
- // XXX should be much larger
- private static final int VERY_WIDE = 1024*1024;
+ final int offset = getSelectionStart();
+ final int line = mLayout.getLineForOffset(offset);
+ final int top = mLayout.getLineTop(line);
+ final int bottom = mLayout.getLineTop(line + 1);
- private static final int BLINK = 500;
+ mCursorCount = mLayout.isLevelBoundary(offset) ? 2 : 1;
- private static final int ANIMATED_SCROLL_GAP = 250;
- private long mLastScroll;
- private Scroller mScroller = null;
+ int middle = bottom;
+ if (mCursorCount == 2) {
+ // Similar to what is done in {@link Layout.#getCursorPath(int, Path, CharSequence)}
+ middle = (top + bottom) >> 1;
+ }
- private BoringLayout.Metrics mBoring;
- private BoringLayout.Metrics mHintBoring;
+ updateCursorPosition(0, top, middle, mLayout.getPrimaryHorizontal(offset));
- private BoringLayout mSavedLayout, mSavedHintLayout;
+ if (mCursorCount == 2) {
+ updateCursorPosition(1, middle, bottom, mLayout.getSecondaryHorizontal(offset));
+ }
+ }
- private TextDirectionHeuristic mTextDir = null;
+ private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
+ if (mCursorDrawable[cursorIndex] == null)
+ mCursorDrawable[cursorIndex] = mContext.getResources().getDrawable(mCursorDrawableRes);
- private static final InputFilter[] NO_FILTERS = new InputFilter[0];
- private InputFilter[] mFilters = NO_FILTERS;
- private static final Spanned EMPTY_SPANNED = new SpannedString("");
- private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
- // System wide time for last cut or copy action.
- private static long sLastCutOrCopyTime;
- // Used to highlight a word when it is corrected by the IME
- private CorrectionHighlighter mCorrectionHighlighter;
- // New state used to change background based on whether this TextView is multiline.
- private static final int[] MULTILINE_STATE_SET = { R.attr.state_multiline };
+ if (mTempRect == null) mTempRect = new Rect();
+ mCursorDrawable[cursorIndex].getPadding(mTempRect);
+ final int width = mCursorDrawable[cursorIndex].getIntrinsicWidth();
+ horizontal = Math.max(0.5f, horizontal - 0.5f);
+ final int left = (int) (horizontal) - mTempRect.left;
+ mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
+ bottom + mTempRect.bottom);
+ }
+ }
}
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 8f10fff919bd..ef1d7d01bf36 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -213,6 +213,7 @@ public class TimePicker extends FrameLayout {
button.requestFocus();
mIsAm = !mIsAm;
updateAmPmControl();
+ onTimeChanged();
}
});
} else {
@@ -227,6 +228,7 @@ public class TimePicker extends FrameLayout {
picker.requestFocus();
mIsAm = !mIsAm;
updateAmPmControl();
+ onTimeChanged();
}
});
mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index afb5bf148484..f3486bdabb99 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -748,6 +748,16 @@ public class ActionBarImpl extends ActionBar {
}
@Override
+ public void setTitleOptionalHint(boolean titleOptional) {
+ mContextView.setTitleOptional(titleOptional);
+ }
+
+ @Override
+ public boolean isTitleOptional() {
+ return mContextView.isTitleOptional();
+ }
+
+ @Override
public View getCustomView() {
return mCustomView != null ? mCustomView.get() : null;
}
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 41993c41289a..ccd27632b9a6 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -22,12 +22,12 @@ import static android.net.NetworkStats.UID_ALL;
import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
import android.net.NetworkStats;
+import android.os.StrictMode;
import android.os.SystemClock;
import android.util.Slog;
import com.android.internal.util.ProcFileReader;
import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
import com.google.android.collect.Sets;
import java.io.BufferedReader;
@@ -36,7 +36,6 @@ import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;
@@ -62,22 +61,6 @@ public class NetworkStatsFactory {
/** Path to {@code /proc/net/xt_qtaguid/stats}. */
private final File mStatsXtUid;
- /** {@link #mStatsXtUid} and {@link #mStatsXtIfaceAll} headers. */
- private static final String KEY_IDX = "idx";
- private static final String KEY_IFACE = "iface";
- private static final String KEY_ACTIVE = "active";
- private static final String KEY_UID = "uid_tag_int";
- private static final String KEY_COUNTER_SET = "cnt_set";
- private static final String KEY_TAG_HEX = "acct_tag_hex";
- private static final String KEY_SNAP_RX_BYTES = "snap_rx_bytes";
- private static final String KEY_SNAP_RX_PACKETS = "snap_rx_packets";
- private static final String KEY_SNAP_TX_BYTES = "snap_tx_bytes";
- private static final String KEY_SNAP_TX_PACKETS = "snap_tx_packets";
- private static final String KEY_RX_BYTES = "rx_bytes";
- private static final String KEY_RX_PACKETS = "rx_packets";
- private static final String KEY_TX_BYTES = "tx_bytes";
- private static final String KEY_TX_PACKETS = "tx_packets";
-
public NetworkStatsFactory() {
this(new File("/proc/"));
}
@@ -106,47 +89,39 @@ public class NetworkStatsFactory {
}
private NetworkStats readNetworkStatsSummarySingleFile() {
+ final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
final NetworkStats.Entry entry = new NetworkStats.Entry();
- // TODO: transition to ProcFileReader
- // TODO: read directly from proc once headers are added
- final ArrayList<String> keys = Lists.newArrayList(KEY_IFACE, KEY_ACTIVE, KEY_SNAP_RX_BYTES,
- KEY_SNAP_RX_PACKETS, KEY_SNAP_TX_BYTES, KEY_SNAP_TX_PACKETS, KEY_RX_BYTES,
- KEY_RX_PACKETS, KEY_TX_BYTES, KEY_TX_PACKETS);
- final ArrayList<String> values = Lists.newArrayList();
- final HashMap<String, String> parsed = Maps.newHashMap();
-
- BufferedReader reader = null;
+ ProcFileReader reader = null;
try {
- reader = new BufferedReader(new FileReader(mStatsXtIfaceAll));
+ reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceAll));
- String line;
- while ((line = reader.readLine()) != null) {
- splitLine(line, values);
- parseLine(keys, values, parsed);
-
- entry.iface = parsed.get(KEY_IFACE);
+ while (reader.hasMoreData()) {
+ entry.iface = reader.nextString();
entry.uid = UID_ALL;
entry.set = SET_DEFAULT;
entry.tag = TAG_NONE;
+ final boolean active = reader.nextInt() != 0;
+
// always include snapshot values
- entry.rxBytes = getParsedLong(parsed, KEY_SNAP_RX_BYTES);
- entry.rxPackets = getParsedLong(parsed, KEY_SNAP_RX_PACKETS);
- entry.txBytes = getParsedLong(parsed, KEY_SNAP_TX_BYTES);
- entry.txPackets = getParsedLong(parsed, KEY_SNAP_TX_PACKETS);
+ entry.rxBytes = reader.nextLong();
+ entry.rxPackets = reader.nextLong();
+ entry.txBytes = reader.nextLong();
+ entry.txPackets = reader.nextLong();
// fold in active numbers, but only when active
- final boolean active = getParsedInt(parsed, KEY_ACTIVE) != 0;
if (active) {
- entry.rxBytes += getParsedLong(parsed, KEY_RX_BYTES);
- entry.rxPackets += getParsedLong(parsed, KEY_RX_PACKETS);
- entry.txBytes += getParsedLong(parsed, KEY_TX_BYTES);
- entry.txPackets += getParsedLong(parsed, KEY_TX_PACKETS);
+ entry.rxBytes += reader.nextLong();
+ entry.rxPackets += reader.nextLong();
+ entry.txBytes += reader.nextLong();
+ entry.txPackets += reader.nextLong();
}
stats.addValues(entry);
+ reader.finishLine();
}
} catch (NullPointerException e) {
throw new IllegalStateException("problem parsing stats: " + e);
@@ -156,6 +131,7 @@ public class NetworkStatsFactory {
throw new IllegalStateException("problem parsing stats: " + e);
} finally {
IoUtils.closeQuietly(reader);
+ StrictMode.setThreadPolicy(savedPolicy);
}
return stats;
}
@@ -165,6 +141,8 @@ public class NetworkStatsFactory {
*/
@Deprecated
private NetworkStats readNetworkStatsSummaryMultipleFiles() {
+ final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
final NetworkStats.Entry entry = new NetworkStats.Entry();
@@ -241,6 +219,7 @@ public class NetworkStatsFactory {
throw new IllegalStateException("problem parsing stats: " + e);
} finally {
IoUtils.closeQuietly(reader);
+ StrictMode.setThreadPolicy(savedPolicy);
}
return stats;
@@ -257,6 +236,8 @@ public class NetworkStatsFactory {
* @throws IllegalStateException when problem parsing stats.
*/
public NetworkStats readNetworkStatsDetail(int limitUid) throws IllegalStateException {
+ final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
final NetworkStats.Entry entry = new NetworkStats.Entry();
@@ -300,23 +281,12 @@ public class NetworkStatsFactory {
throw new IllegalStateException("problem parsing idx " + idx, e);
} finally {
IoUtils.closeQuietly(reader);
+ StrictMode.setThreadPolicy(savedPolicy);
}
return stats;
}
- @Deprecated
- private static int getParsedInt(HashMap<String, String> parsed, String key) {
- final String value = parsed.get(key);
- return value != null ? Integer.parseInt(value) : 0;
- }
-
- @Deprecated
- private static long getParsedLong(HashMap<String, String> parsed, String key) {
- final String value = parsed.get(key);
- return value != null ? Long.parseLong(value) : 0;
- }
-
/**
* Split given line into {@link ArrayList}.
*/
@@ -331,21 +301,6 @@ public class NetworkStatsFactory {
}
/**
- * Zip the two given {@link ArrayList} as key and value pairs into
- * {@link HashMap}.
- */
- @Deprecated
- private static void parseLine(
- ArrayList<String> keys, ArrayList<String> values, HashMap<String, String> outParsed) {
- outParsed.clear();
-
- final int size = Math.min(keys.size(), values.size());
- for (int i = 0; i < size; i++) {
- outParsed.put(keys.get(i), values.get(i));
- }
- }
-
- /**
* Utility method to read a single plain-text {@link Long} from the given
* {@link File}, usually from a {@code /proc/} filesystem.
*/
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java
index c03ff1a15f88..d443523a2c12 100644
--- a/core/java/com/android/internal/statusbar/StatusBarNotification.java
+++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java
@@ -34,25 +34,23 @@ if (truncatedTicker != null && truncatedTicker.length() > maxTickerLen) {
}
*/
+/**
+ * Class encapsulating a Notification. Sent by the NotificationManagerService to the IStatusBar (in System UI).
+ */
public class StatusBarNotification implements Parcelable {
- public static int PRIORITY_JIFFY_EXPRESS = -100;
- public static int PRIORITY_NORMAL = 0;
- public static int PRIORITY_ONGOING = 100;
- public static int PRIORITY_SYSTEM = 200;
-
public String pkg;
public int id;
public String tag;
public int uid;
public int initialPid;
public Notification notification;
- public int priority = PRIORITY_NORMAL;
-
+ public int score;
+
public StatusBarNotification() {
}
public StatusBarNotification(String pkg, int id, String tag,
- int uid, int initialPid, Notification notification) {
+ int uid, int initialPid, int score, Notification notification) {
if (pkg == null) throw new NullPointerException();
if (notification == null) throw new NullPointerException();
@@ -61,9 +59,8 @@ public class StatusBarNotification implements Parcelable {
this.tag = tag;
this.uid = uid;
this.initialPid = initialPid;
+ this.score = score;
this.notification = notification;
-
- this.priority = PRIORITY_NORMAL;
}
public StatusBarNotification(Parcel in) {
@@ -80,7 +77,7 @@ public class StatusBarNotification implements Parcelable {
}
this.uid = in.readInt();
this.initialPid = in.readInt();
- this.priority = in.readInt();
+ this.score = in.readInt();
this.notification = new Notification(in);
}
@@ -95,7 +92,7 @@ public class StatusBarNotification implements Parcelable {
}
out.writeInt(this.uid);
out.writeInt(this.initialPid);
- out.writeInt(this.priority);
+ out.writeInt(this.score);
this.notification.writeToParcel(out, flags);
}
@@ -119,12 +116,12 @@ public class StatusBarNotification implements Parcelable {
public StatusBarNotification clone() {
return new StatusBarNotification(this.pkg, this.id, this.tag,
- this.uid, this.initialPid, this.notification.clone());
+ this.uid, this.initialPid, this.score, this.notification.clone());
}
public String toString() {
- return "StatusBarNotification(package=" + pkg + " id=" + id + " tag=" + tag
- + " notification=" + notification + " priority=" + priority + ")";
+ return "StatusBarNotification(pkg=" + pkg + " id=" + id + " tag=" + tag
+ + " score=" + score + " notn=" + notification + ")";
}
public boolean isOngoing() {
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 5d80b799df70..82b2654f1821 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -43,16 +43,17 @@ interface IInputMethodManager {
void removeClient(in IInputMethodClient client);
InputBindResult startInput(in IInputMethodClient client,
- IInputContext inputContext, in EditorInfo attribute,
- boolean initial, boolean needResult);
+ IInputContext inputContext, in EditorInfo attribute, int controlFlags);
void finishInput(in IInputMethodClient client);
boolean showSoftInput(in IInputMethodClient client, int flags,
in ResultReceiver resultReceiver);
boolean hideSoftInput(in IInputMethodClient client, int flags,
in ResultReceiver resultReceiver);
- void windowGainedFocus(in IInputMethodClient client, in IBinder windowToken,
- boolean viewHasFocus, boolean isTextEditor,
- int softInputMode, boolean first, int windowFlags);
+ // Report that a window has gained focus. If 'attribute' is non-null,
+ // this will also do a startInput.
+ InputBindResult windowGainedFocus(in IInputMethodClient client, in IBinder windowToken,
+ int controlFlags, int softInputMode, int windowFlags,
+ in EditorInfo attribute, IInputContext inputContext);
void showInputMethodPickerFromClient(in IInputMethodClient client);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java
index edf4443b84a2..4b681ec3a44c 100644
--- a/core/java/com/android/internal/view/StandaloneActionMode.java
+++ b/core/java/com/android/internal/view/StandaloneActionMode.java
@@ -72,6 +72,16 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call
}
@Override
+ public void setTitleOptionalHint(boolean titleOptional) {
+ mContextView.setTitleOptional(titleOptional);
+ }
+
+ @Override
+ public boolean isTitleOptional() {
+ return mContextView.isTitleOptional();
+ }
+
+ @Override
public void setCustomView(View view) {
mContextView.setCustomView(view);
mCustomView = view != null ? new WeakReference<View>(view) : null;
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index ed02636f1c6a..16f08f55fea7 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -56,6 +56,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
private int mTitleStyleRes;
private int mSubtitleStyleRes;
private Drawable mSplitBackground;
+ private boolean mTitleOptional;
private Animator mCurrentAnimation;
private boolean mAnimateInOnLayout;
@@ -354,7 +355,18 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
}
if (mTitleLayout != null && mCustomView == null) {
- availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0);
+ if (mTitleOptional) {
+ final int titleWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ mTitleLayout.measure(titleWidthSpec, childSpecHeight);
+ final int titleWidth = mTitleLayout.getMeasuredWidth();
+ final boolean titleFits = titleWidth <= availableWidth;
+ if (titleFits) {
+ availableWidth -= titleWidth;
+ }
+ mTitleLayout.setVisibility(titleFits ? VISIBLE : GONE);
+ } else {
+ availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0);
+ }
}
if (mCustomView != null) {
@@ -405,8 +417,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
View child = mMenuView.getChildAt(i);
child.setScaleY(0);
ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0, 1);
- a.setDuration(100);
- a.setStartDelay(j * 70);
+ a.setDuration(300);
b.with(a);
}
}
@@ -432,8 +443,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
View child = mMenuView.getChildAt(i);
child.setScaleY(0);
ObjectAnimator a = ObjectAnimator.ofFloat(child, "scaleY", 0);
- a.setDuration(100);
- a.setStartDelay(i * 70);
+ a.setDuration(300);
b.with(a);
}
}
@@ -462,7 +472,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
}
}
- if (mTitleLayout != null && mCustomView == null) {
+ if (mTitleLayout != null && mCustomView == null && mTitleLayout.getVisibility() != GONE) {
x += positionChild(mTitleLayout, x, y, contentHeight);
}
@@ -514,4 +524,15 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
super.onInitializeAccessibilityEvent(event);
}
}
+
+ public void setTitleOptional(boolean titleOptional) {
+ if (titleOptional != mTitleOptional) {
+ requestLayout();
+ }
+ mTitleOptional = titleOptional;
+ }
+
+ public boolean isTitleOptional() {
+ return mTitleOptional;
+ }
}
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index 25b0065fd7fe..1767d6841530 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -45,7 +45,7 @@ import android.widget.TextView;
* across different configurations or circumstances.
*/
public class ScrollingTabContainerView extends HorizontalScrollView
- implements AdapterView.OnItemSelectedListener {
+ implements AdapterView.OnItemClickListener {
private static final String TAG = "ScrollingTabContainerView";
Runnable mTabSelector;
private TabClickListener mTabClickListener;
@@ -197,7 +197,7 @@ public class ScrollingTabContainerView extends HorizontalScrollView
com.android.internal.R.attr.actionDropDownStyle);
spinner.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
- spinner.setOnItemSelectedListener(this);
+ spinner.setOnItemClickListenerInt(this);
return spinner;
}
@@ -347,15 +347,11 @@ public class ScrollingTabContainerView extends HorizontalScrollView
}
@Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TabView tabView = (TabView) view;
tabView.getTab().select();
}
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
-
private class TabView extends LinearLayout {
private ActionBar.Tab mTab;
private TextView mTextView;
diff --git a/core/java/com/google/android/mms/ContentType.java b/core/java/com/google/android/mms/ContentType.java
index b066fadae2f1..12a134399c33 100644
--- a/core/java/com/google/android/mms/ContentType.java
+++ b/core/java/com/google/android/mms/ContentType.java
@@ -39,6 +39,7 @@ public class ContentType {
public static final String IMAGE_GIF = "image/gif";
public static final String IMAGE_WBMP = "image/vnd.wap.wbmp";
public static final String IMAGE_PNG = "image/png";
+ public static final String IMAGE_X_MS_BMP = "image/x-ms-bmp";
public static final String AUDIO_UNSPECIFIED = "audio/*";
public static final String AUDIO_AAC = "audio/aac";
@@ -58,6 +59,7 @@ public class ContentType {
public static final String AUDIO_X_MPEG = "audio/x-mpeg";
public static final String AUDIO_X_MPG = "audio/x-mpg";
public static final String AUDIO_3GPP = "audio/3gpp";
+ public static final String AUDIO_X_WAV = "audio/x-wav";
public static final String AUDIO_OGG = "application/ogg";
public static final String VIDEO_UNSPECIFIED = "video/*";
@@ -89,6 +91,7 @@ public class ContentType {
sSupportedContentTypes.add(IMAGE_WBMP);
sSupportedContentTypes.add(IMAGE_PNG);
sSupportedContentTypes.add(IMAGE_JPG);
+ sSupportedContentTypes.add(IMAGE_X_MS_BMP);
//supportedContentTypes.add(IMAGE_SVG); not yet supported.
sSupportedContentTypes.add(AUDIO_AAC);
@@ -106,6 +109,7 @@ public class ContentType {
sSupportedContentTypes.add(AUDIO_X_MPEG3);
sSupportedContentTypes.add(AUDIO_X_MPEG);
sSupportedContentTypes.add(AUDIO_X_MPG);
+ sSupportedContentTypes.add(AUDIO_X_WAV);
sSupportedContentTypes.add(AUDIO_3GPP);
sSupportedContentTypes.add(AUDIO_OGG);
@@ -127,6 +131,7 @@ public class ContentType {
sSupportedImageTypes.add(IMAGE_WBMP);
sSupportedImageTypes.add(IMAGE_PNG);
sSupportedImageTypes.add(IMAGE_JPG);
+ sSupportedImageTypes.add(IMAGE_X_MS_BMP);
// add supported audio types
sSupportedAudioTypes.add(AUDIO_AAC);
@@ -145,6 +150,7 @@ public class ContentType {
sSupportedAudioTypes.add(AUDIO_X_MPEG3);
sSupportedAudioTypes.add(AUDIO_X_MPEG);
sSupportedAudioTypes.add(AUDIO_X_MPG);
+ sSupportedAudioTypes.add(AUDIO_X_WAV);
sSupportedAudioTypes.add(AUDIO_3GPP);
sSupportedAudioTypes.add(AUDIO_OGG);
diff --git a/core/java/com/google/android/mms/pdu/PduComposer.java b/core/java/com/google/android/mms/pdu/PduComposer.java
index 8940945a605a..d426f89bcb6c 100644
--- a/core/java/com/google/android/mms/pdu/PduComposer.java
+++ b/core/java/com/google/android/mms/pdu/PduComposer.java
@@ -835,9 +835,7 @@ public class PduComposer {
appendOctet(PduHeaders.CONTENT_TYPE);
// Message body
- makeMessageBody();
-
- return PDU_COMPOSE_SUCCESS; // Composing the message is OK
+ return makeMessageBody();
}
/**
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
index 8d57e5df5b0c..7037b6128c29 100644
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ b/core/java/com/google/android/mms/pdu/PduPersister.java
@@ -783,7 +783,7 @@ public class PduPersister {
Log.v(TAG, "Saving data to: " + uri);
}
- byte[] buffer = new byte[256];
+ byte[] buffer = new byte[8192];
for (int len = 0; (len = is.read(buffer)) != -1; ) {
os.write(buffer, 0, len);
}
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index 2241f6032dff..2beedada409f 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -101,11 +101,6 @@ void TextLayout::drawTextOnPath(SkPaint* paint, const jchar* text, int count,
SkScalar h_ = SkFloatToScalar(hOffset);
SkScalar v_ = SkFloatToScalar(vOffset);
- if (!needsLayout(text, count, bidiFlags)) {
- canvas->drawTextOnPathHV(text, count << 1, *path, h_, v_, *paint);
- return;
- }
-
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
text, 0, count, count, bidiFlags);
if (value == NULL) {
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 4b3324b7f16f..088062a7f2ce 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -21,13 +21,16 @@
#include <dlfcn.h>
#include <fcntl.h>
-#include <android_runtime/AndroidRuntime.h>
-#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_app_NativeActivity.h>
#include <android_runtime/android_util_AssetManager.h>
-#include <surfaceflinger/Surface.h>
-#include <ui/egl/android_natives.h>
+#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/AndroidRuntime.h>
#include <androidfw/InputTransport.h>
+
+#include <gui/Surface.h>
+
+#include <system/window.h>
+
#include <utils/Looper.h>
#include "JNIHelp.h"
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index d53644de318a..579d6ad858ab 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -30,7 +30,7 @@
#include <string.h>
#include <unistd.h>
-#include "binder/CursorWindow.h"
+#include <androidfw/CursorWindow.h>
#include "android_util_Binder.h"
#include "android_database_SQLiteCommon.h"
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index e061ac3d8e6a..80ecf2f3d02d 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -29,7 +29,7 @@
#include <string.h>
#include <unistd.h>
-#include "binder/CursorWindow.h"
+#include <androidfw/CursorWindow.h>
#include <sqlite3.h>
#include <sqlite3_android.h>
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b89273b6adec..599211e5e9f3 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -26,7 +26,7 @@
#include <utils/Vector.h>
#include <gui/SurfaceTexture.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
#include <camera/Camera.h>
#include <binder/IMemory.h>
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index f076cc85e3ba..aedf1e42cf73 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -19,7 +19,7 @@
#include <cutils/properties.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
#include <ui/PixelFormat.h>
#include <ui/DisplayInfo.h>
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index cdce4f9e1984..f0560c1e02bb 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -521,6 +521,20 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
}
+static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
+ SkPath* path, jfloat hOffset, jfloat vOffset, int flags, SkPaint* paint) {
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, 0, count, count, flags);
+ if (value == NULL) {
+ return;
+ }
+ const jchar* glyphs = value->getGlyphs();
+ size_t glyphsCount = value->getGlyphsCount();
+ int bytesCount = glyphsCount * sizeof(jchar);
+ renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path,
+ hOffset, vOffset, paint);
+}
+
static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
jint start, jint count, jint contextCount, jfloat x, jfloat y,
int flags, SkPaint* paint) {
@@ -551,6 +565,24 @@ static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
env->ReleaseStringChars(text, textArray);
}
+static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
+ SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) {
+ jchar* textArray = env->GetCharArrayElements(text, NULL);
+ renderTextOnPath(renderer, textArray + index, count, path,
+ hOffset, vOffset, flags, paint);
+ env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
+}
+
+static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, jstring text, jint start, jint end,
+ SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) {
+ const jchar* textArray = env->GetStringChars(text, NULL);
+ renderTextOnPath(renderer, textArray + start, end - start, path,
+ hOffset, vOffset, flags, paint);
+ env->ReleaseStringChars(text, textArray);
+}
+
static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
@@ -885,6 +917,10 @@ static JNINativeMethod gMethods[] = {
{ "nDrawText", "(ILjava/lang/String;IIFFII)V",
(void*) android_view_GLES20Canvas_drawText },
+ { "nDrawTextOnPath", "(I[CIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
+ { "nDrawTextOnPath", "(ILjava/lang/String;IIIFFII)V",
+ (void*) android_view_GLES20Canvas_drawTextOnPath },
+
{ "nDrawTextRun", "(I[CIIIIFFII)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
{ "nDrawTextRun", "(ILjava/lang/String;IIIIFFII)V",
(void*) android_view_GLES20Canvas_drawTextRun },
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 18bcea1e89e7..c38775212042 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -22,11 +22,13 @@
#include "android/graphics/GraphicsJNI.h"
#include <binder/IMemory.h>
+
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceTexture.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/Surface.h>
-#include <ui/Region.h>
+
#include <ui/Rect.h>
+#include <ui/Region.h>
#include <EGL/egl.h>
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 4fe76002d0bc..5483867cc70b 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -21,17 +21,19 @@
#include <android_runtime/android_graphics_SurfaceTexture.h>
#include <utils/misc.h>
+
+#include <EGL/egl_display.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
-#include <EGL/egl_display.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/Surface.h>
#include <SkBitmap.h>
#include <SkPixelRef.h>
-#include <gui/SurfaceTexture.h>
-#include <gui/SurfaceTextureClient.h>
+#include <ui/ANativeObjectBase.h>
namespace android {
@@ -44,7 +46,6 @@ static jfieldID gContext_EGLContextFieldID;
static jfieldID gSurface_EGLSurfaceFieldID;
static jfieldID gSurface_NativePixelRefFieldID;
static jfieldID gConfig_EGLConfigFieldID;
-static jfieldID gSurface_SurfaceFieldID;
static jfieldID gBitmap_NativeBitmapFieldID;
static inline EGLDisplay getDisplay(JNIEnv* env, jobject o) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a2b1117ddf95..d4d29ae0badd 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -147,7 +147,7 @@
@hide -->
<permission android:name="android.permission.SEND_SMS_NO_CONFIRMATION"
android:permissionGroup="android.permission-group.COST_MONEY"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_sendSmsNoConfirmation"
android:description="@string/permdesc_sendSmsNoConfirmation" />
@@ -194,7 +194,7 @@
@hide Pending API council approval -->
<permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"
android:permissionGroup="android.permission-group.MESSAGES"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_receiveEmergencyBroadcast"
android:description="@string/permdesc_receiveEmergencyBroadcast" />
@@ -383,7 +383,7 @@
<!-- Allows an application to install a location provider into the Location Manager -->
<permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_installLocationProvider"
android:description="@string/permdesc_installLocationProvider" />
@@ -461,7 +461,7 @@
@hide -->
<permission android:name="android.permission.CONNECTIVITY_INTERNAL"
android:permissionGroup="android.permission-group.NETWORK"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- ================================== -->
<!-- Permissions for accessing accounts -->
@@ -559,7 +559,7 @@
@hide -->
<permission android:name="android.permission.MANAGE_USB"
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_manageUsb"
android:description="@string/permdesc_manageUsb" />
@@ -568,7 +568,7 @@
@hide -->
<permission android:name="android.permission.ACCESS_MTP"
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_accessMtp"
android:description="@string/permdesc_accessMtp" />
@@ -611,7 +611,7 @@
Does not include placing calls. -->
<permission android:name="android.permission.MODIFY_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE_CALLS"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_modifyPhoneState"
android:description="@string/permdesc_modifyPhoneState" />
@@ -626,7 +626,7 @@
@hide Used internally. -->
<permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
android:permissionGroup="android.permission-group.PHONE_CALLS"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- ================================== -->
<!-- Permissions for sdcard interaction -->
@@ -651,7 +651,7 @@
android:permissionGroup="android.permission-group.STORAGE"
android:label="@string/permlab_mediaStorageWrite"
android:description="@string/permdesc_mediaStorageWrite"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- ============================================ -->
<!-- Permissions for low-level system interaction -->
@@ -675,15 +675,9 @@
android:label="@string/permlab_writeSettings"
android:description="@string/permdesc_writeSettings" />
- <!-- Allows an application to read or write the secure system settings. -->
- <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
- android:protectionLevel="signatureOrSystem"
- android:label="@string/permlab_writeSecureSettings"
- android:description="@string/permdesc_writeSecureSettings" />
-
<!-- Allows an application to modify the Google service map. -->
<permission android:name="android.permission.WRITE_GSERVICES"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_writeGservices"
android:description="@string/permdesc_writeGservices" />
@@ -757,19 +751,11 @@
android:label="@string/permlab_forceStopPackages"
android:description="@string/permdesc_forceStopPackages" />
- <!-- Allows an application to retrieve state dump information from system
- services. -->
- <permission android:name="android.permission.DUMP"
- android:permissionGroup="android.permission-group.PERSONAL_INFO"
- android:protectionLevel="signatureOrSystem"
- android:label="@string/permlab_dump"
- android:description="@string/permdesc_dump" />
-
<!-- @hide Allows an application to retrieve the content of the active window
An active window is the window that has fired an accessibility event. -->
<permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_retrieve_window_content"
android:description="@string/permdesc_retrieve_window_content" />
@@ -868,7 +854,7 @@
<!-- Allows applications to set the system time -->
<permission android:name="android.permission.SET_TIME"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_setTime"
android:description="@string/permdesc_setTime" />
@@ -964,7 +950,7 @@
<!-- Allows applications to write the apn settings -->
<permission android:name="android.permission.WRITE_APN_SETTINGS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:description="@string/permdesc_writeApnSettings"
android:label="@string/permlab_writeApnSettings" />
@@ -1035,7 +1021,7 @@
<!-- Allows an application to use any media decoder when decoding for playback
@hide -->
<permission android:name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"
- android:protectionLevel="signatureOrSystem"
+ android:protectionLevel="signature|system"
android:label="@string/permlab_anyCodecForPlayback"
android:description="@string/permdesc_anyCodecForPlayback" />
@@ -1052,6 +1038,21 @@
android:label="@string/permgrouplab_developmentTools"
android:description="@string/permgroupdesc_developmentTools" />
+ <!-- Allows an application to read or write the secure system settings. -->
+ <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
+ android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
+ android:protectionLevel="signature|system|development"
+ android:label="@string/permlab_writeSecureSettings"
+ android:description="@string/permdesc_writeSecureSettings" />
+
+ <!-- Allows an application to retrieve state dump information from system
+ services. -->
+ <permission android:name="android.permission.DUMP"
+ android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
+ android:protectionLevel="signature|system|development"
+ android:label="@string/permlab_dump"
+ android:description="@string/permdesc_dump" />
+
<!-- Configure an application for debugging. -->
<permission android:name="android.permission.SET_DEBUG_APP"
android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
@@ -1099,7 +1100,7 @@
<permission android:name="android.permission.STATUS_BAR"
android:label="@string/permlab_statusBar"
android:description="@string/permdesc_statusBar"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to be the status bar. Currently used only by SystemUI.apk
@hide -->
@@ -1120,7 +1121,7 @@
<permission android:name="android.permission.UPDATE_DEVICE_STATS"
android:label="@string/permlab_batteryStats"
android:description="@string/permdesc_batteryStats"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to open windows that are for use by parts
of the system user interface. Not for use by third party apps. -->
@@ -1160,7 +1161,7 @@
<permission android:name="android.permission.SHUTDOWN"
android:label="@string/permlab_shutdown"
android:description="@string/permdesc_shutdown"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to tell the activity manager to temporarily
stop application switches, putting it into a special mode that
@@ -1170,7 +1171,7 @@
<permission android:name="android.permission.STOP_APP_SWITCHES"
android:label="@string/permlab_stopAppSwitches"
android:description="@string/permdesc_stopAppSwitches"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to retrieve the current state of keys and
switches. This is only for use by the system.-->
@@ -1205,7 +1206,7 @@
<permission android:name="android.permission.BIND_WALLPAPER"
android:label="@string/permlab_bindWallpaper"
android:description="@string/permdesc_bindWallpaper"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Must be required by device administration receiver, to ensure that only the
system can interact with it. -->
@@ -1232,7 +1233,7 @@
<permission android:name="android.permission.INSTALL_PACKAGES"
android:label="@string/permlab_installPackages"
android:description="@string/permdesc_installPackages"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to clear user data -->
<permission android:name="android.permission.CLEAR_APP_USER_DATA"
@@ -1244,27 +1245,33 @@
<permission android:name="android.permission.DELETE_CACHE_FILES"
android:label="@string/permlab_deleteCacheFiles"
android:description="@string/permdesc_deleteCacheFiles"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to delete packages. -->
<permission android:name="android.permission.DELETE_PACKAGES"
android:label="@string/permlab_deletePackages"
android:description="@string/permdesc_deletePackages"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to move location of installed package.
@hide -->
<permission android:name="android.permission.MOVE_PACKAGE"
android:label="@string/permlab_movePackage"
android:description="@string/permdesc_movePackage"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to change whether an application component (other than its own) is
enabled or not. -->
<permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
android:label="@string/permlab_changeComponentState"
android:description="@string/permdesc_changeComponentState"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
+
+ <!-- @hide Allows an application to grant or revoke specific permissions. -->
+ <permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS"
+ android:label="@string/permlab_grantRevokePermissions"
+ android:description="@string/permdesc_grantRevokePermissions"
+ android:protectionLevel="signature" />
<!-- Allows an application to use SurfaceFlinger's low level features -->
<permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
@@ -1277,7 +1284,7 @@
<permission android:name="android.permission.READ_FRAME_BUFFER"
android:label="@string/permlab_readFrameBuffer"
android:description="@string/permdesc_readFrameBuffer"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Required to be able to disable the device (very dangerous!). -->
<permission android:name="android.permission.BRICK"
@@ -1289,7 +1296,7 @@
<permission android:name="android.permission.REBOOT"
android:label="@string/permlab_reboot"
android:description="@string/permdesc_reboot"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows low-level access to power management -->
<permission android:name="android.permission.DEVICE_POWER"
@@ -1329,7 +1336,7 @@
<permission android:name="android.permission.MASTER_CLEAR"
android:label="@string/permlab_masterClear"
android:description="@string/permdesc_masterClear"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to call any phone number, including emergency
numbers, without going through the Dialer user interface for the user
@@ -1337,34 +1344,34 @@
<permission android:name="android.permission.CALL_PRIVILEGED"
android:label="@string/permlab_callPrivileged"
android:description="@string/permdesc_callPrivileged"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to perform CDMA OTA provisioning @hide -->
<permission android:name="android.permission.PERFORM_CDMA_PROVISIONING"
android:label="@string/permlab_performCdmaProvisioning"
android:description="@string/permdesc_performCdmaProvisioning"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows enabling/disabling location update notifications from
the radio. Not for use by normal applications. -->
<permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
android:label="@string/permlab_locationUpdates"
android:description="@string/permdesc_locationUpdates"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows read/write access to the "properties" table in the checkin
database, to change values that get uploaded. -->
<permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
android:label="@string/permlab_checkinProperties"
android:description="@string/permdesc_checkinProperties"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to collect component usage
statistics @hide -->
<permission android:name="android.permission.PACKAGE_USAGE_STATS"
android:label="@string/permlab_pkgUsageStats"
android:description="@string/permdesc_pkgUsageStats"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to collect battery statistics -->
<permission android:name="android.permission.BATTERY_STATS"
@@ -1377,7 +1384,7 @@
<permission android:name="android.permission.BACKUP"
android:label="@string/permlab_backup"
android:description="@string/permdesc_backup"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows a package to launch the secure full-backup confirmation UI.
ONLY the system process may hold this permission.
@@ -1392,7 +1399,7 @@
<permission android:name="android.permission.BIND_REMOTEVIEWS"
android:label="@string/permlab_bindRemoteViews"
android:description="@string/permdesc_bindRemoteViews"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to tell the AppWidget service which application
can access AppWidget's data. The normal user flow is that a user
@@ -1404,7 +1411,7 @@
android:permissionGroup="android.permission-group.PERSONAL_INFO"
android:label="@string/permlab_bindGadget"
android:description="@string/permdesc_bindGadget"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows applications to change the background data setting
@hide pending API council -->
@@ -1424,7 +1431,7 @@
besides global search. -->
<permission android:name="android.permission.GLOBAL_SEARCH"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Internal permission protecting access to the global search
system: ensures that only the system can access the provider
@@ -1442,14 +1449,14 @@
own apk as Ghod Intended. -->
<permission android:name="android.permission.SET_WALLPAPER_COMPONENT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allow an application to read and write the cache partition.
@hide -->
<permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"
android:label="@string/permlab_cache_filesystem"
android:description="@string/permdesc_cache_filesystem"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Must be required by default container service so that only
the system can bind to it and use it to copy
@@ -1465,14 +1472,14 @@
@hide
-->
<permission android:name="android.permission.CRYPT_KEEPER"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to read historical network usage for
specific networks and applications. @hide -->
<permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY"
android:label="@string/permlab_readNetworkUsageHistory"
android:description="@string/permdesc_readNetworkUsageHistory"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Allows an application to manage network policies (such as warning and disable
limits) and to define application-specific rules. @hide -->
@@ -1487,7 +1494,7 @@
<permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING"
android:label="@string/permlab_modifyNetworkAccounting"
android:description="@string/permdesc_modifyNetworkAccounting"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- C2DM permission.
@hide Used internally.
@@ -1503,7 +1510,7 @@
<permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT"
android:label="@string/permlab_packageVerificationAgent"
android:description="@string/permdesc_packageVerificationAgent"
- android:protectionLevel="signatureOrSystem" />
+ android:protectionLevel="signature|system" />
<!-- Must be required by package verifier receiver, to ensure that only the
system can interact with it.
diff --git a/core/res/res/layout/app_perms_summary.xml b/core/res/res/layout/app_perms_summary.xml
index 3f99dde59397..77dbc2e97479 100755
--- a/core/res/res/layout/app_perms_summary.xml
+++ b/core/res/res/layout/app_perms_summary.xml
@@ -32,6 +32,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
+ <!-- List view containing list of new permissions categorized by groups. -->
+ <LinearLayout
+ android:id="@+id/new_perms_list"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:paddingLeft="16dip"
+ android:paddingRight="12dip"
+ android:layout_height="wrap_content" />
+
<!-- List view containing list of dangerous permissions categorized by groups. -->
<LinearLayout
android:id="@+id/dangerous_perms_list"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index abf667693b01..49e0fd518390 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -315,6 +315,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit dalk gebruik om belangrike tabletvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit gebruik om belangrike foonvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"stel voorkeurprogramme"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Laat die program toe om jou voorkeur-programme te verander. Kwaadwillige programme kan stilweg die programme wat loop, verander, wat jou bestaande programme bedrieg om private data oor jou in te samel."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"verander globale stelselinstellings"</string>
@@ -1006,6 +1010,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Stel datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Stel"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Verstek"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Geen toestemmings benodig nie"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Versteek"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Wys alle"</b></string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 18fb40584a08..5cd17b35ae74 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"የመተግበሪያ ምንዝሮችን አንቃ ወይም አቦዝን"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"የሌላ መተግበሪያ ክፍለ አካል እንደነቃ ወይም እንዳልነቃ መተግበሪያው እንዲለውጥ ይፈቅዳል፡፡ አስፈላጊ የጡባዊ ተኮ አቅሞችን ለማስወገድ ጎጂ መተግበሪያዎች ይሄንን ሊጠቀሙበት ይችላሉ፡፡ ከፍቃድ ጋር ጥንቃቄ መወሰድ ይገባል፤ ልክ የማያገለግል፣ ወጥ ያልሆነ፣ ወይም ያልተረጋጋ ሁኔታ ወደ የመተግበሪያ ክፍለ አካል ማግኘት እንደሚቻል ሁሉ፡፡"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"የሌላ መተግበሪያ ክፍለ አካል እንደነቃ ወይም እንዳልነቃ መተግበሪያው እንዲለውጥ ይፈቅዳል፡፡ አስፈላጊ የስልክ አቅሞችን ለማስወገድ ተንኮል አዘል መተግበሪያዎች ይሄንን ሊጠቀሙበት ይችላሉ፡፡ ከፍቃድ ጋር ጥንቃቄ መወሰድ ይገባል፤ ልክ የማያገለግል፣ ወጥ ያልሆነ፣ ወይም ያልተረጋጋ ሁኔታ ወደ የመተግበሪያ ክፍለ አካል ማግኘት እንደሚቻል ሁሉ፡፡"</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ተመራጭ መተግበሪያዎች አዘጋጅ"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ተመራጭ መተግበሪያዎችህን ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ ካንተ የግል ውሂብ ለመሰብሰብ ያሉትን መተግበሪያዎች በመላክ፤ በመሄድ ላይ ያሉ መተግበሪያዎችን ተንኮል አዘል መተግበሪያዎች በዝምታ ሊለውጡ ይችላሉ፡፡"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"የሁሉንም ስርዓት ቅንብሮች ቀይር"</string>
@@ -764,7 +768,7 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"የፓኬጅ አረጋጋጮችን ጥየቃ ለማድረግ ያዡ ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"ተከታታይ ወደቦችን ድረስ"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Allows the holder to access serial ports using the SerialManager API. የተከታታይ አደራጅ APIን በመጠቀም ያዡ የተከታታይ ወደቦችን እንዲደርስ ይፈቅዳል።"</string>
- <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"ይዘት አቅራቢዎች በውጭ በኩል ድረስባቸው"</string>
+ <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"ይዘት አቅራቢዎችን በውጭ በኩል ድረስባቸው"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"ያዢውን ከቀፎው ወደሚመጡ የይዘት አቅራቢዎች እንዲደርስ ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በፍጹም ማስፈለግ የለባቸውም።"</string>
<string name="save_password_message" msgid="767344687139195790">"አሳሹ ይህን ይለፍ ቃል እንዲያስታወስ ይፈልጋሉ?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"አሁን አይደለም"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"ውሂብ አዘጋጅ"</string>
<string name="date_time_set" msgid="5777075614321087758">"አዘጋጅ"</string>
<string name="default_permission_group" msgid="2690160991405646128">"ነባሪ"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"ምንም ፍቃዶች አይጠየቁም"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"ደብቅ "</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"ሁሉንም አሳይ"</b></string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a98a7d4bf6e3..7300fa5439eb 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"تمكين مكونات التطبيق أو تعطيلها"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"للسماح للتطبيق بتغيير ما إذا كان سيتم تمكين مكون لتطبيق آخر أم لا. يمكن أن تستخدم التطبيقات الضارة ذلك لتعطيل قدرات الجهاز اللوحي المهمة. يجب توخي الحذر عند استخدام هذا الإذن، وذلك لأنه من الممكن أن يؤدي ذلك إلى جعل حالة مكونات التطبيق غير قابلة للاستخدام أو غير متناسقة أو غير مستقرة."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"للسماح للتطبيق بتغيير ما إذا كان سيتم تمكين مكون لتطبيق آخر أم لا. يمكن أن تستخدم التطبيقات الضارة ذلك لتعطيل قدرات الهاتف المهمة. يجب توخي الحذر عند استخدام هذا الإذن، وذلك لأنه من الممكن أن يؤدي ذلك إلى جعل حالة مكونات التطبيق غير قابلة للاستخدام أو غير متناسقة أو غير مستقرة."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"تعيين التطبيقات المفضلة"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"للسماح للتطبيق بتعديل التطبيقات المفضلة. يمكن أن تغيّر التطبيقات الضارة التطبيقات قيد التشغيل بشكل غير ملحوظ، وانتحال صفة التطبيقات الحالية لجمع بيانات خاصة منك."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"تعديل إعدادات النظام العمومية"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"تعيين التاريخ"</string>
<string name="date_time_set" msgid="5777075614321087758">"تعيين"</string>
<string name="default_permission_group" msgid="2690160991405646128">"افتراضي"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"لا أذونات مطلوبة"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"إخفاء"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"عرض الكل"</b></string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 233d5a95f02a..9a578da31f6a 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"уключыць або адключыць кампаненты прыкладання"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дазваляе прыкладанням змяняць вызначэнне таго, будзе ўключаны кампанент іншага прыкладання ці не. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў планшэта. З гэтым дазволам трэба быць уважлівым, бо можна прывесці кампаненты прыкладання ў непрыдатны, супярэчлівы або няўстойлівы стан."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дазваляе прыкладанням змяняць вызначэнне таго, будзе ўключаны кампанент іншага прыкладання ці не. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў тэлефона. З гэтым дазволам трэба быць уважлівым, бо можна прывесці кампаненты прыкладання ў непрыдатны, супярэчлівы або няўстойлівы стан."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"усталяваць пажаданыя прыкладанні"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дазваляе прыкладанням змяняць вашы пажаданыя прыкладанні. Шкоднасныя прыкладанні могуць непрыкметна змяняць запушчаныя прыкладанні, падмяняючы існуючыя прыкладанні, каб збiраць вашы асабістыя дадзеныя."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"змена глабальных параметраў сістэмы"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Усталяваць дату"</string>
<string name="date_time_set" msgid="5777075614321087758">"Задаць"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Па змаўчанні"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Дазволу не патрабуецца"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Не паказваць"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Паказаць усе"</b></string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 66516b961900..06a2577b435b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"активиране или деактивиране на компоненти на приложенията"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Разрешава на приложението да активира или деактивира компонент на друго приложение. Злонамерените приложения могат да използват това, за да деактивират важни възможности на таблета. С това разрешение трябва да се внимава, тъй като компонентите на приложенията може да бъдат приведени в неизползваемо, несъгласувано или нестабилно състояние."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Разрешава на приложението да активира или деактивира компонент на друго приложение. Злонамерените приложения могат да използват това, за да деактивират важни възможности на телефона. С това разрешение трябва да се внимава, тъй като компонентите на приложенията може да бъдат приведени в неизползваемо, несъгласувано или нестабилно състояние."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"задаване на предпочитани приложения"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Разрешава на приложението да променя предпочитаните ви приложения. Злонамерените приложения могат скрито да променят приложенията, които се изпълняват, като ги фалшифицират, за да се сдобият с ваши лични данни."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"промяна на глобалните системни настройки"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Задаване на дата"</string>
<string name="date_time_set" msgid="5777075614321087758">"Задаване"</string>
<string name="default_permission_group" msgid="2690160991405646128">"По подразбиране"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Не се изискват разрешения"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Скриване"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Показване на всички"</b></string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index b848c2cf3dd9..907392a57a35 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permet que l\'aplicació canviï si un component d\'una altra aplicació està activat o no. Les aplicacions malicioses poden utilitzar aquesta funció per desactivar funcions importants de la tauleta. Cal anar amb compte amb aquest permís, ja que és possible que els components de l\'aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permet que l\'aplicació canviï si un component d\'una altra aplicació està activat o no. Les aplicacions malicioses poden utilitzar aquesta funció per desactivar funcions importants del telèfon. Cal anar amb compte amb aquest permís, perquè és possible que els components de l\'aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"defineix les aplicacions preferides"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet que l\'aplicació modifiqui les aplicacions preferides. Les aplicacions malicioses poden canviar silenciosament les aplicacions que s\'executen, falsejar les aplicacions existents o recollir dades privades de l\'usuari."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuració global del sistema"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establiment de data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Amaga"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra\'ls tots"</b></string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 544395f7b256..f889c3be166a 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí tabletu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí telefonu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavení upřednostňovaných aplikací"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikaci upravit preferované aplikace. Škodlivé aplikace mohou tajně měnit běžící aplikace a přinutit stávající aplikace, aby shromažďovaly vaše soukromé údaje."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"změna globálních nastavení systému"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Výchozí"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skrýt"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Zobrazit vše"</b></string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ceefe1d43d93..61503ebfda0c 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Tillader, at appen kan ændre, om en komponent i en anden app er aktiveret eller ej. Ondsindede apps kan bruge dette til at deaktivere vigtige tabletfunktioner. Man skal være forsigtig med denne tilladelse, da det er muligt at bringe appkomponenter ind i en ubrugelig, inkonsekvent eller ustabil tilstand."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Tillader, at appen kan ændre, om en komponent i en anden app er aktiveret eller ej. Ondsindede apps kan bruge dette til at deaktivere vigtige funktioner på telefonen. Denne tilladelse skal anvendes med forsigtighed, da det kan forårsage ubrugelige eller ustabile appkomponenter."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angive foretrukne apps"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Tillader, at appen kan ændre dine foretrukne apps. Ondsindede apps kan ubemærket ændre kørende apps derved udgive sig for at være dine eksisterende apps og på den måde indsamle private data fra dig."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"rediger globale systemindstillinger"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Angiv dato"</string>
<string name="date_time_set" msgid="5777075614321087758">"Angiv"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Der kræves ingen tilladelser"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skjul"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3b3d08d30e98..1d1748b11f1e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"App-Komponenten aktivieren oder deaktivieren"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ermöglicht der App, Komponenten einer anderen App zu aktivieren oder zu deaktivieren. Schädliche Apps können so wichtige Tabletfunktionen deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die App-Komponenten unbrauchbar, inkonsistent oder instabil werden können."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ermöglicht der App, Komponenten einer anderen App zu aktivieren oder zu deaktivieren. Schädliche Apps können so wichtige Telefonfunktionen deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die App-Komponenten unbrauchbar, inkonsistent oder instabil werden können."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"Bevorzugte Apps festlegen"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ermöglicht der App, Änderungen an Ihren bevorzugten Apps vorzunehmen. Schädliche Apps können so aktive Apps ohne Ihr Wissen ändern, damit die vorhandenen Apps private Daten von Ihnen erfassen."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"allgemeine Systemeinstellungen ändern"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum festlegen"</string>
<string name="date_time_set" msgid="5777075614321087758">"Speichern"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Keine Berechtigungen erforderlich"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ausblenden"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Alle anzeigen"</b></string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e2bc244ad4a3..b432d46e3664 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Επιτρέπει στην εφαρμογή την αλλαγή της κατάστασης ενεργοποίησης κάποιου στοιχείου. Τυχόν κακόβουλες εφαρμογές μπορούν να χρησιμοποιήσουν αυτήν τη δυνατότητα για την απενεργοποίηση σημαντικών δυνατοτήτων του tablet. Αυτή η άδεια θα πρέπει να χρησιμοποιείται προσεκτικά, καθώς είναι πιθανό να θέσει τα στοιχεία εφαρμογών σε κατάσταση αχρηστίας, μη συνοχής και αστάθειας."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Επιτρέπει στην εφαρμογή την αλλαγή της κατάστασης ενεργοποίησης κάποιου στοιχείου. Τυχόν κακόβουλες εφαρμογές μπορούν να χρησιμοποιήσουν αυτήν τη δυνατότητα για την απενεργοποίηση σημαντικών δυνατοτήτων του τηλεφώνου. Αυτή η άδεια θα πρέπει να χρησιμοποιείται προσεκτικά, καθώς είναι πιθανό να θέσει τα στοιχεία εφαρμογών σε κατάσταση αχρηστίας, μη συνοχής και αστάθειας."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ορισμός προτιμώμενων εφαρμογών"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Επιτρέπει στην εφαρμογή την τροποποίηση των εφαρμογών της προτίμησής σας. Τυχόν κακόβουλες εφαρμογές ενδέχεται να να αλλάξουν χωρίς ειδοποίηση τις εφαρμογές που εκτελούνται, \"ξεγελώντας\" τις υπάρχουσες εφαρμογές ώστε να συλλέξουν ιδιωτικά δεδομένα από εσάς."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"τροποποίηση καθολικών ρυθμίσεων συστήματος"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ορισμός ημερομηνίας"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ορισμός"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Προεπιλεγμένο"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Δεν απαιτούνται άδειες"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Απόκρυψη"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Εμφάνιση όλων"</b></string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bed4de28c014..1013b11bdf72 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important tablet capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important phone capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"set preferred apps"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Allows the app to modify your preferred apps. Malicious apps may silently change the apps that are run, spoofing your existing apps to collect private data from you."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modify global system settings"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
<string name="date_time_set" msgid="5777075614321087758">"Set"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Hide"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Show all"</b></string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 89f51c8a768f..a019c654bebc 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o no. Las aplicaciones maliciosas pueden utilizar este permiso para desactivar funciones importantes de la tableta. Es necesario ser precavido con este permiso, ya que es posible que los componentes de la aplicación queden inservibles, incoherentes o inestables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o no. Las aplicaciones maliciosas pueden utilizar este permiso para desactivar funciones importantes del dispositivo. Es necesario ser precavido con este permiso, ya que es posible que los componentes de la aplicación queden inservibles, incoherentes o inestables."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"establecer aplicaciones preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que la aplicación modifique tus aplicaciones preferidas. Las aplicaciones maliciosas pueden modificar sin aviso las aplicaciones que se ejecutan y así engañar a tus aplicaciones existentes para que recopilen tu información privada."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -764,8 +768,8 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permite que el titular solicite verificadores de paquetes. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"Acceder a los puertos serie"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite acceder a puertos serie a través de la API SerialManager."</string>
- <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"acceder a proveedores de contenido externamente"</string>
- <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permite a su titular a acceder a los proveedores de contenido desde el shell. Las aplicaciones normales nunca deberían necesitarlo."</string>
+ <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"acceder a proveedores externamente"</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permite acceder a los proveedores de contenido desde la interfaz. Las aplicaciones normales nunca deberían necesitarlo."</string>
<string name="save_password_message" msgid="767344687139195790">"¿Quieres recordar esta contraseña en el navegador?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ahora no."</string>
<string name="save_password_remember" msgid="6491879678996749466">"Recuerda"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Configurar fecha"</string>
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 9499214f6bcd..8d2a83661b9a 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"habilitar o inhabilitar componentes de la aplicación"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden usar este permiso para inhabilitar funciones importantes del tablet. Este permiso se debe usar con precaución, ya que los componentes de las aplicaciones se pueden volver inestables, incoherentes o inservibles."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden usar este permiso para inhabilitar funciones importantes del teléfono. Este permiso se debe usar con precaución, ya que los componentes de las aplicaciones se pueden volver inestables, incoherentes o inservibles."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"establecer aplicaciones preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que la aplicación modifique las aplicaciones preferidas del usuario. De esta forma, las aplicaciones malintencionadas pueden cambiar sin aviso las aplicaciones que se están ejecutando y falsificarlas para obtener datos privados del usuario."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Establecer fecha"</string>
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"No es necesario ningún permiso"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index da06538a88ae..7b1d280cbbc4 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Võimaldab rakendusel määrata, kas teise rakenduse komponent on lubatud või mitte. Pahatahtlikud rakendused võivad kasutada seda oluliste tahvelarvutirakenduste keelamiseks. Nende õiguste puhul peab olema ettevaatlik, kuna need võimaldavad muuta rakenduse komponente kasutuks, ebaühtlaseks või ebastabiilseks."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Võimaldab rakendusel määrata, kas teise rakenduse komponent on lubatud või mitte. Pahatahtlikud rakendused võivad kasutada seda oluliste telefonirakenduste keelamiseks. Nende õiguste puhul peab olema ettevaatlik, kuna need võimaldavad muuta rakenduse komponente kasutuks, ebaühtlaseks või ebastabiilseks."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"Eelistatud rakenduste määramine"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Võimaldab rakendusel muuta teie eelistatud rakendusi. Pahatahtlikud rakendused võivad salaja muuta töötavaid rakendusi, pettes teie olemasolevad rakendused koguma teilt privaatseid andmeid."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"muuda üldisi süsteemiseadeid"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Kuupäeva määramine"</string>
<string name="date_time_set" msgid="5777075614321087758">"Määra"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Vaikimisi"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Lube pole vaja"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Peida"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Näita kõiki"</b></string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9a6a293a023a..084e16deadfa 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"فعال یا غیر فعال کردن اجزای برنامه"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"به برنامه اجازه می‎دهد تا فعال بودن یا نبودن اجزای برنامه دیگر را تغییر دهد. برنامه‎های مخرب می‎توانند از آن استفاده کنند تا قابلیتهای مهم رایانه لوحی را غیرفعال کنند. باید دقت کرد که با این مجوز ممکن است وضعیت اجزای برنامه ناپایدار، ناهماهنگ یا غیرقابل استفاده شود."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"به برنامه اجازه می‎دهد تا فعال بودن یا غیرفعال بودن جزئیات برنامه دیگر را تغییر دهد. برنامه‎های مخرب می‎توانند از آن استفاده کنند تا ویژگیهای مهم را غیرفعال کنند. برای این مجوز باید دقت کنید چون ممکن است وضعیت جزئیات برنامه ناپایدار، بی‎ثبات یا غیرقابل استفاده شود."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"تنظیم برنامه‎های ترجیحی"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"به برنامه اجازه می‎دهد تا برنامه‎های ترجیحی شما را تغییر دهد. برنامه‎های مخرب می‎توانند بدون اعلان برنامه‎هایی را که اجرا می‎شوند، تغییر دهند خود را به جای برنامه‎های کنونی قلمداد کنند تا داده‎های شخصی را از شما جمع آوری کنند."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"اصلاح کردن تنظیمات سیستم کلی"</string>
@@ -765,7 +769,7 @@
<string name="permlab_serialPort" msgid="546083327654631076">"دسترسی به درگاه‌های سریال"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"به دارنده اجازه می‌دهد با استفاده از SerialManager API به درگاه‌های سریال دسترسی داشته باشد."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"دسترسی خارجی به ارائه‌دهندگان محتوا"</string>
- <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"به دارنده اجازه می‌دهد تا از خارج برنامه به ارائه دهندگان محتوا دسترسی داشته باشد. هرگز برای برنامه‌های معمولی به آن نیازی نیست."</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"به دارنده اجازه می‌دهد تا از خارج برنامه به ارائه‌دهندگان محتوا دسترسی داشته باشد. هرگز برای برنامه‌های معمولی به آن نیازی نیست."</string>
<string name="save_password_message" msgid="767344687139195790">"می خواهید مرورگر این رمز ورود را به خاطر داشته باشد؟"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"اکنون خیر"</string>
<string name="save_password_remember" msgid="6491879678996749466">"به خاطر سپردن"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"تاریخ تنظیم"</string>
<string name="date_time_set" msgid="5777075614321087758">"تنظیم"</string>
<string name="default_permission_group" msgid="2690160991405646128">"پیش فرض"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"مجوزی لازم نیست"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"پنهان کردن"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"نمایش همه"</b></string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 2fe9b4eaa9fa..a159eb65cb0a 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Antaa sovelluksen muuttaa, onko toisen sovelluksen komponentti käytössä vai ei. Haitalliset sovellukset voivat käyttää tätä tablet-laitteen tärkeiden ominaisuuksien poistamiseen käytöstä. Tämän luvan käyttöönotto edellyttää varovaisuutta, sillä sen avulla sovelluskomponentit on mahdollista saada epäkäytettävään, epäyhtenäiseen tai epävakaaseen tilaan."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Antaa sovelluksen muuttaa sitä, onko toisen sovelluksen komponentti käytössä vai ei. Haitalliset sovellukset voivat käyttää tätä puhelimen tärkeiden ominaisuuksien poistamiseen käytöstä. Tämän luvan käyttöönotto edellyttää varovaisuutta, sillä sen avulla sovelluskomponentit on mahdollista saada epäkäytettävään, epäyhtenäiseen tai epävakaaseen tilaan."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ensisijaisten sovellusten asettaminen"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Antaa sovelluksen muokata ensisijaisia sovelluksia. Haitalliset sovellukset voivat muuttaa käynnistettäviä sovelluksia huomaamattomasti ja kerätä henkilökohtaisia tietoja matkimalla nykyisiä sovelluksia."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"muokkaa yleisiä järjestelmän asetuksia"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Aseta päivämäärä"</string>
<string name="date_time_set" msgid="5777075614321087758">"Aseta"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Oletus"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Lupia ei tarvita"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Piilota"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Näytä kaikki"</b></string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d6e8f301a0b9..3fcb3b7ce88c 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants de l\'application"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permet à l\'application d\'activer ou de désactiver un composant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver les fonctionnalités principales de votre tablette. Cette autorisation doit être utilisée avec prudence, car elle peut rendre les composants d\'une application instables, voire inutilisables."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permet à l\'application d\'activer ou de désactiver un composant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver les fonctionnalités principales de votre téléphone. Cette autorisation doit être utilisée avec prudence, car elle peut rendre les composants d\'une application instables, voire inutilisables."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"définir les applications préférées"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet à l\'application de modifier vos applications préférées. Des applications malveillantes peuvent exploiter cette fonctionnalité pour modifier les applications exécutées en usurpant l\'identité de vos applications existantes dans le but de recueillir des données privées."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"Modification des paramètres généraux du système"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Définir la date"</string>
<string name="date_time_set" msgid="5777075614321087758">"Définir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Par défaut"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Masquer"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tout afficher"</b></string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f5a3cb76a6b7..f32322ed613a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"एप्‍लिकेशन घटकों को सक्षम या अक्षम करें"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"एप्‍लिकेशन को यह बदलने देता है कि किसी अन्‍य एप्‍लिकेशन का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्‍लिकेशन महत्‍वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्‍लिकेशन घटकों के अनुपयोगी, असंगत, या अस्‍थिर स्‍थिति में जाने की संभावना है."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"एप्‍लिकेशन को यह बदलने देता है कि किसी अन्‍य एप्‍लिकेशन का घटक सक्षम है या नहीं. दुर्भावनापूर्ण एप्‍लिकेशन महत्‍वपूर्ण फ़ोन क्षमताओं को अक्षम करने में इसका उपयोग कर सकते हैं. इस अनुमति का उपयोग सावधानी के साथ करना चाहिए, क्योंकि इससे एप्‍लिकेशन घटकों के अनुपयोगी, असंगत, या अस्‍थिर स्‍थिति में जाने की संभावना है."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा एप्‍लिकेशन सेट करें"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"एप्लिकेशन को आपके पसंदीदा एप्लिकेशन को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन आपसे निजी डेटा एकत्रित करने के लिए आपके मौजूदा एप्लिकेशन को स्पूफ़ करके, चलाए जाने वाले एप्लिकेशन को चुपचाप बदल सकते हैं."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"वैश्विक सिस्‍टम सेटिंग संशोधित करें"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"दिनांक सेट करें"</string>
<string name="date_time_set" msgid="5777075614321087758">"सेट करें"</string>
<string name="default_permission_group" msgid="2690160991405646128">"डिफ़ॉल्ट"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"किसी अनुमति की आवश्‍यकता नहीं है"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"छुपाएं"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"सभी दिखाएं"</b></string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 01378666557e..8b8a51f81113 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Omogućuje aplikaciji da promijeni hoće li komponenta neke druge aplikacije biti omogućena ili neće. Zlonamjerne aplikacije mogu to upotrijebiti da bi onemogućile važne mogućnosti tabletnog računala. Treba biti oprezan s tom dozvolom jer je moguće dovesti komponente aplikacija u neupotrebljivo, nedosljedno ili nestabilno stanje."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Omogućuje aplikaciji da promijeni hoće li komponenta neke druge aplikacije biti omogućena. Zlonamjerne aplikacije mogu to upotrijebiti da bi onemogućile važne mogućnosti telefona. Treba biti oprezan s tom dozvolom jer je moguće dovesti komponente aplikacija u neupotrebljivo, nedosljedno ili nestabilno stanje."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"postavljanje željenih aplikacija"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Omogućuje aplikaciji promjenu vaših željenih aplikacija. Zlonamjerne aplikacije mogu potajno promijeniti aplikacije koje su pokrenute, zavaravajući vaše postojeće aplikacije kako bi prikupljale privatne podatke od vas."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"izmjena postavki globalnog sustava"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Zadano"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nije potrebno dopuštenje"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Sakrij"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaži sve"</b></string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 54e8b06b4e8d..7f8999065bab 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"alkalmazáskomponensek be- és kikapcsolása"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a táblagép fontos funkcióinak kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabilak lesznek."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a telefon fontos funkcióinak kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabilak lesznek."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"előnyben részesített alkalmazások beállítása"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lehetővé teszi az alkalmazás számára a preferált alkalmazások módosítását. A rosszindulatú alkalmazások ezáltal észrevétlenül megváltoztathatják a futó alkalmazásokat, személyes adatokat gyűjtve Öntől."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"rendszer globális beállításainak módosítása"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Dátum beállítása"</string>
<string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Alapértelmezett"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nincs szükség engedélyre"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Elrejtés"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Az összes megjelenítése"</b></string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ac5d46310a7a..52453062e930 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan ini untuk menonaktifkan kemampuan tablet yang penting. Izin ini harus digunakan dengan hati-hati karena dapat menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan izin ini untuk menonaktifkan kemampuan ponsel yang penting. Izin ini harus digunakan dengan hati-hati, karena mungkin saja menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"menyetel apl yang disukai"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Mengizinkan apl memodifikasi apl pilihan Anda. Apl berbahaya dapat diam-diam mengubah apl yang berjalan, menipu apl yang ada untuk mengumpulkan data pribadi dari Anda."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"ubah setelan sistem global"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setel tanggal"</string>
<string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Bawaan"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Sembunyikan"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tampilkan semua"</b></string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 77733b313e13..408b3466bb62 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"attivazione/disattivazione componenti applicazioni"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Consente all\'applicazione di cambiare lo stato di attivazione o disattivazione del componente di un\'altra applicazione. Le applicazioni dannose potrebbero farne uso per disattivare importanti funzionalità del tablet. È necessario prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Consente all\'applicazione di cambiare lo stato di attivazione o disattivazione del componente di un\'altra applicazione. Le applicazioni dannose potrebbero farne uso per disattivare importanti funzionalità del telefono. È necessario prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"impostazione applicazioni preferite"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Consente all\'applicazione di modificare le tue applicazioni preferite. Le applicazioni dannose potrebbero cambiare di nascosto le applicazioni che vengono eseguite, facendo in modo che le applicazioni esistenti raccolgano dati riservati su di te."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modifica impostazioni di sistema globali"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Imposta data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predefinito"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nessuna autorizzazione richiesta"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Nascondi"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra tutto"</b></string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index a232c69c6388..3cef8bb342af 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"הפעלה או השבתה של רכיבי יישומים"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"מאפשר ליישום לשנות את מצב ההפעלה של רכיב ביישום אחר. יישומים זדוניים עלולים להשתמש בכך כדי להשבית יכולות חשובות של הטבלט. יש לנהוג בהרשאה זו בזהירות, מכיוון שהיא יכולה להביא רכיבי יישומים למצב לא שמיש, לא עקבי או לא יציב."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"מאפשר ליישום לשנות את מצב ההפעלה של רכיב ביישום אחר. יישומים זדוניים עלולים להשתמש בכך כדי להשבית יכולות חשובות של הטלפון. יש לנהוג בהרשאה זו בזהירות, מכיוון שהיא יכולה להביא רכיבי יישומים למצב לא שמיש, לא עקבי או לא יציב."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"הגדרת יישומים מועדפים"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"מאפשר ליישום לשנות את היישומים המועדפים עליך. יישומים זדוניים עלולים לשנות בחשאי את היישומים שמופעלים, תוך שידול במרמה של היישומים הקיימים שלך לאסוף ממך נתונים פרטיים."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"שנה את הגדרות המערכת הכלליות"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"הגדר תאריך"</string>
<string name="date_time_set" msgid="5777075614321087758">"הגדר"</string>
<string name="default_permission_group" msgid="2690160991405646128">"ברירת מחדל"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"לא דרושים אישורים"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"הסתר"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"הצג הכל"</b></string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 66e847ae034b..4e4a1aae7a87 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"アプリのコンポーネントの有効/無効化"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"別のアプリのコンポーネントの有効/無効を変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、タブレットの重要な機能が無効にされる恐れがあります。アプリのコンポーネントが利用できなくなったり、整合性が取れなくなったり、不安定な状態になったりする恐れがあるので許可には注意が必要です。"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"別のアプリのコンポーネントの有効/無効を変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、携帯端末の重要な機能が無効にされる恐れがあります。アプリのコンポーネントが利用できなくなったり、整合性が取れなくなったり、不安定な状態になったりする恐れがあるので許可には注意が必要です。"</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"優先アプリの設定"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"優先アプリを変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、実行中のアプリが密かに変更され、既存のアプリへのなりすましにより非公開データがだまし取られる恐れがあります。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"システムの全般設定の変更"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"日付設定"</string>
<string name="date_time_set" msgid="5777075614321087758">"設定"</string>
<string name="default_permission_group" msgid="2690160991405646128">"端末既定"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"権限の許可は必要ありません"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"隠す"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"すべて表示"</b></string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 754f79187ff2..f3cc2fe3685a 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"앱이 다른 앱 구성요소 사용 여부를 변경할 수 있도록 허용합니다. 이 경우 악성 앱이 이 기능을 이용하여 중요한 태블릿 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 앱 구성요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"앱이 다른 앱 구성요소 사용 여부를 변경할 수 있도록 허용합니다. 이 경우 악성 앱이 이 기능을 이용하여 중요한 휴대전화 기능을 중지시킬 수 있습니다. 이 권한을 허용할 경우 앱 구성요소가 사용 불가능하게 되거나 일관성이 맞지 않거나 불안정해질 수 있으므로 주의해야 합니다."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"기본 앱 설정"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"앱이 기본 앱을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 실행되는 앱을 몰래 변경하고 기존 앱으로 위장하여 사용자의 개인 정보를 수집할 수 있습니다."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"전체 시스템 설정 수정"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"날짜 설정"</string>
<string name="date_time_set" msgid="5777075614321087758">"설정"</string>
<string name="default_permission_group" msgid="2690160991405646128">"기본값"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"권한 필요 없음"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"숨기기"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"모두 표시"</b></string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 43aa1d3359be..c99d9bae2340 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Leidžiama programai pakeisti, ar įgalintas kitos programos komponentas, ar ne. Kenkėjiškos programos gali tai naudoti, kad neleistų svarbių planšetinio kompiuterio funkcijų. Šį leidimą reikia naudoti atsargiai, nes programos komponentai gali tapti nenaudojami, nenuoseklūs ar nestabilūs."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Leidžiama programai pakeisti nustatymą, ar įgalintas kitos programos komponentas, ar ne. Kenkėjiškos programos gali tai naudoti, kad neleistų svarbių telefono funkcijų. Šį leidimą reikia naudoti atsargiai, nes programos komponentai gali tapti nenaudojami, nenuoseklūs ar nestabilūs."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nustatyti pageidaujamas programas"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Leidžiama programai keisti jūsų pageidaujamas programas. Kenkėjiškos programos gali nepastebimai pakeisti vykdomas programas, klastodama esamas programas, kad rinktų jūsų privačius duomenis."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"keisti visuotinius sistemos nustatymus"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nustatyti datą"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Numatytasis"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nereikia leidimų"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Slėpti"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Rodyti viską"</b></string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 5f84a4885253..d2233e34fe30 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ļauj lietotnei mainīt to, vai tiek iespējots citas lietotnes komponents. Ļaunprātīgas lietotnes to var izmantot, lai atspējotu svarīgas planšetdatora iespējas. Izmantojiet šo atļauju uzmanīgi, jo pastāv iespēja, ka lietotnes komponenti var kļūt neizmantojami, neatbilstīgi vai nestabili."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ļauj lietotnei mainīt to, vai tiek iespējots citas lietotnes komponents. Ļaunprātīgas lietotnes to var izmantot, lai atspējotu svarīgas tālruņa iespējas. Izmantojiet šo atļauju uzmanīgi, jo pastāv iespēja, ka lietotnes komponenti var kļūt neizmantojami, neatbilstīgi vai nestabili."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"iestatīt vēlamās lietotnes"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ļauj lietotnei modificēt jūsu vēlamās lietotnes. Ļaunprātīgas lietotnes var nemanāmi mainīt izmantotās lietotnes, atveidojot esošās lietotnes, lai no jums iegūtu privātus datus."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"pārveidot globālos sistēmas iestatījumus"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datuma iestatīšana"</string>
<string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Noklusējums"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Atļaujas nav nepieciešamas."</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Slēpt"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Rādīt visu"</b></string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 3f240ab24307..d3c48854fc4b 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen apl"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Membenarkan apl untuk menukar sama ada komponen apl lain didayakan atau tidak. Apl hasad boleh menggunakannya untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana hal ini boleh menjadikan komponen apl berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Membenarkan apl untuk menukar sama ada komponen apl lain didayakan atau tidak. Apl hasad boleh menggunakannya untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana hal ini boleh menjadikan komponen apl berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tetapkan keutamaan apl"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Membenarkan apl untuk mengubah suai apl pilihan anda. Apl hasad secara diam-diam boleh menukar apl yang dijalankan, menipu apl anda yang sedia ada untuk mengumpul data peribadi daripada anda."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"mengubah suai tetapan sistem global"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Tetapkan tarikh"</string>
<string name="date_time_set" msgid="5777075614321087758">"Tetapkan"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Lalai"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Tiada kebenaran diperlukan"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Sembunyikan"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tunjukkan semua"</b></string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 63df5f466a79..bef0b20705ab 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige telefonfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angi foretrukne apper"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lar appen endre de foretrukne appene dine. Ondsinnede apper kan ubemerket endre apper som kjøres, og forfalske eksisterende apper til å samle private data fra deg."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"endre globale systeminnstillinger"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Angi dato"</string>
<string name="date_time_set" msgid="5777075614321087758">"Lagre"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Trenger ingen rettigheter"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skjul"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8e5e8bc54e59..3941a3dce190 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"componenten van apps in- of uitschakelen"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Hiermee kan de app wijzigen of een component van een andere app wel of niet is ingeschakeld. Schadelijke apps kunnen dit gebruiken om belangrijke tabletfuncties uit te schakelen. U moet voorzichtig omgaan met deze rechten, aangezien het mogelijk is dat onderdelen van apps onbruikbaar, inconsistent of instabiel worden."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Hiermee kan de app wijzigen of een component van een andere app wel of niet is ingeschakeld. Schadelijke apps kunnen dit gebruiken om belangrijke telefoonfuncties uit te schakelen. U moet voorzichtig omgaan met deze rechten, aangezien het mogelijk is dat onderdelen van apps onbruikbaar, inconsistent of instabiel worden."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"voorkeursapps instellen"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Hiermee kan de app uw voorkeursapps aanpassen. Schadelijke apps kunnen de apps die worden uitgevoerd zonder uw medeweten wijzigen om uw bestaande apps te imiteren en privégegevens van u te verzamelen."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"algemene systeeminstellingen wijzigen"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
<string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standaard"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Geen machtigingen vereist"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Verbergen"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Alles weergeven"</b></string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index c17da8ff4714..705cfccd426e 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Pozwala aplikacji na włączenie lub wyłączenie składnika innej aplikacji. Złośliwe aplikacje mogą wykorzystać to uprawnienie do wyłączenia ważnych funkcji tabletu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ istnieje możliwość wprowadzenia składników aplikacji w stan nieużywalności, niespójności lub niestabilności."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Pozwala aplikacji na włączenie lub wyłączenie składnika innej aplikacji. Złośliwe aplikacje mogą wykorzystać to uprawnienie do wyłączenia ważnych funkcji telefonu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ istnieje możliwość wprowadzenia składników aplikacji w stan nieużywalności, niespójności lub niestabilności."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ustawianie preferowanych aplikacji"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Pozwala aplikacji na zmianę Twoich preferowanych aplikacji. Złośliwe aplikacje mogą dyskretnie zmienić uruchamiane aplikacje, podszywając się pod dotychczasowe aplikacje w celu zebrania od Ciebie prywatnych danych."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modyfikowanie ogólnych ustawień systemu"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ustaw datę"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Domyślne"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nie są wymagane żadne uprawnienia"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ukryj"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaż wszystko"</b></string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 74870ffa98d1..4865537f9fc6 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar componentes da aplicação"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que a aplicação mude a opção de ativar ou não um componente de outra aplicação. As aplicações maliciosas podem utilizar isto para desativar funcionalidades importantes do tablet. É necessário ter cuidado com esta autorização, uma vez que é possível colocar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que a aplicação mude a opção de ativar ou não um componente de outra aplicação. As aplicações maliciosas podem utilizar isto para desativar funcionalidades importantes do telemóvel. É necessário ter cuidado com esta autorização, uma vez que é possível colocar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"definir aplicações preferidas"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite ao aplicativo modificar as suas aplicações preferidas. As aplicações maliciosas podem alterar sem aviso as aplicações que são executadas, espiando as aplicações existentes para recolher os seus dados privados."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar definições globais do sistema"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predefinido"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Não são necessárias permissões"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar tudo"</b></string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index efe6833ff715..374102c5e35f 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que o aplicativo ative ou desative um componente de outro aplicativo. Aplicativos maliciosos podem usar esse recurso para desativar recursos importantes do tablet. Tenha cuidado com essa permissão, pois é possível fazer com que os componentes do aplicativo fiquem inutilizáveis, inconsistentes ou instáveis."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que o aplicativo altere se um componente de outro aplicativo está ativado ou não. Aplicativos maliciosos podem usar esse recurso para desativar recursos importantes do telefone. Deve-se tomar cuidado com essa permissão, uma vez que isso pode deixar os componentes do aplicativo inutilizáveis, inconsistentes ou instáveis."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"definir aplicativos preferidos"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que o aplicativo modifique seus aplicativos preferidos. Aplicativos maliciosos podem alterar os aplicativos que são executados, falsificando seus aplicativos existentes para coletar seus dados particulares."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificar configurações globais do sistema"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Padrão"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todas"</b></string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 5b8efa61ed6c..c7579de10e5a 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -451,6 +451,10 @@
<skip />
<!-- no translation found for permdesc_changeComponentState (1827232484416505615) -->
<skip />
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<!-- no translation found for permlab_setPreferredApplications (8463181628695396391) -->
<skip />
<!-- no translation found for permdesc_setPreferredApplications (4973986762241783712) -->
@@ -1474,6 +1478,8 @@
<skip />
<string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Naginas permissiuns obligatoricas"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Zuppentar"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Mussar tut"</b></string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8ffa16e9f5f7..0890cc09c6f8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"activare sau dezactivare a componentelor aplicaţiei"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite aplicaţiei să modifice starea activată sau dezactivată a unei componente a altei aplicaţii. Aplicaţiile rău intenţionate pot să utilizeze această permisiune pentru a dezactiva funcţii importante ale tabletei. Este necesar să utilizaţi cu atenţie această permisiune, deoarece este posibil să aduceţi componentele aplicaţiei într-o stare inutilizabilă, inconsecventă sau instabilă."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite aplicaţiei să modifice starea activată sau dezactivată a unei componente a altei aplicaţii. Aplicaţiile rău intenţionate pot să utilizeze această permisiune pentru a dezactiva funcţii importante ale telefonului. Este necesar să utilizaţi cu atenţie această permisiune, deoarece este posibil să aduceţi componentele aplicaţiei într-o stare inutilizabilă, inconsecventă sau instabilă."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"setare aplicaţii preferate"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite aplicaţiei să modifice aplicaţiile dvs. preferate. Aplicaţiile rău intenţionate pot să modifice fără a vă înştiinţa aplicaţiile care rulează, păcălind aplicaţiile existente să colecteze date private de la dvs."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"modificare setări sistem globale"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setaţi data"</string>
<string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Prestabilit"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nu se solicită nicio permisiune"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ascundeţi"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Afişaţi-le pe toate"</b></string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index a6644e5094f4..5dfa64899e04 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"включение и отключение компонентов приложения"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Приложение сможет включать и отключать компоненты других программ. Вредоносные программы смогут таким образом отключать важные функции планшетного ПК. Используйте это разрешение с особой осторожностью, чтобы случайно не нарушить работу компонентов приложения."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Приложение сможет включать и отключать компоненты других программ. Вредоносные программы смогут таким образом отключать важные функции телефона. Используйте это разрешение с особой осторожностью, чтобы случайно не нарушить работу компонентов приложения."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"настройка предпочтительных приложений"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Приложение сможет изменять предпочтительные приложения. Вредоносные программы смогут незаметно изменять запускаемые вами программы и собирать ваши личные данные от имени существующих приложений."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"изменять общие настройки системы"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Настройка даты"</string>
<string name="date_time_set" msgid="5777075614321087758">"Установить"</string>
<string name="default_permission_group" msgid="2690160991405646128">"По умолчанию"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Не требуется разрешений"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Скрыть"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Показать все"</b></string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index df25ac7a296a..b65f535ed898 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikácii zmeniť to, či je súčasť inej aplikácie povolená alebo zakázaná. Škodlivé aplikácie môžu pomocou tohto nastavenia zakázať dôležité funkcie tabletu. S týmto povolením musíte zaobchádzať opatrne, pretože súčasti aplikácie môžete dostať do nepoužiteľného, nekonzistentného alebo nestabilného stavu."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikácii zmeniť to, či je súčasť inej aplikácie povolená alebo zakázaná. Škodlivé aplikácie môžu pomocou tohto nastavenia zakázať dôležité funkcie telefónu. S týmto povolením musíte zaobchádzať opatrne, pretože súčasti aplikácie môžete dostať do nepoužiteľného, nekonzistentného alebo nestabilného stavu."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastaviť preferované aplikácie"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikácii zmeniť vaše preferované aplikácie. Škodlivé aplikácie môžu v tichosti zmeniť spustené aplikácie a oklamať existujúce aplikácie, aby zhromažďovali vaše súkromné údaje."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"zmeny globálnych nastavení systému"</string>
@@ -1006,6 +1010,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastaviť dátum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Predvolené"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skryť"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Zobraziť všetky"</b></string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 81e1e6f24082..83515ddff351 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Programu omogoča, da spremeni, ali je komponenta drugega programa omogočena ali ne. Zlonamerni programi lahko to uporabijo za onemogočanje pomembnih zmožnosti tabličnega računalnika. Pri dodeljevanju dovoljenja je treba biti previden, saj lahko komponente programa nastavite tako, da jih ni mogoče uporabiti, da niso dosledne ali da niso stabilne."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Programu omogoča, da spremeni, ali je komponenta drugega programa omogočena ali ne. Zlonamerni programi lahko to uporabijo za onemogočanje pomembnih zmožnosti telefona. Pri dodeljevanju dovoljenja je treba biti previden, saj lahko komponente programa nastavite tako, da jih ni mogoče uporabiti, da niso dosledne ali da niso stabilne."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavitev prednostnih programov"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Programu omogoča spreminjanje priljubljenih programov. Zlonamerni programi lahko s tem neopazno spremenijo programe, ki se izvajajo, tako da se izdajajo za obstoječe programe in zbirajo osebne podatke."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"spreminjanje splošnih nastavitev sistema"</string>
@@ -765,7 +769,7 @@
<string name="permlab_serialPort" msgid="546083327654631076">"dostop do serijskih vrat"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Imetniku omogoča, da z API-jem za SerialManager dostopa do serijskih vrat."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"zunanji dostop do ponudnikov vsebine"</string>
- <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Omogoča imetniku, da dostopa do ponudnikov vsebine iz lupine. Naj ne bi bilo nikoli potrebno za običajne programe"</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Omogoča imetniku, da dostopa do ponudnikov vsebine iz lupine. Nikoli naj ne bi bilo potrebno za običajne programe"</string>
<string name="save_password_message" msgid="767344687139195790">"Ali želite, da si brskalnik zapomni to geslo?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ne zdaj"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapomni si"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavi datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Privzeto"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Ni zahtevanih dovoljenj"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Skrij"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaži vse"</b></string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 199d318c0821..2992fbe2a526 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дозвољава апликацији да промени да ли је компонента друге апликације омогућена или онемогућена. Злонамерне апликације могу то да искористе да онемогуће важне функције таблета. Треба бити опрезан при додељивању ове дозволе, јер компоненте апликација могу постати неупотребљиве, непоуздане или нестабилне."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дозвољава апликацији да промени да ли је компонента друге апликације омогућена или онемогућена. Злонамерне апликације могу то да искористе да онемогуће важне функције телефона. Треба бити опрезан при додељивању ове дозволе, јер компоненте апликација могу да постану неупотребљиве, непоуздане или нестабилне."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"подешавање жељених апликација"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дозвољава апликацији да мења омиљене апликације. Злонамерне апликације могу без обавештења да промене апликације које су покренуте и да преко њих прикупљају ваше приватне податке."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"измена глобалних подешавања система"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Подешавање датума"</string>
<string name="date_time_set" msgid="5777075614321087758">"Подеси"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Подразумевано"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Није потребна ниједна дозвола"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Сакриј"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Прикажи све"</b></string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index be397b0ebe7d..f780ca455c3f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivera eller inaktivera appkomponenter"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Tillåter att appen ändrar inställningen för om en komponent i en annan app ska aktiveras eller inte. Skadliga appar kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom appkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Tillåter att appen ändrar inställningen för om en komponent i en annan app ska aktiveras eller inte. Skadliga appar kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ange önskade appar"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Tillåter att appen ändrar dina önskade appar. Skadliga appar kan utan förvarning ändra de appar som körs och kapa dina befintliga appar så att de börjar samla privata uppgifter från dig."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"ändra globala systeminställningar"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Ange datum"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ställ in"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Standardinställning"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Inga behörigheter krävs"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Dölj"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Visa alla"</b></string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 9005a9b50e05..c9e469214145 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"wezesha au lemeza vijenzi vya programu"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Inaruhusu programu kubadilisha kama kijenzi cha programu nyingine kimewezeshwa au la. Programu hasidi zinaweza kutumia hii kulemeza uwezo muhimu wa kompyuta kibao. Lazina uangalifu utumike kwa ruhusa hii, kwani kuna uwezekano kupata vijenzi vya programu katika hali isiyotumika, isiyowiana, au hali isiyo thabiti."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Inaruhusu programu kubadilisha kama kijenzi cha programu nyingine kimewezeshwa au la. Programu hasidi zinaweza kutumia hii kulemeza mambo muhimu ambayo simu inaweza kufanya. Lazima uangalifu utumike kwa ruhusa hii, kwani kuna uwezekano kufanya vijenzi vya programu kuwa katika hali ya kutotumika, kutokuwa na uwiano, au kutokuwa thabiti."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"kuweka programu zinazopendelewa"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Inaruhusu programu kurekebisha programu unazopendelea. Programu hasidi zinaweza, polepole, kubadilisha programu zinazoendeshwa, na kuzifanya programu ulizo nazo kukusanya data ya kibinafsi kutoka kwako."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"rekebisha mipangilio ya mfumo jumla"</string>
@@ -337,9 +341,9 @@
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Inaruhusu programu kusoma maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya kuwasiliana. Hii ina maanisha programu inaweza kukutambua na kutuma taarifa yako fupi ya kibinafsi kwa wengine."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"andika kwenye data ya maelezo yako mafupi"</string>
<string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Inaruhusu programu kubadilisha au kuongeza taarifa fupi ya kibinafsi iliyohifadhiwa katika kifaa chako, kama vile jina lako na maelezo ya kuwasiliana. Hii ina maanisha kwamba programu zingine zinaweza kukutambua na kutuma taarifa yako fupi kwa wengine."</string>
- <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mkondo wako wa kijamii"</string>
+ <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mipasho yako wa kijamii"</string>
<string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Inaruhusu programu kufikia na kulandanisha sasisho za kijamii kutoka kwako na marafiki zako. Programu hasidi zinaweza kutumia hii kusoma mawasiliano ya kibinafsi kati yako na marafiki zako kwenye mitandao ya kijamii."</string>
- <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mkondo wako wa kijamii"</string>
+ <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mipasho yako wa kijamii"</string>
<string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Inaruhusu programu kuonyesha sasisho za kijamii kutoka kwa marafiki zako. Programu hasidi zinaweza kutumia hii kujifanya kuwa rafiki na kukuhadaa kuonyesha nenosiri au taarifa zingine za siri."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwa kompyuta yako kibao pamoja na za marafiki au wafanyakazi wenzako. Programu hasidi zinaweza kutoa maelezo ya kibinafsi kutoka kwa kalenda hizi bila wamiliki kujua."</string>
@@ -639,7 +643,7 @@
<string name="relationTypeParent" msgid="4755635567562925226">"Mzazi"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"Mshirika"</string>
<string name="relationTypeReferredBy" msgid="101573059844135524">"Alipendekezwa na"</string>
- <string name="relationTypeRelative" msgid="1799819930085610271">"Ndugu"</string>
+ <string name="relationTypeRelative" msgid="1799819930085610271">"Jamaa"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Dada"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"Mwenzi wa Ndoa"</string>
<string name="sipAddressTypeCustom" msgid="2473580593111590945">"Maalum"</string>
@@ -765,7 +769,7 @@
<string name="permlab_serialPort" msgid="546083327654631076">"kituo tambulishi cha ufikivu"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Inaruhusu mmiliki kufikia vituo tambulishi kwa kutumia KisimamiziTambulishi cha API."</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"fikia watoa huduma nje"</string>
- <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Inaruhusu mmiliki kufikia watoa huduma kutoka kwa onyesho. Haifai kuhitajika kwa programu za kawaida."</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Inaruhusu mmiliki kufikia watoa huduma kutoka kwa onyesho. Haifai kuhitajika kamwe kwa programu za kawaida."</string>
<string name="save_password_message" msgid="767344687139195790">"Unataka kuvinjari ili ukumbuke nenosiri hili?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Si Sasa"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Kumbuka"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Weka tarehe"</string>
<string name="date_time_set" msgid="5777075614321087758">"Weka"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Chaguo-msingi"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Hakuna vibali vinavyohitajika"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ficha"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Onyesha zote"</b></string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 41c56f473111..329a80788f13 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงการเปิดใช้งานส่วนประกอบของแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ปิดใช้งานความสามารถของแท็บเล็ตที่สำคัญ ต้องใช้ความระมัดระวังสำหรับการอนุญาตนี้ เนื่องจากอาจทำให้ส่วนประกอบต่างๆ ของแอปพลิเคชันไม่สามารถใช้งาน ไม่สอดคล้อง หรือมีสถานะที่ไม่เสถียร"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงการเปิดใช้งานส่วนประกอบของแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจใช้การอนุญาตนี้ปิดใช้งานความสามารถที่สำคัญของโทรศัพท์ ต้องใช้ความระมัดระวังสำหรับการอนุญาตนี้เนื่องจากอาจทำให้ส่วนประกอบต่างๆ ของแอปพลิเคชันไม่สามารถใช้งาน ไม่สอดคล้อง หรือมีสถานะที่ไม่เสถียร"</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ตั้งค่าแอปพลิเคชันที่ต้องการ"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"อนุญาตให้แอปพลิเคชันแก้ไขแอปพลิเคชันต่างๆ ที่คุณชอบใช้ แอปพลิเคชันที่เป็นอันตรายอาจจะแอบเปลี่ยนแอปพลิเคชันที่กำลังทำงาน ปลอมแปลงเป็นแอปพลิเคชันที่มีอยู่ของคุณเพื่อรวบรวมข้อมูลส่วนบุคคลจากคุณ"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"แก้ไขการตั้งค่าระบบสากล"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"ตั้งวันที่"</string>
<string name="date_time_set" msgid="5777075614321087758">"ตั้งค่า"</string>
<string name="default_permission_group" msgid="2690160991405646128">"เริ่มต้น"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"ไม่ต้องการการอนุญาต"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"ซ่อน"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"แสดงทั้งหมด"</b></string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 9548fe90584b..40e8cc527f97 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Pinapayagan ang app na baguhin kung ang bahagi ng isa pang app ay pinagana o hindi. Maaari itong gamitin ng nakakahamak na apps upang huwag paganahin ang mahahalagang kakayahan ng tablet. Dapat na mayroong pag-iingat sa pahintulot na ito, dahil posibleng mailagay ng mga bahagi ng app sa isang hindi nagagamit, pabagu-bago, o hindi matatag na katayuan."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Pinapayagan ang app na baguhin kung ang isang bahagi ng isa pang app ay pinapagana o hindi. Maaari itong gamitin ng nakakahamak na apps upang huwag paganahin ang mga mahalagang kakayahan ng telepono. Dapat na mayroong pag-iingat sa pahintulot na ito, dahil posibleng mailagay ang mga bahagi ng app sa isang hindi nagagamit, pabagu-bago, o hindi matatag na katayuan."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"itakda ang gustong apps"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Pinapayagan ang app na baguhin ang iyong gustong apps. Maaaring tahimik na baguhin ng nakakahamak na apps ang apps na tumatakbo, na dinadaya ang iyong umiiral nang apps upang mangolekta ng pribadong data mula sa iyo."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"baguhin ang mga setting ng global system"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string>
<string name="date_time_set" msgid="5777075614321087758">"Itakda"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Walang mga kinakailangang pahintulot"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Itago"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Ipakita lahat"</b></string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6da7fcdeea2f..730c69fdd00a 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Uygulamaya, başka bir uygulamanın bir bileşeninin etkin veya devre dışı olma durumunu değiştirme izni verir. Kötü amaçlı uygulamalar tabletin önemli özelliklerini devre dışı bırakmak için bunu kullanabilir. Uygulama bileşenlerini kullanılamaz, tutarsız ya da kararsız hale getirebileceğinden bu izin ayarlanırken dikkat edilmelidir."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Uygulamaya, başka bir uygulamanın bir bileşeninin etkin veya devre dışı olma durumunu değiştirme izni verir. Kötü amaçlı uygulamalar telefonun önemli özelliklerini devre dışı bırakmak için bunu kullanabilir. Uygulama bileşenlerini kullanılamaz, tutarsız ya da kararsız getirebileceğinden bu izin ayarlanırken dikkat edilmelidir."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tercih edilen uygulamaları ayarla"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Uygulamaya, tercih edilen uygulamalarınızı değiştirme izni verir. Kötü amaçlı uygulamalar çalışmakta olan uygulamaları sessizce değiştirip gizli verilerinizi toplamak için mevcut uygulamalarınızı yanlış yönlendirebilir."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"genel sistem ayarlarını değiştir"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarla"</string>
<string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Varsayılan"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"İzin gerektirmez"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Gizle"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Tümünü göster"</b></string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3fd626476ae0..fd0beafea2ce 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дозволяє програмі змінювати статус ввімкнення чи вимкнення компонента іншої програми. Шкідливі програми можуть використовувати це для вимкнення важливих характеристик планшетного ПК. З цим типом дозволу треба поводитися обережно, оскільки компоненти програми можуть стати непридатними, невідповідними чи нестабільними."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дозволяє програмі змінювати статус ввімкнення чи вимкнення компонента іншої програми. Шкідливі програми можуть використовувати це для вимкнення важливих характеристик телефону. З цим типом дозволу треба поводитися обережно, оскільки компоненти програми можуть стати непридатними, невідповідними чи нестабільними."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"установлювати потрібні програми"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дозволяє програмі змінювати ваші вибрані програми. Шкідливі програми можуть непомітно змінювати запущені програми, примушуючи існуючі програми оманливим шляхом збирати ваші особисті дані."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"змін. загальні налашт-ня сист."</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Установити дату"</string>
<string name="date_time_set" msgid="5777075614321087758">"Застосувати"</string>
<string name="default_permission_group" msgid="2690160991405646128">"За умовч."</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Дозвіл не потрібний"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Сховати"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Показ. всі"</b></string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 8503dc56c8fe..37af091ce71f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Cho phép ứng dụng thay đổi việc có bật cấu phần của ứng dụng khác hay không. Ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa những tính năng quan trọng của máy tính bảng. Phải cẩn trọng khi sử dụng quyền này vì quyền này có thể khiến các cấu phần rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Cho phép ứng dụng thay đổi việc có bật cấu phần của một ứng dụng khác hay không. Ứng dụng độc hại có thể sử dụng quyền này để tắt những tính năng quan trọng của điện thoại. Phải sử dụng quyền này thận trọng vì có thể khiến các cấu phần của ứng dụng rơi vào trạng thái không thể sử dụng được, không đồng nhất hoặc không ổn định."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"đặt ứng dụng ưa thích"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Cho phép ứng dụng sửa đổi ứng dụng ưa thích của bạn. Ứng dụng độc hại có thể ngầm thay đổi các ứng dụng đã được chạy, giả mạo các ứng dụng hiện có để thu thập dữ liệu cá nhân của bạn."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"sửa đổi cài đặt hệ thống chung"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Đặt ngày"</string>
<string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Mặc định"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Ẩn"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Hiển thị tất cả"</b></string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index bc74518610bf..6882d7afc954 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用程序组件"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"允许应用程序启用或停用其他应用程序的组件。恶意应用程序可能借此停用重要的平板电脑功能。请务必谨慎使用此权限,因为这可能导致某些应用程序组件处于无法使用、不一致或不稳定的状态。"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"允许应用程序启用或停用其他应用程序的组件。恶意应用程序可能借此停用重要的手机功能。请务必谨慎使用此权限,因为这可能导致某些应用程序组件进入无法使用、不一致或不稳定的状态。"</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"设置首选应用程序"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允许应用程序修改您的首选应用程序。恶意应用程序可能会在后台更改运行的应用程序,欺骗您现有的应用程序,以收集您的私人数据。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"修改全局系统设置"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"设置日期"</string>
<string name="date_time_set" msgid="5777075614321087758">"设置"</string>
<string name="default_permission_group" msgid="2690160991405646128">"默认"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"不需要任何权限"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"隐藏"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"全部显示"</b></string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5c89004cb660..18d0836bfb15 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"允許應用程式啟用或停用其他應用程式的元件。請注意,惡意應用程式可能利用此功能停用重要的平板電腦功能。這項權限可能導致應用程式元件無法使用、不一致或不穩定,請務必謹慎使用。"</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"允許應用程式啟用或停用其他應用程式的元件。請注意,惡意應用程式可能利用此功能停用重要的手機功能。這項權限可能導致應用程式元件無法使用、不一致或不穩定,請務必謹慎使用。"</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"設定偏好的應用程式"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允許應用程式修改您偏好的應用程式。請注意,惡意應用程式可能利用此功能擅自竄改執行的應用程式,並冒充現有的程式收集您的私人資料。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"編輯全域系統設定"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"日期設定"</string>
<string name="date_time_set" msgid="5777075614321087758">"設定"</string>
<string name="default_permission_group" msgid="2690160991405646128">"預設值"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"無須許可"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>" 隱藏"</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"顯示全部"</b></string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index b3cb9a07ca05..096aba7b4c3e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -70,11 +70,11 @@
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Isevisi ayilungiselelwe."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"Ngeke ukwazi ukuguqul izilungiselelo zemininingwane yoshayayo."</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Ukufinyelela okuvinjelwe kushintshiwe"</string>
- <string name="RestrictedOnData" msgid="8653794784690065540">"Insizakalo yedatha ivaliwe."</string>
- <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Insizakalo ephuthumayo ivimbelwe."</string>
- <string name="RestrictedOnNormal" msgid="4953867011389750673">"Insizakalo yezwi ivimbelwe."</string>
+ <string name="RestrictedOnData" msgid="8653794784690065540">"Isevisi yedatha ivaliwe."</string>
+ <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Isevisi ephuthumayo ivimbelwe."</string>
+ <string name="RestrictedOnNormal" msgid="4953867011389750673">"Isevisi yezwi ivimbelwe."</string>
<string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Wonke amasevisi Wezwi avimbelwe."</string>
- <string name="RestrictedOnSms" msgid="8314352327461638897">"Insizakalo ye-SMS ivaliwe."</string>
+ <string name="RestrictedOnSms" msgid="8314352327461638897">"Isevisi ye-SMS ivaliwe."</string>
<string name="RestrictedOnVoiceData" msgid="996636487106171320">"Amasevisi Wezwi/Idatha avimbelwe."</string>
<string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Amasevisi Wezwi/SMS avimbelwe."</string>
<string name="RestrictedOnAll" msgid="5643028264466092821">"Wonke amasevisi Wezwi/Idatha/SMS avimbelwe."</string>
@@ -276,7 +276,7 @@
<string name="permdesc_bindVpnService" msgid="2067845564581693905">"Ivumela umnini ukuthi abophele kwissekelo esingaphezulu sesevisi ye-Vpm. Ayidingakeli izinsiza ezejwayelekile."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"hlanganisa kwiphephadonga"</string>
<string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lwephephadonga. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
- <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bophezela kube insizakalo yesinqunjana"</string>
+ <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bophezela kube isevisi yesinqunjana"</string>
<string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lensizakalo yesinqunjwana. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"xhumana nomphathi wedivaysi"</string>
<string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ivumela ummeli ukuthumela okuqukethwe kumphathi wedivaysi. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
@@ -313,6 +313,10 @@
<string name="permlab_changeComponentState" msgid="6335576775711095931">"vumela noma vimbela izingxenye zensiza"</string>
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ivumela ukuthi insiza iguqule ukuthi okuqukethwe kwenye insiza kuyasebenza noma cha. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ekhompyutheni yepeni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesimweni esingazinzile, nesiguquguqukayo."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ivumela ukuthi insiza iguqule ukuthi okuqukethwe kwenye insiza kuyasebenza noma cha. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ocingweni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesmweni esingazinzile, nesiguquguqukayo."</string>
+ <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+ <skip />
+ <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+ <skip />
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"setha izinsiza ezincamelwayo"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ivuela insiza ukuthi iguqule izinsiza ezincanyelwayo. Izinsiza ezinobungozi zingashintsha izinsiz buthule ezisebenzyo okwenza ukuthi izinsiza zakho ezikhona zingasebenzi ukuthola ze zithole imininingwane yakho eyimfihlo."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"guqula izilungiselelo zohlelo jikelele"</string>
@@ -764,7 +768,7 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Ivumela umnikazi ukuthi enze izicelo zezinsiza eziqinisekisa iphakheji. Akumele kudingeke ekusetshenzisweni okujwayelekile."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"finyelela kuma- serial port"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Ivumela umnikai ukuthi athole inombolo ye-serial ukue angene kwiindawo ze-serial esebenzisa i-SerialManager API."</string>
- <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"finyelela ngaphandle abahlinzeki bokuqukethwe"</string>
+ <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"finyelela abahlinzeki bokuqukethwe ngaphandle"</string>
<string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Ivumela umphathi ukufinyelela abahlinzeki bokuqukethwe kusuka kumasistimu asebenzayo. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
<string name="save_password_message" msgid="767344687139195790">"Ingabe ufuna ukuba isiphequluli sikhumbule lephasiwedi?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Hha yi manje"</string>
@@ -1004,6 +1008,8 @@
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Setha idethi"</string>
<string name="date_time_set" msgid="5777075614321087758">"Hlela"</string>
<string name="default_permission_group" msgid="2690160991405646128">"Okuzenzakalelayo"</string>
+ <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+ <skip />
<string name="no_permissions" msgid="7283357728219338112">"Ayikho imvume edingekayo"</string>
<string name="perms_hide" msgid="7283915391320676226"><b>"Fihla "</b></string>
<string name="perms_show_all" msgid="2671791163933091180"><b>"Bonisa konke"</b></string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c152b73386bc..93757303a9ae 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2999,7 +2999,10 @@
<attr name="textColorLink" />
<!-- Makes the cursor visible (the default) or invisible. -->
<attr name="cursorVisible" format="boolean" />
- <!-- Makes the TextView be at most this many lines tall. -->
+ <!-- Makes the TextView be at most this many lines tall.
+
+ When used on an editable text, the <code>inputType</code> attribute's value must be
+ combined with the <code>textMultiLine</code> flag for the maxLines attribute to apply. -->
<attr name="maxLines" format="integer" min="0" />
<!-- Makes the TextView be at most this many pixels tall. -->
<attr name="maxHeight" />
@@ -3009,7 +3012,10 @@
You could get the same effect by specifying this number in the
layout parameters. -->
<attr name="height" format="dimension" />
- <!-- Makes the TextView be at least this many lines tall. -->
+ <!-- Makes the TextView be at least this many lines tall.
+
+ When used on an editable text, the <code>inputType</code> attribute's value must be
+ combined with the <code>textMultiLine</code> flag for the minLines attribute to apply. -->
<attr name="minLines" format="integer" min="0" />
<!-- Makes the TextView be at least this many pixels tall. -->
<attr name="minHeight" />
@@ -3040,21 +3046,20 @@
<!-- Constrains the text to a single horizontally scrolling line
instead of letting it wrap onto multiple lines, and advances
focus instead of inserting a newline when you press the
- enter key. Note: for editable text views, it is better
- to control this using the textMultiLine flag in the inputType
- attribute. (If both singleLine and inputType are supplied,
- the inputType flags will override the value of singleLine.)
- {@deprecated This attribute is deprecated and is replaced by the textMultiLine flag
- in the inputType attribute. Use caution when altering existing layouts, as the
- default value of singeLine is false (multi-line mode), but if you specify any
- value for inputType, the default is single-line mode. (If both singleLine and
- inputType attributes are found, the inputType flags will override the value of
- singleLine.) } -->
+ enter key.
+
+ The default value is false (multi-line wrapped text mode) for non-editable text, but if
+ you specify any value for inputType, the default is true (single-line input field mode).
+
+ {@deprecated This attribute is deprecated. Use <code>maxLines</code> instead to change
+ the layout of a static text, and use the <code>textMultiLine</code> flag in the
+ inputType attribute instead for editable text views (if both singleLine and inputType
+ are supplied, the inputType flags will override the value of singleLine). } -->
<attr name="singleLine" format="boolean" />
<!-- Specifies whether the TextView is enabled or not. {@deprecated Use state_enabled instead}. -->
<attr name="enabled" format="boolean" />
<!-- If the text is selectable, select it all when the view takes
- focus instead of moving the cursor to the start or end. -->
+ focus. -->
<attr name="selectAllOnFocus" format="boolean" />
<!-- Leave enough room for ascenders and descenders instead of
using the font ascent and descent strictly. (Normally true). -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 92c59ab99391..4aa7dde1e162 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -157,7 +157,7 @@
of permission to a requesting application at installation, without
asking for the user's explicit approval (though the user always
has the option to review these permissions before installing). -->
- <enum name="normal" value="0" />
+ <flag name="normal" value="0" />
<!-- A higher-risk permission that would give a requesting application
access to private user data or control over the device that can
negatively impact the user. Because this type of permission
@@ -167,13 +167,13 @@
user and require confirmation before proceeding, or some other
approach may be taken to avoid the user automatically allowing
the use of such facilities. -->
- <enum name="dangerous" value="1" />
+ <flag name="dangerous" value="1" />
<!-- A permission that the system is to grant only if the requesting
application is signed with the same certificate as the application
that declared the permission. If the certificates match, the system
automatically grants the permission without notifying the user or
asking for the user's explicit approval. -->
- <enum name="signature" value="2" />
+ <flag name="signature" value="2" />
<!-- A permission that the system is to grant only to packages in the
Android system image <em>or</em> that are signed with the same
certificates. Please avoid using this option, as the
@@ -183,7 +183,20 @@
vendors have applications built in to a system image which need
to share specific features explicitly because they are being built
together. -->
- <enum name="signatureOrSystem" value="3" />
+ <flag name="signatureOrSystem" value="3" />
+ <!-- Additional flag from base permission type: this permission can also
+ be granted to any applications installed on the system image.
+ Please avoid using this option, as the
+ signature protection level should be sufficient for most needs and
+ works regardless of exactly where applications are installed. This
+ permission flag is used for certain special situations where multiple
+ vendors have applications built in to a system image which need
+ to share specific features explicitly because they are being built
+ together. -->
+ <flag name="system" value="0x10" />
+ <!-- Additional flag from base permission type: this permission can also
+ (optionally) be granted to development applications. -->
+ <flag name="development" value="0x20" />
</attr>
<!-- Specified the name of a group that this permission is associated
@@ -924,6 +937,13 @@
tag; often this is one of the {@link android.Manifest.permission standard
system permissions}. -->
<attr name="name" />
+ <!-- Specify whether this permission is required for the application.
+ The default is true, meaning the application requires the
+ permission, and it must always be granted when it is installed.
+ If you set this to false, then in some cases the application may
+ be installed with it being granted the permission, and it will
+ need to request the permission later if it needs it. -->
+ <attr name="required" format="boolean" />
</declare-styleable>
<!-- The <code>uses-configuration</code> tag specifies
@@ -966,7 +986,7 @@
don't support it. If you set this to false, then this will
not impose a restriction on where the application can be
installed. -->
- <attr name="required" format="boolean" />
+ <attr name="required" />
</declare-styleable>
<!-- The <code>uses-sdk</code> tag describes the SDK features that the
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2a6cef3f56b9..94a671d28d43 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -115,6 +115,7 @@
<java-symbol type="id" name="new_app_action" />
<java-symbol type="id" name="new_app_description" />
<java-symbol type="id" name="new_app_icon" />
+ <java-symbol type="id" name="new_perms_list" />
<java-symbol type="id" name="no_permissions" />
<java-symbol type="id" name="non_dangerous_perms_list" />
<java-symbol type="id" name="numberpicker_input" />
@@ -629,6 +630,7 @@
<java-symbol type="string" name="orgTypeWork" />
<java-symbol type="string" name="passwordIncorrect" />
<java-symbol type="string" name="permissions_format" />
+ <java-symbol type="string" name="perms_new_perm_prefix" />
<java-symbol type="string" name="perms_hide" />
<java-symbol type="string" name="perms_show_all" />
<java-symbol type="string" name="petabyteShort" />
@@ -962,6 +964,7 @@
<java-symbol type="drawable" name="tab_bottom_right_v4" />
<java-symbol type="drawable" name="tab_indicator_v4" />
<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="unknown_image" />
<java-symbol type="drawable" name="unlock_default" />
@@ -1541,6 +1544,21 @@
<java-symbol type="drawable" name="ic_volume" />
<java-symbol type="drawable" name="stat_notify_sim_toolkit" />
+ <!-- From maps library -->
+ <java-symbol type="array" name="maps_starting_lat_lng" />
+ <java-symbol type="array" name="maps_starting_zoom" />
+ <java-symbol type="attr" name="mapViewStyle" />
+ <java-symbol type="attr" name="state_focused" />
+ <java-symbol type="attr" name="state_selected" />
+ <java-symbol type="attr" name="state_pressed" />
+ <java-symbol type="drawable" name="compass_arrow" />
+ <java-symbol type="drawable" name="compass_base" />
+ <java-symbol type="drawable" name="ic_maps_indicator_current_position_anim" />
+ <java-symbol type="drawable" name="loading_tile_android" />
+ <java-symbol type="drawable" name="maps_google_logo" />
+ <java-symbol type="drawable" name="no_tile_256" />
+ <java-symbol type="drawable" name="reticle" />
+
<!-- From PinyinIME(!!!) -->
<java-symbol type="string" name="inputMethod" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3c1f50d11b6d..f548165cb7e7 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -861,6 +861,14 @@
possible to get app components into an unusable, inconsistent, or unstable state.
</string>
+ <!-- Title of an application permission for granting or revoking other permissions [CHAR LIMIT=NONE] -->
+ <string name="permlab_grantRevokePermissions">grant or revoke permissions</string>
+ <!-- Description of an application permission for granting or revoking other permissions [CHAR LIMIT=NONE] -->
+ <string name="permdesc_grantRevokePermissions">Allows an application to grant or revoke
+ specific permissions for it or other applications. Malicious applications may use this
+ to access features you have not granted them.
+ </string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_setPreferredApplications">set preferred apps</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -2775,6 +2783,8 @@
<string name="default_permission_group">Default</string>
<!-- Do not translate. -->
<string name="permissions_format"><xliff:g id="perm_line1">%1$s</xliff:g>, <xliff:g id="perm_line2">%2$s</xliff:g></string>
+ <!-- Text that is placed at the front of a permission name that is being added to an app [CHAR LIMIT=NONE] -->
+ <string name="perms_new_perm_prefix"><font size="12" fgcolor="#ffffa3a3">NEW: </font></string>
<!-- Shown for an application when it doesn't require any permission grants. -->
<string name="no_permissions">No permissions required</string>
<!-- When installing an application, the less-dangerous permissions are hidden. If the user showed those, this is the text to hide them again. -->
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
index 7499f68f87f6..8d778c46b5cf 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -44,6 +44,8 @@ import com.android.bandwidthtest.NetworkState;
import com.android.bandwidthtest.NetworkState.StateTransitionDirection;
import com.android.internal.util.AsyncChannel;
+import junit.framework.Assert;
+
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.List;
@@ -453,6 +455,11 @@ public class ConnectionUtil {
} catch (InterruptedException e) {
e.printStackTrace();
}
+ if (mNetworkInfo == null) {
+ Log.v(LOG_TAG, "Do not have networkInfo! Force fetch of network info.");
+ mNetworkInfo = mCM.getActiveNetworkInfo();
+ Assert.assertNotNull(mNetworkInfo);
+ }
if ((mNetworkInfo.getType() != networkType) ||
(mNetworkInfo.getState() != expectedState)) {
Log.v(LOG_TAG, "network state for " + mNetworkInfo.getType() +
diff --git a/docs/html/guide/developing/projects/projects-cmdline.jd b/docs/html/guide/developing/projects/projects-cmdline.jd
index 81c2c584e45e..b8db5f333a1a 100644
--- a/docs/html/guide/developing/projects/projects-cmdline.jd
+++ b/docs/html/guide/developing/projects/projects-cmdline.jd
@@ -218,7 +218,7 @@ android update lib-project \
<p>To add a reference to a library project, navigate to the <code>&lt;sdk&gt;/tools/</code>
directory and use this command:</p>
<pre>
-android update lib-project \
+android update project \
--target <em>&lt;target_ID&gt;</em> \
--path <em>path/to/your/project</em>
--library <em>path/to/library_projectA</em>
diff --git a/docs/html/guide/developing/projects/projects-eclipse.jd b/docs/html/guide/developing/projects/projects-eclipse.jd
index 40c17ed14d5c..90f7820631ae 100644
--- a/docs/html/guide/developing/projects/projects-eclipse.jd
+++ b/docs/html/guide/developing/projects/projects-eclipse.jd
@@ -201,7 +201,7 @@ parent.link=index.html
priority. The application itself has highest priority and its resources are always used in
preference to identical resource IDs defined in libraries.</p>
- <h3>Declaring library components in the the manifest file</h3>
+ <h3>Declaring library components in the manifest file</h3>
<p>In the manifest file of the application project, you must add declarations of all components
that the application will use that are imported from a library project. For example, you must
diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd
index d4f9342dd632..281cb9dc717f 100644
--- a/docs/html/guide/topics/fundamentals/fragments.jd
+++ b/docs/html/guide/topics/fundamentals/fragments.jd
@@ -659,7 +659,7 @@ href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guides.
<div class="figure" style="width:350px">
<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt=""/>
-<p class="img-caption"><strong>Figure 3.</strong> The activity lifecycle's affect on the fragment
+<p class="img-caption"><strong>Figure 3.</strong> The effect of the activity lifecycle on the fragment
lifecycle.</p>
</div>
diff --git a/docs/html/images/training/lint_icon.png b/docs/html/images/training/lint_icon.png
new file mode 100644
index 000000000000..118a7419c6bd
--- /dev/null
+++ b/docs/html/images/training/lint_icon.png
Binary files differ
diff --git a/docs/html/sdk/ndk/overview.jd b/docs/html/sdk/ndk/overview.jd
index 85599f76600d..e969f5d299ec 100644
--- a/docs/html/sdk/ndk/overview.jd
+++ b/docs/html/sdk/ndk/overview.jd
@@ -46,7 +46,7 @@ page.title=What is the NDK?
<li>Documentation, samples, and tutorials</li>
</ul>
- <p>The latest release of the NDK supports these ARM instruction sets:</p>
+ <p>The latest release of the NDK supports the following instruction sets:</p>
<ul>
<li>ARMv5TE (including Thumb-1 instructions)</li>
diff --git a/docs/html/training/improving-layouts/optimizing-layout.jd b/docs/html/training/improving-layouts/optimizing-layout.jd
index 65c8af798fd1..0eaf199b132e 100644
--- a/docs/html/training/improving-layouts/optimizing-layout.jd
+++ b/docs/html/training/improving-layouts/optimizing-layout.jd
@@ -18,7 +18,7 @@ next.link=reusing-layouts.html
<ol>
<li><a href="#Inspect">Inspect Your Layout</a></li>
<li><a href="#Revise">Revise Your Layout</a></li>
- <li><a href="#Layoutopt">Use Layoutopt</a></li>
+ <li><a href="#Lint">Use Lint</a></li>
</ol>
<!-- other docs (NOT javadocs) -->
@@ -44,7 +44,7 @@ is inflated repeatedly, such as when used in a {@link android.widget.ListView} o
android.widget.GridView}.</p>
<p>In this lesson you'll learn to use <a
-href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Heirachy Viewer</a> and <a
+href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a> and <a
href="{@docRoot}guide/developing/tools/layoutopt.html">Layoutopt</a> to examine and optimize your
layout.</p>
@@ -53,7 +53,7 @@ layout.</p>
<h2 id="Inspect">Inspect Your Layout</h2>
<p>The Android SDK tools include a tool called <a
-href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Heirachy Viewer</a> that allows
+href="{@docRoot}guide/developing/tools/hierarchy-viewer.html">Hierarchy Viewer</a> that allows
you to analyze your layout while your application is running. Using this tool helps you discover
bottlenecks in the layout performance.</p>
@@ -130,27 +130,28 @@ example of how each layout has appropriate uses and you should carefully conside
layout weight is necessary.</p>
-<h2 id="Layoutopt">Use Layoutopt</h2>
+<h2 id="Lint">Use Lint</h2>
+
+<p>It is always good practice to run the <a href="http://tools.android.com/tips/lint">Lint</a> tool on your layout files to search for possible view hierarchy optimizations. Lint has replaced the Layoutopt tool and has much greater functionality. Some examples of Lint <a
+href="http://tools.android.com/tips/lint-checks">rules</a> are:</p>
+
+<ul>
+<li>Use compound drawables - A {@link android.widget.LinearLayout} which contains an {@link android.widget.ImageView} and a {@link android.widget.TextView} can be more efficiently handled as a compound drawable.</li>
+<li>Merge root frame - If a {@link android.widget.FrameLayout} is the root of a layout and does not provide background or padding etc, it can be replaced with a merge tag which is slightly more efficient.</li>
+<li>Useless leaf - A layout that has no children or no background can often be removed (since it is invisible) for a flatter and more efficient layout hierarchy.</li>
+<li>Useless parent - A layout with children that has no siblings, is not a {@link android.widget.ScrollView} or a root layout, and does not have a background, can be removed and have its children moved directly into the parent for a flatter and more efficient layout hierarchy.</li>
+<li>Deep layouts - Layouts with too much nesting are bad for performance. Consider using flatter layouts such as {@link android.widget.RelativeLayout} or {@link android.widget.GridLayout} to improve performance. The default maximum depth is 10.</li>
+</ul>
+
+<p>Another benefit of Lint is that it is integrated into the Android Development Tools for Eclipse (ADT 16+). Lint automatically runs whenever you export an APK, edit and save an XML file or use the Layout Editor. To manually force Lint to run press the Lint button in the Eclipse toolbar.</p>
+
+<img src="{@docRoot}images/training/lint_icon.png" alt="" />
+
+<p>When used inside Eclipse, Lint has the ability to automatically fix some issues, provide suggestions for others and jump directly to the offending code for review. If you don’t use Eclipse for your development, Lint can also be run from the command line. More information about Lint is available at <a href="http://tools.android.com/tips/lint">tools.android.com</a>.</p>
+
+
-<p>It is always good practice to also run the <a
-href="{@docRoot}guide/developing/tools/layoutopt.html">layoutopt</a> tool on your final layout files
-to search for places in your view hierarchy that may be optimized. Layoutopt is also in your SDK
-{@code tools/} directory and takes a layout directory name or a space-separated list of layout files
-that you'd like to inspect.</p>
-<p>When you run {@code layoutopt} on a layout file, it prints a line number for each issue found, a
-description of the issue, and for some types of issues it also suggests a resolution. For
-example:</p>
-<pre class="no-pretty-print classic">
-$ layoutopt samples/
-samples/compound.xml
- 7:23 The root-level &lt;FrameLayout/&gt; can be replaced with &lt;merge/&gt;
- 11:21 This LinearLayout layout or its FrameLayout parent is useless
-samples/simple.xml
- 7:7 The root-level &lt;FrameLayout/&gt; can be replaced with &lt;merge/&gt;
-</pre>
-<p>After you apply the suggested layout optimizations, run Hierarchy Viewer again to inspect the
-performance changes.</p>
diff --git a/drm/java/android/drm/DrmErrorEvent.java b/drm/java/android/drm/DrmErrorEvent.java
index 2cb82e67e14b..c61819dacd99 100755
--- a/drm/java/android/drm/DrmErrorEvent.java
+++ b/drm/java/android/drm/DrmErrorEvent.java
@@ -24,6 +24,10 @@ import java.util.HashMap;
*
*/
public class DrmErrorEvent extends DrmEvent {
+
+ // Please add newly defined type constants to the end of the list,
+ // and modify checkTypeValidity() accordingly.
+
/**
* Something went wrong installing the rights.
*/
@@ -60,28 +64,46 @@ public class DrmErrorEvent extends DrmEvent {
*/
public static final int TYPE_ACQUIRE_DRM_INFO_FAILED = 2008;
+ // Add more type constants here...
+
+ // FIXME:
+ // We may want to add a user-defined type constant, such as
+ // TYPE_VENDOR_SPECIFIC_FAILED, to take care vendor specific use
+ // cases.
+
+
/**
* Creates a <code>DrmErrorEvent</code> object with the specified parameters.
*
* @param uniqueId Unique session identifier.
- * @param type Type of the event. Could be any of the event types defined above.
- * @param message Message description.
+ * @param type Type of the event. Must be any of the event types defined above.
+ * @param message Message description. It can be null.
*/
public DrmErrorEvent(int uniqueId, int type, String message) {
super(uniqueId, type, message);
+ checkTypeValidity(type);
}
/**
* Creates a <code>DrmErrorEvent</code> object with the specified parameters.
*
* @param uniqueId Unique session identifier.
- * @param type Type of the event. Could be any of the event types defined above.
+ * @param type Type of the event. Must be any of the event types defined above.
* @param message Message description.
* @param attributes Attributes for extensible information. Could be any
- * information provided by the plug-in.
+ * information provided by the plug-in. It can be null.
*/
public DrmErrorEvent(int uniqueId, int type, String message,
HashMap<String, Object> attributes) {
super(uniqueId, type, message, attributes);
+ checkTypeValidity(type);
+ }
+
+ private void checkTypeValidity(int type) {
+ if (type < TYPE_RIGHTS_NOT_INSTALLED ||
+ type > TYPE_ACQUIRE_DRM_INFO_FAILED) {
+ final String msg = "Unsupported type: " + type;
+ throw new IllegalArgumentException(msg);
+ }
}
}
diff --git a/drm/java/android/drm/DrmEvent.java b/drm/java/android/drm/DrmEvent.java
index 4053eb39e799..1a19f5c62b94 100755
--- a/drm/java/android/drm/DrmEvent.java
+++ b/drm/java/android/drm/DrmEvent.java
@@ -23,6 +23,10 @@ import java.util.HashMap;
*
*/
public class DrmEvent {
+
+ // Please do not add type constants in this class. More event type constants
+ // should go to DrmInfoEvent or DrmErrorEvent classes.
+
/**
* All of the rights information associated with all DRM schemes have been successfully removed.
*/
diff --git a/drm/java/android/drm/DrmInfoEvent.java b/drm/java/android/drm/DrmInfoEvent.java
index 67aa0a96b636..2826dcee4f67 100755
--- a/drm/java/android/drm/DrmInfoEvent.java
+++ b/drm/java/android/drm/DrmInfoEvent.java
@@ -24,6 +24,10 @@ import java.util.HashMap;
*
*/
public class DrmInfoEvent extends DrmEvent {
+
+ // Please add newly defined type constants to the end of the list,
+ // and modify checkTypeValidity() accordingly.
+
/**
* The registration has already been done by another account ID.
*/
@@ -50,29 +54,57 @@ public class DrmInfoEvent extends DrmEvent {
*/
public static final int TYPE_RIGHTS_REMOVED = 6;
+ // Add more type constants here...
+
+ // FIXME:
+ // We may want to add a user-defined type constant, such as
+ // TYPE_VENDOR_SPECIFIC, to take care vendor specific use
+ // cases.
+
/**
* Creates a <code>DrmInfoEvent</code> object with the specified parameters.
*
* @param uniqueId Unique session identifier.
- * @param type Type of the event. Could be any of the event types defined above.
- * @param message Message description.
+ * @param type Type of the event. Must be any of the event types defined above,
+ * or the constants defined in {@link DrmEvent}.
+ * @param message Message description. It can be null.
*/
public DrmInfoEvent(int uniqueId, int type, String message) {
super(uniqueId, type, message);
+ checkTypeValidity(type);
}
/**
* Creates a <code>DrmInfoEvent</code> object with the specified parameters.
*
* @param uniqueId Unique session identifier.
- * @param type Type of the event. Could be any of the event types defined above.
- * @param message Message description.
+ * @param type Type of the event. Must be any of the event types defined above,
+ * or the constants defined in {@link DrmEvent}
+ * @param message Message description. It can be null.
* @param attributes Attributes for extensible information. Could be any
* information provided by the plug-in.
*/
public DrmInfoEvent(int uniqueId, int type, String message,
HashMap<String, Object> attributes) {
super(uniqueId, type, message, attributes);
+ checkTypeValidity(type);
+ }
+
+ /*
+ * Check the validity of the given type.
+ * To overcome a design flaw, we need also accept the type constants
+ * defined in super class, DrmEvent.
+ */
+ private void checkTypeValidity(int type) {
+ if (type < TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT ||
+ type > TYPE_RIGHTS_REMOVED) {
+
+ if (type != TYPE_ALL_RIGHTS_REMOVED &&
+ type != TYPE_DRM_INFO_PROCESSED) {
+ final String msg = "Unsupported type: " + type;
+ throw new IllegalArgumentException(msg);
+ }
+ }
}
}
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 9a7194c4d637..14d5fae04c5a 100755
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -317,6 +317,7 @@ public class DrmManagerClient {
*
* @return A {@link android.content.ContentValues} instance that contains
* key-value pairs representing the constraints. Null in case of failure.
+ * The keys are defined in {@link DrmStore.ConstraintsColumns}.
*/
public ContentValues getConstraints(String path, int action) {
if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
diff --git a/drm/java/android/drm/DrmStore.java b/drm/java/android/drm/DrmStore.java
index ae311de73861..2f004cfdae26 100755
--- a/drm/java/android/drm/DrmStore.java
+++ b/drm/java/android/drm/DrmStore.java
@@ -23,45 +23,65 @@ package android.drm;
public class DrmStore {
/**
* Interface definition for the columns that represent DRM constraints.
+ * {@link android.drm.DrmManagerClient#getConstraints DrmManagerClient.getConstraints()}
+ * can be called by an application to find out the contraints on the
+ * {@link android.drm.DrmStore.Action actions} that can be performed
+ * on right-protected content. The constants defined in this interface
+ * represent three most common types of constraints: count-based,
+ * date-based, and duration-based. Two or more constraints can be used
+ * at the same time to represent more sophisticated constraints.
+ * In addition, user-defined constraint,
+ * {@link #EXTENDED_METADATA extended metadata}, can be
+ * used if these three types of constraints are not sufficient.
*/
public interface ConstraintsColumns {
/**
- * The maximum repeat count.
+ * This is a count-based constraint. It represents the maximum
+ * repeat count that can be performed on an
+ * {@link android.drm.DrmStore.Action action}.
* <p>
* Type: INTEGER
*/
public static final String MAX_REPEAT_COUNT = "max_repeat_count";
/**
- * The remaining repeat count.
+ * This is a count-based constraint. It represents the remaining
+ * repeat count that can be performed on an
+ * {@link android.drm.DrmStore.Action action}.
* <p>
* Type: INTEGER
*/
public static final String REMAINING_REPEAT_COUNT = "remaining_repeat_count";
/**
- * The time before which the rights-protected file cannot be played/viewed.
+ * This is a date-based constraint. It represents the time before which
+ * an {@link android.drm.DrmStore.Action action} can be performed on
+ * the rights-protected content.
* <p>
* Type: TEXT
*/
public static final String LICENSE_START_TIME = "license_start_time";
/**
- * The time after which the rights-protected file cannot be played/viewed.
+ * This is a date-based constaint. It represents the time after which
+ * an {@link android.drm.DrmStore.Action action} can not be performed on
+ * the rights-protected content.
* <p>
* Type: TEXT
*/
public static final String LICENSE_EXPIRY_TIME = "license_expiry_time";
/**
- * The available time left before the license expires.
+ * This is a duration-based constaint. It represents the available time left
+ * before the license expires.
* <p>
* Type: TEXT
*/
public static final String LICENSE_AVAILABLE_TIME = "license_available_time";
/**
- * The data stream for extended metadata.
+ * This is a user-defined constraint. It represents the additional constraint
+ * using extended metadata.
* <p>
* Type: TEXT
*/
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index 182f14d60e11..f7c202f8dca3 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -39,11 +39,15 @@ public class PixelFormat
public static final int RGB_888 = 3;
public static final int RGB_565 = 4;
+ @Deprecated
public static final int RGBA_5551 = 6;
+ @Deprecated
public static final int RGBA_4444 = 7;
public static final int A_8 = 8;
public static final int L_8 = 9;
+ @Deprecated
public static final int LA_88 = 0xA;
+ @Deprecated
public static final int RGB_332 = 0xB;
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 0ada1fbdcd8d..ec911b06be75 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -352,8 +352,7 @@ public final class Rect implements Parcelable {
// check for empty first
return this.left < this.right && this.top < this.bottom
// now check for containment
- && left <= r.left && top <= r.top
- && right >= r.right && bottom >= r.bottom;
+ && left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom;
}
/**
@@ -375,20 +374,11 @@ public final class Rect implements Parcelable {
* return false and do not change this rectangle.
*/
public boolean intersect(int left, int top, int right, int bottom) {
- if (this.left < right && left < this.right
- && this.top < bottom && top < this.bottom) {
- if (this.left < left) {
- this.left = left;
- }
- if (this.top < top) {
- this.top = top;
- }
- if (this.right > right) {
- this.right = right;
- }
- if (this.bottom > bottom) {
- this.bottom = bottom;
- }
+ if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) {
+ if (this.left < left) this.left = left;
+ if (this.top < top) this.top = top;
+ if (this.right > right) this.right = right;
+ if (this.bottom > bottom) this.bottom = bottom;
return true;
}
return false;
@@ -422,8 +412,7 @@ public final class Rect implements Parcelable {
* false and do not change this rectangle.
*/
public boolean setIntersect(Rect a, Rect b) {
- if (a.left < b.right && b.left < a.right
- && a.top < b.bottom && b.top < a.bottom) {
+ if (a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom) {
left = Math.max(a.left, b.left);
top = Math.max(a.top, b.top);
right = Math.min(a.right, b.right);
@@ -448,8 +437,7 @@ public final class Rect implements Parcelable {
* no event is this rectangle modified.
*/
public boolean intersects(int left, int top, int right, int bottom) {
- return this.left < right && left < this.right
- && this.top < bottom && top < this.bottom;
+ return this.left < right && left < this.right && this.top < bottom && top < this.bottom;
}
/**
@@ -463,8 +451,7 @@ public final class Rect implements Parcelable {
* either of the rectangles modified.
*/
public static boolean intersects(Rect a, Rect b) {
- return a.left < b.right && b.left < a.right
- && a.top < b.bottom && b.top < a.bottom;
+ return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom;
}
/**
@@ -480,14 +467,10 @@ public final class Rect implements Parcelable {
public void union(int left, int top, int right, int bottom) {
if ((left < right) && (top < bottom)) {
if ((this.left < this.right) && (this.top < this.bottom)) {
- if (this.left > left)
- this.left = left;
- if (this.top > top)
- this.top = top;
- if (this.right < right)
- this.right = right;
- if (this.bottom < bottom)
- this.bottom = bottom;
+ if (this.left > left) this.left = left;
+ if (this.top > top) this.top = top;
+ if (this.right < right) this.right = right;
+ if (this.bottom < bottom) this.bottom = bottom;
} else {
this.left = left;
this.top = top;
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 37a270e9c10d..6539ff374724 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -534,6 +534,7 @@ public class Allocation extends BaseObj {
* @param fp
*/
public void setFromFieldPacker(int xoff, FieldPacker fp) {
+ mRS.validate();
int eSize = mType.mElement.getSizeBytes();
final byte[] data = fp.getData();
@@ -554,6 +555,7 @@ public class Allocation extends BaseObj {
* @param fp
*/
public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
+ mRS.validate();
if (component_number >= mType.mElement.mElements.length) {
throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 95175135cf3a..6921f3780c41 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -17,6 +17,7 @@
package android.renderscript;
import java.lang.reflect.Field;
+import java.io.File;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -82,6 +83,25 @@ public class RenderScript {
native void nContextInitToClient(int con);
native void nContextDeinitToClient(int con);
+ /**
+ * Name of the file that holds the object cache.
+ */
+ private static final String CACHE_PATH = "com.android.renderscript.cache";
+ static String mCachePath;
+
+ /**
+ * Sets the directory to use as a persistent storage for the
+ * renderscript object file cache.
+ *
+ * @hide
+ * @param cacheDir A directory the current process can write to
+ */
+ public static void setupDiskCache(File cacheDir) {
+ File f = new File(cacheDir, CACHE_PATH);
+ mCachePath = f.getAbsolutePath();
+ f.mkdirs();
+ }
+
// Methods below are wrapped to protect the non-threadsafe
// lockless fifo.
@@ -884,7 +904,9 @@ public class RenderScript {
}
RenderScript(Context ctx) {
- mApplicationContext = ctx.getApplicationContext();
+ if (ctx != null) {
+ mApplicationContext = ctx.getApplicationContext();
+ }
}
/**
@@ -896,21 +918,16 @@ public class RenderScript {
return mApplicationContext;
}
- static int getTargetSdkVersion(Context ctx) {
- return ctx.getApplicationInfo().targetSdkVersion;
- }
-
/**
* Create a basic RenderScript context.
*
+ * @hide
* @param ctx The context.
* @return RenderScript
*/
- public static RenderScript create(Context ctx) {
+ public static RenderScript create(Context ctx, int sdkVersion) {
RenderScript rs = new RenderScript(ctx);
- int sdkVersion = getTargetSdkVersion(ctx);
-
rs.mDev = rs.nDeviceCreate();
rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion);
if (rs.mContext == 0) {
@@ -922,6 +939,17 @@ public class RenderScript {
}
/**
+ * Create a basic RenderScript context.
+ *
+ * @param ctx The context.
+ * @return RenderScript
+ */
+ public static RenderScript create(Context ctx) {
+ int v = ctx.getApplicationInfo().targetSdkVersion;
+ return create(ctx, v);
+ }
+
+ /**
* Print the currently available debugging information about the state of
* the RS context to the log.
*
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 2cfeb176c146..1b2ac90b3671 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -166,7 +166,7 @@ public class RenderScriptGL extends RenderScript {
super(ctx);
mSurfaceConfig = new SurfaceConfig(sc);
- int sdkVersion = getTargetSdkVersion(ctx);
+ int sdkVersion = ctx.getApplicationInfo().targetSdkVersion;
mWidth = 0;
mHeight = 0;
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 90f959f90a6d..108b230f1a5b 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -92,13 +92,9 @@ public class ScriptC extends Script {
throw new Resources.NotFoundException();
}
- // E.g, /system/apps/Fountain.apk
- //String packageName = rs.getApplicationContext().getPackageResourcePath();
- // For res/raw/fountain.bc, it wil be /com.android.fountain:raw/fountain
String resName = resources.getResourceEntryName(resourceID);
- String cacheDir = rs.getApplicationContext().getCacheDir().toString();
Log.v(TAG, "Create script for resource = " + resName);
- return rs.nScriptCCreate(resName, cacheDir, pgm, pgmLength);
+ return rs.nScriptCCreate(resName, rs.mCachePath, pgm, pgmLength);
}
}
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 27ea8f6ecc8a..9fc4fd4ba68f 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -23,8 +23,6 @@
#include <math.h>
#include <utils/misc.h>
-#include <surfaceflinger/Surface.h>
-
#include <core/SkBitmap.h>
#include <core/SkPixelRef.h>
#include <core/SkStream.h>
diff --git a/include/binder/CursorWindow.h b/include/androidfw/CursorWindow.h
index 8a2979a3756d..8a2979a3756d 100644
--- a/include/binder/CursorWindow.h
+++ b/include/androidfw/CursorWindow.h
diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h
index 400d7f404a57..3d188379fede 100644
--- a/include/camera/ICamera.h
+++ b/include/camera/ICamera.h
@@ -20,15 +20,15 @@
#include <utils/RefBase.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
-#include <surfaceflinger/Surface.h>
#include <binder/IMemory.h>
#include <utils/String8.h>
#include <camera/Camera.h>
-#include <gui/ISurfaceTexture.h>
namespace android {
class ICameraClient;
+class ISurfaceTexture;
+class Surface;
class ICamera: public IInterface
{
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index ae991601817a..8c21a28cff5e 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -19,9 +19,9 @@
#include <EGL/egl.h>
+#include <gui/IGraphicBufferAlloc.h>
#include <gui/ISurfaceTexture.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
#include <ui/GraphicBuffer.h>
#include <utils/String8.h>
@@ -40,6 +40,7 @@ public:
};
enum { NUM_BUFFER_SLOTS = 32 };
enum { NO_CONNECTED_API = 0 };
+ enum { INVALID_BUFFER_SLOT = -1 };
struct FrameAvailableListener : public virtual RefBase {
// onFrameAvailable() is called from queueBuffer() each time an
@@ -119,8 +120,91 @@ public:
// connected to the specified client API.
virtual status_t disconnect(int api);
-protected:
+ // dump our state in a String
+ virtual void dump(String8& result) const;
+ virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
+
+ // public facing structure for BufferSlot
+ struct BufferItem {
+
+ BufferItem()
+ :
+ mTransform(0),
+ mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+ mTimestamp(0),
+ mFrameNumber(0),
+ mBuf(INVALID_BUFFER_SLOT) {
+ mCrop.makeInvalid();
+ }
+ // mGraphicBuffer points to the buffer allocated for this slot or is NULL
+ // if no buffer has been allocated.
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // mCrop is the current crop rectangle for this buffer slot. This gets
+ // set to mNextCrop each time queueBuffer gets called for this buffer.
+ Rect mCrop;
+
+ // mTransform is the current transform flags for this buffer slot. This
+ // gets set to mNextTransform each time queueBuffer gets called for this
+ // slot.
+ uint32_t mTransform;
+
+ // mScalingMode is the current scaling mode for this buffer slot. This
+ // gets set to mNextScalingMode each time queueBuffer gets called for
+ // this slot.
+ uint32_t mScalingMode;
+
+ // mTimestamp is the current timestamp for this buffer slot. This gets
+ // to set by queueBuffer each time this slot is queued.
+ int64_t mTimestamp;
+ // mFrameNumber is the number of the queued frame for this slot.
+ uint64_t mFrameNumber;
+
+ // buf is the slot index of this buffer
+ int mBuf;
+
+ };
+
+ // The following public functions is the consumer facing interface
+
+ // acquire consumes a buffer by transferring its ownership to a consumer.
+ // buffer contains the GraphicBuffer and its corresponding information.
+ // buffer.mGraphicsBuffer will be NULL when the buffer has been already
+ // acquired by the consumer.
+
+ status_t acquire(BufferItem *buffer);
+
+ // releaseBuffer releases a buffer slot from the consumer back to the
+ // BufferQueue pending a fence sync.
+ status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence);
+
+ // consumerDisconnect disconnects a consumer from the BufferQueue. All
+ // buffers will be freed.
+ status_t consumerDisconnect();
+
+ // setDefaultBufferSize is used to set the size of buffers returned by
+ // requestBuffers when a with and height of zero is requested.
+ status_t setDefaultBufferSize(uint32_t w, uint32_t h);
+
+ // setBufferCountServer set the buffer count. If the client has requested
+ // a buffer count using setBufferCount, the server-buffer count will
+ // take effect once the client sets the count back to zero.
+ status_t setBufferCountServer(int bufferCount);
+
+ // isSynchronousMode returns whether the SurfaceTexture is currently in
+ // synchronous mode.
+ bool isSynchronousMode() const;
+
+ // setConsumerName sets the name used in logging
+ void setConsumerName(const String8& name);
+
+ // setFrameAvailableListener sets the listener object that will be notified
+ // when a new frame becomes available.
+ void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+
+private:
// freeBufferLocked frees the resources (both GraphicBuffer and EGLImage)
// for the given slot.
void freeBufferLocked(int index);
@@ -145,20 +229,18 @@ protected:
status_t setBufferCountServerLocked(int bufferCount);
- enum { INVALID_BUFFER_SLOT = -1 };
-
struct BufferSlot {
BufferSlot()
- : mEglImage(EGL_NO_IMAGE_KHR),
- mEglDisplay(EGL_NO_DISPLAY),
+ : mEglDisplay(EGL_NO_DISPLAY),
mBufferState(BufferSlot::FREE),
mRequestBufferCalled(false),
mTransform(0),
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mTimestamp(0),
mFrameNumber(0),
- mFence(EGL_NO_SYNC_KHR) {
+ mFence(EGL_NO_SYNC_KHR),
+ mAcquireCalled(false) {
mCrop.makeInvalid();
}
@@ -166,9 +248,6 @@ protected:
// if no buffer has been allocated.
sp<GraphicBuffer> mGraphicBuffer;
- // mEglImage is the EGLImage created from mGraphicBuffer.
- EGLImageKHR mEglImage;
-
// mEglDisplay is the EGLDisplay used to create mEglImage.
EGLDisplay mEglDisplay;
@@ -178,6 +257,7 @@ protected:
// FREE indicates that the buffer is not currently being used and
// will not be used in the future until it gets dequeued and
// subsequently queued by the client.
+ // aka "owned by BufferQueue, ready to be dequeued"
FREE = 0,
// DEQUEUED indicates that the buffer has been dequeued by the
@@ -190,6 +270,7 @@ protected:
// dequeued by the client. That means that the current buffer can
// be in either the DEQUEUED or QUEUED state. In asynchronous mode,
// however, the current buffer is always in the QUEUED state.
+ // aka "owned by producer, ready to be queued"
DEQUEUED = 1,
// QUEUED indicates that the buffer has been queued by the client,
@@ -199,7 +280,11 @@ protected:
// the current buffer may be dequeued by the client under some
// circumstances. See the note about the current buffer in the
// documentation for DEQUEUED.
+ // aka "owned by BufferQueue, ready to be acquired"
QUEUED = 2,
+
+ // aka "owned by consumer, ready to be released"
+ ACQUIRED = 3
};
// mBufferState is the current state of this buffer slot.
@@ -236,6 +321,9 @@ protected:
// to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
// on a compile-time option) set to a new sync object in updateTexImage.
EGLSyncKHR mFence;
+
+ // Indicates whether this buffer has been seen by a consumer yet
+ bool mAcquireCalled;
};
// mSlots is the array of buffer slots that must be mirrored on the client
@@ -245,7 +333,6 @@ protected:
// for a slot when requestBuffer is called with that slot's index.
BufferSlot mSlots[NUM_BUFFER_SLOTS];
-
// mDefaultWidth holds the default width of allocated buffers. It is used
// in requestBuffers() if a width and height of zero is specified.
uint32_t mDefaultWidth;
@@ -271,14 +358,6 @@ protected:
// mServerBufferCount buffer count requested by the server-side
int mServerBufferCount;
- // mCurrentTexture is the buffer slot index of the buffer that is currently
- // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
- // indicating that no buffer slot is currently bound to the texture. Note,
- // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
- // that no buffer is bound to the texture. A call to setBufferCount will
- // reset mCurrentTexture to INVALID_BUFFER_SLOT.
- int mCurrentTexture;
-
// mNextCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mNextCrop;
@@ -327,7 +406,7 @@ protected:
// mName is a string used to identify the BufferQueue in log messages.
// It is set by the setName method.
- String8 mName;
+ String8 mConsumerName;
// mMutex is the mutex used to prevent concurrent access to the member
// variables of BufferQueue objects. It must be locked whenever the
@@ -337,6 +416,8 @@ protected:
// mFrameCounter is the free running counter, incremented for every buffer queued
// with the surface Texture.
uint64_t mFrameCounter;
+
+ bool mBufferHasBeenQueued;
};
// ----------------------------------------------------------------------------
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/gui/IGraphicBufferAlloc.h
index d3b206223312..cee41d93414f 100644
--- a/include/surfaceflinger/IGraphicBufferAlloc.h
+++ b/include/gui/IGraphicBufferAlloc.h
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
-#define ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+#ifndef ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H
#include <stdint.h>
#include <sys/types.h>
-#include <utils/RefBase.h>
-
#include <binder/IInterface.h>
+#include <ui/PixelFormat.h>
+#include <utils/RefBase.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -55,4 +55,4 @@ public:
}; // namespace android
-#endif // ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+#endif // ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H
diff --git a/include/surfaceflinger/ISurface.h b/include/gui/ISurface.h
index 5fdf234e5fac..c0ff9fcb1e41 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/gui/ISurface.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_ISURFACE_H
-#define ANDROID_SF_ISURFACE_H
+#ifndef ANDROID_GUI_ISURFACE_H
+#define ANDROID_GUI_ISURFACE_H
#include <stdint.h>
#include <sys/types.h>
@@ -61,4 +61,4 @@ public:
}; // namespace android
-#endif // ANDROID_SF_ISURFACE_H
+#endif // ANDROID_GUI_ISURFACE_H
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 58fd89d3b62c..f3c0ecbc8141 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_ISURFACE_COMPOSER_H
-#define ANDROID_SF_ISURFACE_COMPOSER_H
+#ifndef ANDROID_GUI_ISURFACE_COMPOSER_H
+#define ANDROID_GUI_ISURFACE_COMPOSER_H
#include <stdint.h>
#include <sys/types.h>
@@ -27,8 +27,8 @@
#include <ui/PixelFormat.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposerClient.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -171,4 +171,4 @@ public:
}; // namespace android
-#endif // ANDROID_SF_ISURFACE_COMPOSER_H
+#endif // ANDROID_GUI_ISURFACE_COMPOSER_H
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index 02cabc1cdc31..c793933f6510 100644
--- a/include/surfaceflinger/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
-#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#ifndef ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H
#include <stdint.h>
#include <sys/types.h>
@@ -27,7 +27,7 @@
#include <ui/PixelFormat.h>
-#include <surfaceflinger/ISurface.h>
+#include <gui/ISurface.h>
namespace android {
@@ -81,4 +81,4 @@ public:
}; // namespace android
-#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#endif // ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/gui/Surface.h
index 0460bbd35a8b..1f90c595aa1f 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/gui/Surface.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_SURFACE_H
-#define ANDROID_SF_SURFACE_H
+#ifndef ANDROID_GUI_SURFACE_H
+#define ANDROID_GUI_SURFACE_H
#include <stdint.h>
#include <sys/types.h>
@@ -26,12 +26,10 @@
#include <ui/PixelFormat.h>
#include <ui/Region.h>
-#include <ui/egl/android_natives.h>
#include <gui/SurfaceTextureClient.h>
-
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposerClient.h>
#define ANDROID_VIEW_SURFACE_JNI_ID "mNativeSurface"
@@ -174,4 +172,4 @@ private:
}; // namespace android
-#endif // ANDROID_SF_SURFACE_H
+#endif // ANDROID_GUI_SURFACE_H
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 99affdae64d0..d971031c01a4 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
-#define ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
+#ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
+#define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
#include <stdint.h>
#include <sys/types.h>
@@ -29,7 +29,7 @@
#include <ui/PixelFormat.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
namespace android {
@@ -174,4 +174,4 @@ public:
// ---------------------------------------------------------------------------
}; // namespace android
-#endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
+#endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index dcab049ef06d..5531e539bfdb 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -153,8 +153,8 @@ public:
void setName(const String8& name);
// dump our state in a String
- void dump(String8& result) const;
- void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
+ virtual void dump(String8& result) const;
+ virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
protected:
@@ -217,6 +217,56 @@ private:
// browser's tile cache exceeds.
const GLenum mTexTarget;
+ // SurfaceTexture maintains EGL information about GraphicBuffers that corresponds
+ // directly with BufferQueue's buffers
+ struct EGLSlot {
+ EGLSlot()
+ : mEglImage(EGL_NO_IMAGE_KHR),
+ mEglDisplay(EGL_NO_DISPLAY),
+ mFence(EGL_NO_SYNC_KHR) {
+ }
+
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // mEglImage is the EGLImage created from mGraphicBuffer.
+ EGLImageKHR mEglImage;
+
+ // mEglDisplay is the EGLDisplay used to create mEglImage.
+ EGLDisplay mEglDisplay;
+
+ // mFence is the EGL sync object that must signal before the buffer
+ // associated with this buffer slot may be dequeued. It is initialized
+ // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
+ // on a compile-time option) set to a new sync object in updateTexImage.
+ EGLSyncKHR mFence;
+ };
+
+ EGLSlot mEGLSlots[NUM_BUFFER_SLOTS];
+
+ // mAbandoned indicates that the BufferQueue will no longer be used to
+ // consume images buffers pushed to it using the ISurfaceTexture interface.
+ // It is initialized to false, and set to true in the abandon method. A
+ // BufferQueue that has been abandoned will return the NO_INIT error from
+ // all ISurfaceTexture methods capable of returning an error.
+ bool mAbandoned;
+
+ // mName is a string used to identify the SurfaceTexture in log messages.
+ // It can be set by the setName method.
+ String8 mName;
+
+ // mMutex is the mutex used to prevent concurrent access to the member
+ // variables of SurfaceTexture objects. It must be locked whenever the
+ // member variables are accessed.
+ mutable Mutex mMutex;
+
+ // mCurrentTexture is the buffer slot index of the buffer that is currently
+ // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
+ // indicating that no buffer slot is currently bound to the texture. Note,
+ // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+ // that no buffer is bound to the texture. A call to setBufferCount will
+ // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+ int mCurrentTexture;
+
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 971a1b80dc88..aa7fe48a5292 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -20,7 +20,7 @@
#include <gui/ISurfaceTexture.h>
#include <gui/SurfaceTexture.h>
-#include <ui/egl/android_natives.h>
+#include <ui/ANativeObjectBase.h>
#include <ui/Region.h>
#include <utils/RefBase.h>
@@ -31,7 +31,7 @@ namespace android {
class Surface;
class SurfaceTextureClient
- : public EGLNativeBase<ANativeWindow, SurfaceTextureClient, RefBase>
+ : public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase>
{
public:
SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 3963d9cf5909..70799a638b8a 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -22,6 +22,7 @@
#include <android/native_window.h>
#include <media/IOMX.h>
#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
+#include <OMX_Audio.h>
namespace android {
@@ -37,6 +38,9 @@ struct ACodec : public AHierarchicalStateMachine {
kWhatFlushCompleted = 'fcom',
kWhatOutputFormatChanged = 'outC',
kWhatError = 'erro',
+ kWhatComponentAllocated = 'cAll',
+ kWhatComponentConfigured = 'cCon',
+ kWhatBuffersAllocated = 'allc',
};
ACodec();
@@ -47,6 +51,10 @@ struct ACodec : public AHierarchicalStateMachine {
void signalResume();
void initiateShutdown();
+ void initiateAllocateComponent(const sp<AMessage> &msg);
+ void initiateConfigureComponent(const sp<AMessage> &msg);
+ void initiateStart();
+
protected:
virtual ~ACodec();
@@ -70,6 +78,9 @@ private:
kWhatFlush = 'flus',
kWhatResume = 'resm',
kWhatDrainDeferredMessages = 'drai',
+ kWhatAllocateComponent = 'allo',
+ kWhatConfigureComponent = 'conf',
+ kWhatStart = 'star',
};
enum {
@@ -118,6 +129,7 @@ private:
List<sp<AMessage> > mDeferredQueue;
bool mSentFormat;
+ bool mIsEncoder;
status_t allocateBuffersOnPort(OMX_U32 portIndex);
status_t freeBuffersOnPort(OMX_U32 portIndex);
@@ -132,8 +144,8 @@ private:
uint32_t portIndex, IOMX::buffer_id bufferID,
ssize_t *index = NULL);
- void setComponentRole(bool isEncoder, const char *mime);
- void configureCodec(const char *mime, const sp<AMessage> &msg);
+ status_t setComponentRole(bool isEncoder, const char *mime);
+ status_t configureCodec(const char *mime, const sp<AMessage> &msg);
status_t setVideoPortFormatType(
OMX_U32 portIndex,
@@ -145,20 +157,37 @@ private:
status_t setupVideoDecoder(
const char *mime, int32_t width, int32_t height);
+ status_t setupVideoEncoder(
+ const char *mime, const sp<AMessage> &msg);
+
status_t setVideoFormatOnPort(
OMX_U32 portIndex,
int32_t width, int32_t height,
OMX_VIDEO_CODINGTYPE compressionFormat);
- status_t setupAACDecoder(int32_t numChannels, int32_t sampleRate);
- status_t setupAMRDecoder(bool isWAMR);
- status_t setupG711Decoder(int32_t numChannels);
+ status_t setupAACCodec(
+ bool encoder,
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate);
+
+ status_t selectAudioPortFormat(
+ OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
+
+ status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
+ status_t setupG711Codec(bool encoder, int32_t numChannels);
status_t setupRawAudioFormat(
OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
+ status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
+ status_t setupH263EncoderParameters(const sp<AMessage> &msg);
+ status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
+
+ status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
+ status_t configureBitrate(int32_t bitrate);
+ status_t setupErrorCorrectionParameters();
+
status_t initNativeWindow();
// Returns true iff all buffers on the given port have status OWNED_BY_US.
@@ -173,7 +202,9 @@ private:
void sendFormatChange();
- void signalError(OMX_ERRORTYPE error = OMX_ErrorUndefined);
+ void signalError(
+ OMX_ERRORTYPE error = OMX_ErrorUndefined,
+ status_t internalError = UNKNOWN_ERROR);
DISALLOW_EVIL_CONSTRUCTORS(ACodec);
};
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 32eed3f79c6c..17efd35a5558 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -19,7 +19,7 @@
#define HARDWARE_API_H_
#include <media/stagefright/OMXPluginBase.h>
-#include <ui/android_native_buffer.h>
+#include <system/window.h>
#include <utils/RefBase.h>
#include <OMX_Component.h>
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
new file mode 100644
index 000000000000..8c11c9c67f13
--- /dev/null
+++ b/include/media/stagefright/MediaCodec.h
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+#ifndef MEDIA_CODEC_H_
+
+#define MEDIA_CODEC_H_
+
+#include <gui/ISurfaceTexture.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ABuffer;
+struct ACodec;
+struct AMessage;
+struct SoftwareRenderer;
+struct SurfaceTextureClient;
+
+struct MediaCodec : public AHandler {
+ enum ConfigureFlags {
+ CONFIGURE_FLAG_ENCODE = 1,
+ };
+
+ enum BufferFlags {
+ BUFFER_FLAG_SYNCFRAME = 1,
+ BUFFER_FLAG_CODECCONFIG = 2,
+ BUFFER_FLAG_EOS = 4,
+ };
+
+ static sp<MediaCodec> CreateByType(
+ const sp<ALooper> &looper, const char *mime, bool encoder);
+
+ static sp<MediaCodec> CreateByComponentName(
+ const sp<ALooper> &looper, const char *name);
+
+ status_t configure(
+ const sp<AMessage> &format,
+ const sp<SurfaceTextureClient> &nativeWindow,
+ uint32_t flags);
+
+ status_t start();
+ status_t stop();
+
+ status_t flush();
+
+ status_t queueInputBuffer(
+ size_t index,
+ size_t offset,
+ size_t size,
+ int64_t presentationTimeUs,
+ uint32_t flags);
+
+ status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs = 0ll);
+
+ status_t dequeueOutputBuffer(
+ size_t *index,
+ size_t *offset,
+ size_t *size,
+ int64_t *presentationTimeUs,
+ uint32_t *flags,
+ int64_t timeoutUs = 0ll);
+
+ status_t renderOutputBufferAndRelease(size_t index);
+ status_t releaseOutputBuffer(size_t index);
+
+ status_t getOutputFormat(sp<AMessage> *format) const;
+
+ status_t getInputBuffers(Vector<sp<ABuffer> > *buffers) const;
+ status_t getOutputBuffers(Vector<sp<ABuffer> > *buffers) const;
+
+protected:
+ virtual ~MediaCodec();
+ virtual void onMessageReceived(const sp<AMessage> &msg);
+
+private:
+ enum State {
+ UNINITIALIZED,
+ INITIALIZING,
+ INITIALIZED,
+ CONFIGURING,
+ CONFIGURED,
+ STARTING,
+ STARTED,
+ FLUSHING,
+ STOPPING,
+ };
+
+ enum {
+ kPortIndexInput = 0,
+ kPortIndexOutput = 1,
+ };
+
+ enum {
+ kWhatInit = 'init',
+ kWhatConfigure = 'conf',
+ kWhatStart = 'strt',
+ kWhatStop = 'stop',
+ kWhatDequeueInputBuffer = 'deqI',
+ kWhatQueueInputBuffer = 'queI',
+ kWhatDequeueOutputBuffer = 'deqO',
+ kWhatReleaseOutputBuffer = 'relO',
+ kWhatGetBuffers = 'getB',
+ kWhatFlush = 'flus',
+ kWhatGetOutputFormat = 'getO',
+ kWhatDequeueInputTimedOut = 'dITO',
+ kWhatDequeueOutputTimedOut = 'dOTO',
+ kWhatCodecNotify = 'codc',
+ };
+
+ enum {
+ kFlagIsSoftwareCodec = 1,
+ kFlagOutputFormatChanged = 2,
+ kFlagOutputBuffersChanged = 4,
+ kFlagStickyError = 8,
+ kFlagDequeueInputPending = 16,
+ kFlagDequeueOutputPending = 32,
+ };
+
+ struct BufferInfo {
+ void *mBufferID;
+ sp<ABuffer> mData;
+ sp<AMessage> mNotify;
+ bool mOwnedByClient;
+ };
+
+ State mState;
+ sp<ALooper> mLooper;
+ sp<ALooper> mCodecLooper;
+ sp<ACodec> mCodec;
+ uint32_t mReplyID;
+ uint32_t mFlags;
+ sp<SurfaceTextureClient> mNativeWindow;
+ SoftwareRenderer *mSoftRenderer;
+ sp<AMessage> mOutputFormat;
+
+ List<size_t> mAvailPortBuffers[2];
+ Vector<BufferInfo> mPortBuffers[2];
+
+ int32_t mDequeueInputTimeoutGeneration;
+ uint32_t mDequeueInputReplyID;
+
+ int32_t mDequeueOutputTimeoutGeneration;
+ uint32_t mDequeueOutputReplyID;
+
+ MediaCodec(const sp<ALooper> &looper);
+
+ static status_t PostAndAwaitResponse(
+ const sp<AMessage> &msg, sp<AMessage> *response);
+
+ status_t init(const char *name, bool nameIsType, bool encoder);
+
+ void setState(State newState);
+ void returnBuffersToCodec();
+ void returnBuffersToCodecOnPort(int32_t portIndex);
+ size_t updateBuffers(int32_t portIndex, const sp<AMessage> &msg);
+ status_t onQueueInputBuffer(const sp<AMessage> &msg);
+ status_t onReleaseOutputBuffer(const sp<AMessage> &msg);
+ ssize_t dequeuePortBuffer(int32_t portIndex);
+
+ bool handleDequeueInputBuffer(uint32_t replyID, bool newRequest = false);
+ bool handleDequeueOutputBuffer(uint32_t replyID, bool newRequest = false);
+ void cancelPendingDequeueOperations();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
+};
+
+} // namespace android
+
+#endif // MEDIA_CODEC_H_
diff --git a/include/media/stagefright/MediaErrors.h b/include/media/stagefright/MediaErrors.h
index 21d00b8c531b..dd3bf2876999 100644
--- a/include/media/stagefright/MediaErrors.h
+++ b/include/media/stagefright/MediaErrors.h
@@ -40,6 +40,7 @@ enum {
// Not technically an error.
INFO_FORMAT_CHANGED = MEDIA_ERROR_BASE - 12,
INFO_DISCONTINUITY = MEDIA_ERROR_BASE - 13,
+ INFO_OUTPUT_BUFFERS_CHANGED = MEDIA_ERROR_BASE - 14,
// The following constant values should be in sync with
// drm/drm_framework_common.h
diff --git a/include/media/stagefright/NativeWindowWrapper.h b/include/media/stagefright/NativeWindowWrapper.h
index f323cbc1935c..97cc0cebda3e 100644
--- a/include/media/stagefright/NativeWindowWrapper.h
+++ b/include/media/stagefright/NativeWindowWrapper.h
@@ -18,40 +18,28 @@
#define NATIVE_WINDOW_WRAPPER_H_
-#include <surfaceflinger/Surface.h>
#include <gui/SurfaceTextureClient.h>
namespace android {
-// Both Surface and SurfaceTextureClient are RefBase that implement the
-// ANativeWindow interface, but at different addresses. ANativeWindow is not
-// a RefBase but acts like one for use with sp<>. This wrapper converts a
-// Surface or SurfaceTextureClient into a single reference-counted object
-// that holds an sp reference to the underlying Surface or SurfaceTextureClient,
-// It provides a method to get the ANativeWindow.
+// SurfaceTextureClient derives from ANativeWindow which derives from multiple
+// base classes, in order to carry it in AMessages, we'll temporarily wrap it
+// into a NativeWindowWrapper.
struct NativeWindowWrapper : RefBase {
NativeWindowWrapper(
- const sp<Surface> &surface) :
- mSurface(surface) { }
-
- NativeWindowWrapper(
const sp<SurfaceTextureClient> &surfaceTextureClient) :
mSurfaceTextureClient(surfaceTextureClient) { }
sp<ANativeWindow> getNativeWindow() const {
- if (mSurface != NULL) {
- return mSurface;
- } else {
- return mSurfaceTextureClient;
- }
+ return mSurfaceTextureClient;
}
- // If needed later we can provide a method to ask what kind of native window
+ sp<SurfaceTextureClient> getSurfaceTextureClient() const {
+ return mSurfaceTextureClient;
+ }
private:
- // At most one of mSurface and mSurfaceTextureClient will be non-NULL
- const sp<Surface> mSurface;
const sp<SurfaceTextureClient> mSurfaceTextureClient;
DISALLOW_EVIL_CONSTRUCTORS(NativeWindowWrapper);
diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h
new file mode 100644
index 000000000000..96efdff9eb35
--- /dev/null
+++ b/include/media/stagefright/NuMediaExtractor.h
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#ifndef NU_MEDIA_EXTRACTOR_H_
+#define NU_MEDIA_EXTRACTOR_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ABuffer;
+struct AMessage;
+struct MediaBuffer;
+struct MediaExtractor;
+struct MediaSource;
+
+struct NuMediaExtractor : public RefBase {
+ NuMediaExtractor();
+
+ status_t setDataSource(const char *path);
+
+ size_t countTracks() const;
+ status_t getTrackFormat(size_t index, sp<AMessage> *format) const;
+
+ status_t selectTrack(size_t index);
+
+ status_t seekTo(int64_t timeUs);
+
+ status_t advance();
+ status_t readSampleData(const sp<ABuffer> &buffer);
+ status_t getSampleTrackIndex(size_t *trackIndex);
+ status_t getSampleTime(int64_t *sampleTimeUs);
+
+protected:
+ virtual ~NuMediaExtractor();
+
+private:
+ enum TrackFlags {
+ kIsVorbis = 1,
+ };
+
+ struct TrackInfo {
+ sp<MediaSource> mSource;
+ size_t mTrackIndex;
+ status_t mFinalResult;
+ MediaBuffer *mSample;
+ int64_t mSampleTimeUs;
+ uint32_t mFlags; // bitmask of "TrackFlags"
+ };
+
+ sp<MediaExtractor> mImpl;
+
+ Vector<TrackInfo> mSelectedTracks;
+
+ ssize_t fetchTrackSamples(int64_t seekTimeUs = -1ll);
+ void releaseTrackSamples();
+
+ DISALLOW_EVIL_CONSTRUCTORS(NuMediaExtractor);
+};
+
+} // namespace android
+
+#endif // NU_MEDIA_EXTRACTOR_H_
+
diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h
index 7ec54aa213c4..e5416e4fc9d7 100644
--- a/include/media/stagefright/foundation/AMessage.h
+++ b/include/media/stagefright/foundation/AMessage.h
@@ -25,6 +25,7 @@
namespace android {
+struct ABuffer;
struct AString;
struct Parcel;
@@ -50,6 +51,7 @@ struct AMessage : public RefBase {
void setPointer(const char *name, void *value);
void setString(const char *name, const char *s, ssize_t len = -1);
void setObject(const char *name, const sp<RefBase> &obj);
+ void setBuffer(const char *name, const sp<ABuffer> &buffer);
void setMessage(const char *name, const sp<AMessage> &obj);
void setRect(
@@ -64,6 +66,7 @@ struct AMessage : public RefBase {
bool findPointer(const char *name, void **value) const;
bool findString(const char *name, AString *value) const;
bool findObject(const char *name, sp<RefBase> *obj) const;
+ bool findBuffer(const char *name, sp<ABuffer> *buffer) const;
bool findMessage(const char *name, sp<AMessage> *obj) const;
bool findRect(
@@ -90,10 +93,6 @@ struct AMessage : public RefBase {
AString debugString(int32_t indent = 0) const;
-protected:
- virtual ~AMessage();
-
-private:
enum Type {
kTypeInt32,
kTypeInt64,
@@ -105,8 +104,16 @@ private:
kTypeObject,
kTypeMessage,
kTypeRect,
+ kTypeBuffer,
};
+ size_t countEntries() const;
+ const char *getEntryNameAt(size_t index, Type *type) const;
+
+protected:
+ virtual ~AMessage();
+
+private:
uint32_t mWhat;
ALooper::handler_id mTarget;
@@ -131,7 +138,7 @@ private:
};
enum {
- kMaxNumItems = 16
+ kMaxNumItems = 32
};
Item mItems[kMaxNumItems];
size_t mNumItems;
@@ -140,6 +147,9 @@ private:
void freeItem(Item *item);
const Item *findItem(const char *name, Type type) const;
+ void setObjectInternal(
+ const char *name, const sp<RefBase> &obj, Type type);
+
DISALLOW_EVIL_CONSTRUCTORS(AMessage);
};
diff --git a/include/private/surfaceflinger/LayerState.h b/include/private/gui/LayerState.h
index 3eb5c99f6f57..ca277e02b94b 100644
--- a/include/private/surfaceflinger/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -23,8 +23,7 @@
#include <utils/Errors.h>
#include <ui/Region.h>
-
-#include <surfaceflinger/ISurface.h>
+#include <gui/ISurface.h>
namespace android {
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/gui/SharedBufferStack.h
index 0da03d1343c7..0da03d1343c7 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/gui/SharedBufferStack.h
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
deleted file mode 100644
index 6b1fa770281d..000000000000
--- a/include/private/opengles/gl_context.h
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_OPENGLES_CONTEXT_H
-#define ANDROID_OPENGLES_CONTEXT_H
-
-#include <stdint.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <pthread.h>
-#ifdef HAVE_ANDROID_OS
-#include <bionic_tls.h>
-#endif
-
-#include <private/pixelflinger/ggl_context.h>
-#include <hardware/gralloc.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-namespace android {
-
-
-const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
-#ifdef GL_OES_compressed_ETC1_RGB8_texture
- + 1
-#endif
- ;
-
-class EGLTextureObject;
-class EGLSurfaceManager;
-class EGLBufferObjectManager;
-
-namespace gl {
-
-struct ogles_context_t;
-struct matrixx_t;
-struct transform_t;
-struct buffer_t;
-
-ogles_context_t* getGlContext();
-
-template<typename T>
-static inline void swap(T& a, T& b) {
- T t(a); a = b; b = t;
-}
-template<typename T>
-inline T max(T a, T b) {
- return a<b ? b : a;
-}
-template<typename T>
-inline T max(T a, T b, T c) {
- return max(a, max(b, c));
-}
-template<typename T>
-inline T min(T a, T b) {
- return a<b ? a : b;
-}
-template<typename T>
-inline T min(T a, T b, T c) {
- return min(a, min(b, c));
-}
-template<typename T>
-inline T min(T a, T b, T c, T d) {
- return min(min(a,b), min(c,d));
-}
-
-// ----------------------------------------------------------------------------
-// vertices
-// ----------------------------------------------------------------------------
-
-struct vec3_t {
- union {
- struct { GLfixed x, y, z; };
- struct { GLfixed r, g, b; };
- struct { GLfixed S, T, R; };
- GLfixed v[3];
- };
-};
-
-struct vec4_t {
- union {
- struct { GLfixed x, y, z, w; };
- struct { GLfixed r, g, b, a; };
- struct { GLfixed S, T, R, Q; };
- GLfixed v[4];
- };
-};
-
-struct vertex_t {
- enum {
- // these constant matter for our clipping
- CLIP_L = 0x0001, // clipping flags
- CLIP_R = 0x0002,
- CLIP_B = 0x0004,
- CLIP_T = 0x0008,
- CLIP_N = 0x0010,
- CLIP_F = 0x0020,
-
- EYE = 0x0040,
- RESERVED = 0x0080,
-
- USER_CLIP_0 = 0x0100, // user clipping flags
- USER_CLIP_1 = 0x0200,
- USER_CLIP_2 = 0x0400,
- USER_CLIP_3 = 0x0800,
- USER_CLIP_4 = 0x1000,
- USER_CLIP_5 = 0x2000,
-
- LIT = 0x4000, // lighting has been applied
- TT = 0x8000, // texture coords transformed
-
- FRUSTUM_CLIP_ALL= 0x003F,
- USER_CLIP_ALL = 0x3F00,
- CLIP_ALL = 0x3F3F,
- };
-
- // the fields below are arranged to minimize d-cache usage
- // we group together, by cache-line, the fields most likely to be used
-
- union {
- vec4_t obj;
- vec4_t eye;
- };
- vec4_t clip;
-
- uint32_t flags;
- size_t index; // cache tag, and vertex index
- GLfixed fog;
- uint8_t locked;
- uint8_t mru;
- uint8_t reserved[2];
- vec4_t window;
-
- vec4_t color;
- vec4_t texture[GGL_TEXTURE_UNIT_COUNT];
- uint32_t reserved1[4];
-
- inline void clear() {
- flags = index = locked = mru = 0;
- }
-};
-
-struct point_size_t {
- GGLcoord size;
- GLboolean smooth;
-};
-
-struct line_width_t {
- GGLcoord width;
- GLboolean smooth;
-};
-
-struct polygon_offset_t {
- GLfixed factor;
- GLfixed units;
- GLboolean enable;
-};
-
-// ----------------------------------------------------------------------------
-// arrays
-// ----------------------------------------------------------------------------
-
-struct array_t {
- typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
- fetcher_t fetch;
- GLvoid const* physical_pointer;
- GLint size;
- GLsizei stride;
- GLvoid const* pointer;
- buffer_t const* bo;
- uint16_t type;
- GLboolean enable;
- GLboolean pad;
- GLsizei bounds;
- void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
- inline void resolve();
- inline const GLubyte* element(GLint i) const {
- return (const GLubyte*)physical_pointer + i * stride;
- }
-};
-
-struct array_machine_t {
- array_t vertex;
- array_t normal;
- array_t color;
- array_t texture[GGL_TEXTURE_UNIT_COUNT];
- uint8_t activeTexture;
- uint8_t tmu;
- uint16_t cull;
- uint32_t flags;
- GLenum indicesType;
- buffer_t const* array_buffer;
- buffer_t const* element_array_buffer;
-
- void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
- void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
-
- void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
- void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
- void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
- void (*perspective)(ogles_context_t*c, vertex_t* v);
- void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
- GGLfixed t, const vertex_t* s, const vertex_t* p);
- void (*clipEye)(ogles_context_t* c, vertex_t* nv,
- GGLfixed t, const vertex_t* s, const vertex_t* p);
-};
-
-struct vertex_cache_t {
- enum {
- // must be at least 4
- // 3 vertice for triangles
- // or 2 + 2 for indexed triangles w/ cache contention
- VERTEX_BUFFER_SIZE = 8,
- // must be a power of two and at least 3
- VERTEX_CACHE_SIZE = 64, // 8 KB
-
- INDEX_BITS = 16,
- INDEX_MASK = ((1LU<<INDEX_BITS)-1),
- INDEX_SEQ = 1LU<<INDEX_BITS,
- };
- vertex_t* vBuffer;
- vertex_t* vCache;
- uint32_t sequence;
- void* base;
- uint32_t total;
- uint32_t misses;
- int64_t startTime;
- void init();
- void uninit();
- void clear();
- void dump_stats(GLenum mode);
-};
-
-// ----------------------------------------------------------------------------
-// fog
-// ----------------------------------------------------------------------------
-
-struct fog_t {
- GLfixed density;
- GLfixed start;
- GLfixed end;
- GLfixed invEndMinusStart;
- GLenum mode;
- GLfixed (*fog)(ogles_context_t* c, GLfixed z);
-};
-
-// ----------------------------------------------------------------------------
-// user clip planes
-// ----------------------------------------------------------------------------
-
-const unsigned int OGLES_MAX_CLIP_PLANES = 6;
-
-struct clip_plane_t {
- vec4_t equation;
-};
-
-struct user_clip_planes_t {
- clip_plane_t plane[OGLES_MAX_CLIP_PLANES];
- uint32_t enable;
-};
-
-// ----------------------------------------------------------------------------
-// lighting
-// ----------------------------------------------------------------------------
-
-const unsigned int OGLES_MAX_LIGHTS = 8;
-
-struct light_t {
- vec4_t ambient;
- vec4_t diffuse;
- vec4_t specular;
- vec4_t implicitAmbient;
- vec4_t implicitDiffuse;
- vec4_t implicitSpecular;
- vec4_t position; // position in eye space
- vec4_t objPosition;
- vec4_t normalizedObjPosition;
- vec4_t spotDir;
- vec4_t normalizedSpotDir;
- GLfixed spotExp;
- GLfixed spotCutoff;
- GLfixed spotCutoffCosine;
- GLfixed attenuation[3];
- GLfixed rConstAttenuation;
- GLboolean enable;
-};
-
-struct material_t {
- vec4_t ambient;
- vec4_t diffuse;
- vec4_t specular;
- vec4_t emission;
- GLfixed shininess;
-};
-
-struct light_model_t {
- vec4_t ambient;
- GLboolean twoSide;
-};
-
-struct color_material_t {
- GLenum face;
- GLenum mode;
- GLboolean enable;
-};
-
-struct lighting_t {
- light_t lights[OGLES_MAX_LIGHTS];
- material_t front;
- light_model_t lightModel;
- color_material_t colorMaterial;
- vec4_t implicitSceneEmissionAndAmbient;
- vec4_t objViewer;
- uint32_t enabledLights;
- GLboolean enable;
- GLenum shadeModel;
- typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
- void (*lightVertex)(ogles_context_t* c, vertex_t* v);
- void (*lightTriangle)(ogles_context_t* c,
- vertex_t* v0, vertex_t* v1, vertex_t* v2);
-};
-
-struct culling_t {
- GLenum cullFace;
- GLenum frontFace;
- GLboolean enable;
-};
-
-// ----------------------------------------------------------------------------
-// textures
-// ----------------------------------------------------------------------------
-
-struct texture_unit_t {
- GLuint name;
- EGLTextureObject* texture;
- uint8_t dirty;
-};
-
-struct texture_state_t
-{
- texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT];
- int active; // active tmu
- EGLTextureObject* defaultTexture;
- GGLContext* ggl;
- uint8_t packAlignment;
- uint8_t unpackAlignment;
-};
-
-// ----------------------------------------------------------------------------
-// transformation and matrices
-// ----------------------------------------------------------------------------
-
-struct matrixf_t;
-
-struct matrixx_t {
- GLfixed m[16];
- void load(const matrixf_t& rhs);
-};
-
-struct matrix_stack_t;
-
-
-struct matrixf_t {
- void loadIdentity();
- void load(const matrixf_t& rhs);
-
- inline GLfloat* editElements() { return m; }
- inline GLfloat const* elements() const { return m; }
-
- void set(const GLfixed* rhs);
- void set(const GLfloat* rhs);
-
- static void multiply(matrixf_t& r,
- const matrixf_t& lhs, const matrixf_t& rhs);
-
- void dump(const char* what);
-
-private:
- friend struct matrix_stack_t;
- GLfloat m[16];
- void load(const GLfixed* rhs);
- void load(const GLfloat* rhs);
- void multiply(const matrixf_t& rhs);
- void translate(GLfloat x, GLfloat y, GLfloat z);
- void scale(GLfloat x, GLfloat y, GLfloat z);
- void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
-};
-
-enum {
- OP_IDENTITY = 0x00,
- OP_TRANSLATE = 0x01,
- OP_UNIFORM_SCALE = 0x02,
- OP_SCALE = 0x05,
- OP_ROTATE = 0x08,
- OP_SKEW = 0x10,
- OP_ALL = 0x1F
-};
-
-struct transform_t {
- enum {
- FLAGS_2D_PROJECTION = 0x1
- };
- matrixx_t matrix;
- uint32_t flags;
- uint32_t ops;
-
- union {
- struct {
- void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
- void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
- void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
- };
- void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
- };
-
- void loadIdentity();
- void picker();
- void dump(const char* what);
-};
-
-struct mvui_transform_t : public transform_t
-{
- void picker();
-};
-
-struct matrix_stack_t {
- enum {
- DO_PICKER = 0x1,
- DO_FLOAT_TO_FIXED = 0x2
- };
- transform_t transform;
- uint8_t maxDepth;
- uint8_t depth;
- uint8_t dirty;
- uint8_t reserved;
- matrixf_t *stack;
- uint8_t *ops;
- void init(int depth);
- void uninit();
- void loadIdentity();
- void load(const GLfixed* rhs);
- void load(const GLfloat* rhs);
- void multiply(const matrixf_t& rhs);
- void translate(GLfloat x, GLfloat y, GLfloat z);
- void scale(GLfloat x, GLfloat y, GLfloat z);
- void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
- GLint push();
- GLint pop();
- void validate();
- matrixf_t& top() { return stack[depth]; }
- const matrixf_t& top() const { return stack[depth]; }
- uint32_t top_ops() const { return ops[depth]; }
- inline bool isRigidBody() const {
- return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
- }
-};
-
-struct vp_transform_t {
- transform_t transform;
- matrixf_t matrix;
- GLfloat zNear;
- GLfloat zFar;
- void loadIdentity();
-};
-
-struct transform_state_t {
- enum {
- MODELVIEW = 0x01,
- PROJECTION = 0x02,
- VIEWPORT = 0x04,
- TEXTURE = 0x08,
- MVUI = 0x10,
- MVIT = 0x20,
- MVP = 0x40,
- };
- matrix_stack_t *current;
- matrix_stack_t modelview;
- matrix_stack_t projection;
- matrix_stack_t texture[GGL_TEXTURE_UNIT_COUNT];
-
- // modelview * projection
- transform_t mvp __attribute__((aligned(32)));
- // viewport transformation
- vp_transform_t vpt __attribute__((aligned(32)));
- // same for 4-D vertices
- transform_t mvp4;
- // full modelview inverse transpose
- transform_t mvit4;
- // upper 3x3 of mv-inverse-transpose (for normals)
- mvui_transform_t mvui;
-
- GLenum matrixMode;
- GLenum rescaleNormals;
- uint32_t dirty;
- void invalidate();
- void update_mvp();
- void update_mvit();
- void update_mvui();
-};
-
-struct viewport_t {
- GLint x;
- GLint y;
- GLsizei w;
- GLsizei h;
- struct {
- GLint x;
- GLint y;
- } surfaceport;
- struct {
- GLint x;
- GLint y;
- GLsizei w;
- GLsizei h;
- } scissor;
-};
-
-// ----------------------------------------------------------------------------
-// Lerping
-// ----------------------------------------------------------------------------
-
-struct compute_iterators_t
-{
- void initTriangle(
- vertex_t const* v0,
- vertex_t const* v1,
- vertex_t const* v2);
-
- void initLine(
- vertex_t const* v0,
- vertex_t const* v1);
-
- inline void initLerp(vertex_t const* v0, uint32_t enables);
-
- int iteratorsScale(int32_t it[3],
- int32_t c0, int32_t c1, int32_t c2) const;
-
- void iterators1616(GGLfixed it[3],
- GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
-
- void iterators0032(int32_t it[3],
- int32_t c0, int32_t c1, int32_t c2) const;
-
- void iterators0032(int64_t it[3],
- int32_t c0, int32_t c1, int32_t c2) const;
-
- GGLcoord area() const { return m_area; }
-
-private:
- // don't change order of members here -- used by iterators.S
- GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
- GGLcoord m_x0, m_y0;
- GGLcoord m_area;
- uint8_t m_scale;
- uint8_t m_area_scale;
- uint8_t m_reserved[2];
-
-};
-
-// ----------------------------------------------------------------------------
-// state
-// ----------------------------------------------------------------------------
-
-#ifdef HAVE_ANDROID_OS
- // We have a dedicated TLS slot in bionic
- inline void setGlThreadSpecific(ogles_context_t *value) {
- ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
- }
- inline ogles_context_t* getGlThreadSpecific() {
- return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
- }
-#else
- extern pthread_key_t gGLKey;
- inline void setGlThreadSpecific(ogles_context_t *value) {
- pthread_setspecific(gGLKey, value);
- }
- inline ogles_context_t* getGlThreadSpecific() {
- return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
- }
-#endif
-
-
-struct prims_t {
- typedef ogles_context_t* GL;
- void (*renderPoint)(GL, vertex_t*);
- void (*renderLine)(GL, vertex_t*, vertex_t*);
- void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
-};
-
-struct ogles_context_t {
- context_t rasterizer;
- array_machine_t arrays __attribute__((aligned(32)));
- texture_state_t textures;
- transform_state_t transforms;
- vertex_cache_t vc;
- prims_t prims;
- culling_t cull;
- lighting_t lighting;
- user_clip_planes_t clipPlanes;
- compute_iterators_t lerp; __attribute__((aligned(32)));
- vertex_t current;
- vec4_t currentColorClamped;
- vec3_t currentNormal;
- viewport_t viewport;
- point_size_t point;
- line_width_t line;
- polygon_offset_t polygonOffset;
- fog_t fog;
- uint32_t perspective : 1;
- uint32_t transformTextures : 1;
- EGLSurfaceManager* surfaceManager;
- EGLBufferObjectManager* bufferObjectManager;
-
- GLenum error;
-
- static inline ogles_context_t* get() {
- return getGlThreadSpecific();
- }
-
-};
-
-}; // namespace gl
-}; // namespace android
-
-#endif // ANDROID_OPENGLES_CONTEXT_H
-
diff --git a/include/ui/egl/android_natives.h b/include/ui/ANativeObjectBase.h
index 9ac50a5a39a8..76e850fa279a 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/ANativeObjectBase.h
@@ -22,8 +22,7 @@
#include <hardware/gralloc.h>
#include <system/window.h>
-// FIXME: remove this header, it's for legacy use. native_window is pulled from frameworks/base/native/include/android/
-#include <android/native_window.h>
+
// ---------------------------------------------------------------------------
/* FIXME: this is legacy for pixmaps */
@@ -52,11 +51,11 @@ typedef struct egl_native_pixmap_t
namespace android {
/*
- * This helper class turns an EGL android_native_xxx type into a C++
+ * This helper class turns a ANativeXXX object type into a C++
* reference-counted object; with proper type conversions.
*/
template <typename NATIVE_TYPE, typename TYPE, typename REF>
-class EGLNativeBase : public NATIVE_TYPE, public REF
+class ANativeObjectBase : public NATIVE_TYPE, public REF
{
public:
// Disambiguate between the incStrong in REF and NATIVE_TYPE
@@ -68,8 +67,8 @@ public:
}
protected:
- typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
- EGLNativeBase() : NATIVE_TYPE(), REF() {
+ typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE;
+ ANativeObjectBase() : NATIVE_TYPE(), REF() {
NATIVE_TYPE::common.incRef = incRef;
NATIVE_TYPE::common.decRef = decRef;
}
@@ -86,11 +85,11 @@ protected:
return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));
}
static void incRef(android_native_base_t* base) {
- EGLNativeBase* self = getSelf(base);
+ ANativeObjectBase* self = getSelf(base);
self->incStrong(self);
}
static void decRef(android_native_base_t* base) {
- EGLNativeBase* self = getSelf(base);
+ ANativeObjectBase* self = getSelf(base);
self->decStrong(self);
}
};
diff --git a/include/ui/EGLNativeSurface.h b/include/ui/EGLNativeSurface.h
deleted file mode 100644
index 7964e7c6bac9..000000000000
--- a/include/ui/EGLNativeSurface.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_EGL_NATIVE_SURFACE_H
-#define ANDROID_EGL_NATIVE_SURFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <cutils/atomic.h>
-#include <utils/RefBase.h>
-
-#include <EGL/eglnatives.h>
-
-// ---------------------------------------------------------------------------
-namespace android {
-// ---------------------------------------------------------------------------
-
-template <class TYPE>
-class EGLNativeSurface : public egl_native_window_t, public LightRefBase<TYPE>
-{
-public:
- EGLNativeSurface() {
- memset(egl_native_window_t::reserved, 0,
- sizeof(egl_native_window_t::reserved));
- memset(egl_native_window_t::reserved_proc, 0,
- sizeof(egl_native_window_t::reserved_proc));
- memset(egl_native_window_t::oem, 0,
- sizeof(egl_native_window_t::oem));
- }
-protected:
- EGLNativeSurface& operator = (const EGLNativeSurface& rhs);
- EGLNativeSurface(const EGLNativeSurface& rhs);
- inline ~EGLNativeSurface() { };
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
-
-#endif // ANDROID_EGL_SURFACE_H
-
diff --git a/include/ui/EGLUtils.h b/include/ui/EGLUtils.h
deleted file mode 100644
index a5bff812399b..000000000000
--- a/include/ui/EGLUtils.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-
-#ifndef ANDROID_UI_EGLUTILS_H
-#define ANDROID_UI_EGLUTILS_H
-
-#include <utils/Errors.h>
-#include <ui/PixelFormat.h>
-#include <EGL/egl.h>
-
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-class EGLUtils
-{
-public:
-
- static const char *strerror(EGLint err);
-
- static status_t selectConfigForPixelFormat(
- EGLDisplay dpy,
- EGLint const* attrs,
- PixelFormat format,
- EGLConfig* outConfig);
-
- static status_t selectConfigForNativeWindow(
- EGLDisplay dpy,
- EGLint const* attrs,
- EGLNativeWindowType window,
- EGLConfig* outConfig);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-
-#endif /* ANDROID_UI_EGLUTILS_H */
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 302d01239eeb..b202b95b1c5f 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -24,11 +24,9 @@
#include <utils/threads.h>
#include <utils/String8.h>
-#include <ui/Rect.h>
-
-#include <pixelflinger/pixelflinger.h>
-#include <ui/egl/android_natives.h>
+#include <ui/ANativeObjectBase.h>
+#include <ui/Rect.h>
#define NUM_FRAME_BUFFERS 2
@@ -44,7 +42,7 @@ class NativeBuffer;
// ---------------------------------------------------------------------------
class FramebufferNativeWindow
- : public EGLNativeBase<
+ : public ANativeObjectBase<
ANativeWindow,
FramebufferNativeWindow,
LightRefBase<FramebufferNativeWindow> >
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 6ab01f4c98ef..f318cd899fec 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -20,11 +20,11 @@
#include <stdint.h>
#include <sys/types.h>
-#include <ui/android_native_buffer.h>
+#include <ui/ANativeObjectBase.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <utils/Flattenable.h>
-#include <pixelflinger/pixelflinger.h>
+
struct ANativeWindowBuffer;
@@ -37,7 +37,7 @@ class GraphicBufferMapper;
// ===========================================================================
class GraphicBuffer
- : public EGLNativeBase<
+ : public ANativeObjectBase<
ANativeWindowBuffer,
GraphicBuffer,
LightRefBase<GraphicBuffer> >, public Flattenable
@@ -93,7 +93,6 @@ public:
status_t lock(uint32_t usage, void** vaddr);
status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
- status_t lock(GGLSurface* surface, uint32_t usage);
status_t unlock();
ANativeWindowBuffer* getNativeBuffer() const;
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index fc260c4f4b1d..9f3e267139c7 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -64,9 +64,6 @@ enum {
PIXEL_FORMAT_RGBA_5551 = HAL_PIXEL_FORMAT_RGBA_5551, // 16-bit ARGB
PIXEL_FORMAT_RGBA_4444 = HAL_PIXEL_FORMAT_RGBA_4444, // 16-bit ARGB
PIXEL_FORMAT_A_8 = 8, // 8-bit A
-
- // New formats can be added if they're also defined in
- // pixelflinger/format.h
};
typedef int32_t PixelFormat;
@@ -80,10 +77,12 @@ struct PixelFormatInfo {
};
enum { // components
- ALPHA = 1,
- RGB = 2,
- RGBA = 3,
- OTHER = 0xFF
+ ALPHA = 1,
+ RGB = 2,
+ RGBA = 3,
+ L = 4,
+ LA = 5,
+ OTHER = 0xFF
};
struct szinfo {
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h
new file mode 100644
index 000000000000..f9f7aa41a061
--- /dev/null
+++ b/include/utils/AndroidThreads.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_ANDROID_THREADS_H
+#define _LIBS_UTILS_ANDROID_THREADS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/ThreadDefs.h>
+
+// ---------------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Create and run a new thread.
+extern int androidCreateThread(android_thread_func_t, void *);
+
+// Create thread with lots of parameters
+extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
+ void *userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t *threadId);
+
+// Get some sort of unique identifier for the current thread.
+extern android_thread_id_t androidGetThreadId();
+
+// Low-level thread creation -- never creates threads that can
+// interact with the Java VM.
+extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+ void *userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t *threadId);
+
+// Used by the Java Runtime to control how threads are created, so that
+// they can be proper and lovely Java threads.
+typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
+ void *userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t *threadId);
+
+extern void androidSetCreateThreadFunc(android_create_thread_fn func);
+
+// ------------------------------------------------------------------
+// Extra functions working with raw pids.
+
+// Get pid for the current thread.
+extern pid_t androidGetTid();
+
+// Change the scheduling group of a particular thread. The group
+// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if
+// grp is out of range, else another non-zero value with errno set if
+// the operation failed. Thread ID zero means current thread.
+extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
+
+// Change the priority AND scheduling group of a particular thread. The priority
+// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
+// if the priority set failed, else another value if just the group set failed;
+// in either case errno is set. Thread ID zero means current thread.
+extern int androidSetThreadPriority(pid_t tid, int prio);
+
+// Get the current priority of a particular thread. Returns one of the
+// ANDROID_PRIORITY constants or a negative result in case of error.
+extern int androidGetThreadPriority(pid_t tid);
+
+// Get the current scheduling group of a particular thread. Normally returns
+// one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT.
+// Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if
+// scheduling groups are disabled. Returns INVALID_OPERATION if unexpected error.
+// Thread ID zero means current thread.
+extern int androidGetThreadSchedulingGroup(pid_t tid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ----------------------------------------------------------------------------
+// C++ API
+#ifdef __cplusplus
+namespace android {
+// ----------------------------------------------------------------------------
+
+// Create and run a new thread.
+inline bool createThread(thread_func_t f, void *a) {
+ return androidCreateThread(f, a) ? true : false;
+}
+
+// Create thread with lots of parameters
+inline bool createThreadEtc(thread_func_t entryFunction,
+ void *userData,
+ const char* threadName = "android:unnamed_thread",
+ int32_t threadPriority = PRIORITY_DEFAULT,
+ size_t threadStackSize = 0,
+ thread_id_t *threadId = 0)
+{
+ return androidCreateThreadEtc(entryFunction, userData, threadName,
+ threadPriority, threadStackSize, threadId) ? true : false;
+}
+
+// Get some sort of unique identifier for the current thread.
+inline thread_id_t getThreadId() {
+ return androidGetThreadId();
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+#endif // __cplusplus
+// ----------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_ANDROID_THREADS_H
diff --git a/include/utils/Condition.h b/include/utils/Condition.h
new file mode 100644
index 000000000000..8852d53330e7
--- /dev/null
+++ b/include/utils/Condition.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_CONDITION_H
+#define _LIBS_UTILS_CONDITION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/Timers.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+/*
+ * Condition variable class. The implementation is system-dependent.
+ *
+ * Condition variables are paired up with mutexes. Lock the mutex,
+ * call wait(), then either re-wait() if things aren't quite what you want,
+ * or unlock the mutex and continue. All threads calling wait() must
+ * use the same mutex for a given Condition.
+ */
+class Condition {
+public:
+ enum {
+ PRIVATE = 0,
+ SHARED = 1
+ };
+
+ Condition();
+ Condition(int type);
+ ~Condition();
+ // Wait on the condition variable. Lock the mutex before calling.
+ status_t wait(Mutex& mutex);
+ // same with relative timeout
+ status_t waitRelative(Mutex& mutex, nsecs_t reltime);
+ // Signal the condition variable, allowing one thread to continue.
+ void signal();
+ // Signal the condition variable, allowing all threads to continue.
+ void broadcast();
+
+private:
+#if defined(HAVE_PTHREADS)
+ pthread_cond_t mCond;
+#else
+ void* mState;
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+#if defined(HAVE_PTHREADS)
+
+inline Condition::Condition() {
+ pthread_cond_init(&mCond, NULL);
+}
+inline Condition::Condition(int type) {
+ if (type == SHARED) {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_cond_init(&mCond, &attr);
+ pthread_condattr_destroy(&attr);
+ } else {
+ pthread_cond_init(&mCond, NULL);
+ }
+}
+inline Condition::~Condition() {
+ pthread_cond_destroy(&mCond);
+}
+inline status_t Condition::wait(Mutex& mutex) {
+ return -pthread_cond_wait(&mCond, &mutex.mMutex);
+}
+inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
+#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
+ struct timespec ts;
+ ts.tv_sec = reltime/1000000000;
+ ts.tv_nsec = reltime%1000000000;
+ return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
+#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
+ struct timespec ts;
+#if defined(HAVE_POSIX_CLOCKS)
+ clock_gettime(CLOCK_REALTIME, &ts);
+#else // HAVE_POSIX_CLOCKS
+ // we don't support the clocks here.
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ ts.tv_sec = t.tv_sec;
+ ts.tv_nsec= t.tv_usec*1000;
+#endif // HAVE_POSIX_CLOCKS
+ ts.tv_sec += reltime/1000000000;
+ ts.tv_nsec+= reltime%1000000000;
+ if (ts.tv_nsec >= 1000000000) {
+ ts.tv_nsec -= 1000000000;
+ ts.tv_sec += 1;
+ }
+ return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
+#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
+}
+inline void Condition::signal() {
+ pthread_cond_signal(&mCond);
+}
+inline void Condition::broadcast() {
+ pthread_cond_broadcast(&mCond);
+}
+
+#endif // HAVE_PTHREADS
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_CONDITON_H
diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h
index fcc3bcfa00a1..85535bd61e97 100644
--- a/include/utils/KeyedVector.h
+++ b/include/utils/KeyedVector.h
@@ -122,7 +122,7 @@ ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {
template<typename KEY, typename VALUE> inline
const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
- ssize_t i = indexOfKey(key);
+ ssize_t i = this->indexOfKey(key);
assert(i>=0);
return mVector.itemAt(i).value;
}
@@ -139,7 +139,7 @@ const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {
template<typename KEY, typename VALUE> inline
VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {
- ssize_t i = indexOfKey(key);
+ ssize_t i = this->indexOfKey(key);
assert(i>=0);
return mVector.editItemAt(i).value;
}
@@ -190,7 +190,7 @@ DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)
template<typename KEY, typename VALUE> inline
const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
- ssize_t i = indexOfKey(key);
+ ssize_t i = this->indexOfKey(key);
return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;
}
diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h
new file mode 100644
index 000000000000..de6fb394ad9c
--- /dev/null
+++ b/include/utils/Mutex.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_MUTEX_H
+#define _LIBS_UTILS_MUTEX_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Condition;
+
+/*
+ * Simple mutex class. The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it. They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class Mutex {
+public:
+ enum {
+ PRIVATE = 0,
+ SHARED = 1
+ };
+
+ Mutex();
+ Mutex(const char* name);
+ Mutex(int type, const char* name = NULL);
+ ~Mutex();
+
+ // lock or unlock the mutex
+ status_t lock();
+ void unlock();
+
+ // lock if possible; returns 0 on success, error otherwise
+ status_t tryLock();
+
+ // Manages the mutex automatically. It'll be locked when Autolock is
+ // constructed and released when Autolock goes out of scope.
+ class Autolock {
+ public:
+ inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
+ inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
+ inline ~Autolock() { mLock.unlock(); }
+ private:
+ Mutex& mLock;
+ };
+
+private:
+ friend class Condition;
+
+ // A mutex cannot be copied
+ Mutex(const Mutex&);
+ Mutex& operator = (const Mutex&);
+
+#if defined(HAVE_PTHREADS)
+ pthread_mutex_t mMutex;
+#else
+ void _init();
+ void* mState;
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+#if defined(HAVE_PTHREADS)
+
+inline Mutex::Mutex() {
+ pthread_mutex_init(&mMutex, NULL);
+}
+inline Mutex::Mutex(const char* name) {
+ pthread_mutex_init(&mMutex, NULL);
+}
+inline Mutex::Mutex(int type, const char* name) {
+ if (type == SHARED) {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_mutex_init(&mMutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ } else {
+ pthread_mutex_init(&mMutex, NULL);
+ }
+}
+inline Mutex::~Mutex() {
+ pthread_mutex_destroy(&mMutex);
+}
+inline status_t Mutex::lock() {
+ return -pthread_mutex_lock(&mMutex);
+}
+inline void Mutex::unlock() {
+ pthread_mutex_unlock(&mMutex);
+}
+inline status_t Mutex::tryLock() {
+ return -pthread_mutex_trylock(&mMutex);
+}
+
+#endif // HAVE_PTHREADS
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Automatic mutex. Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+
+typedef Mutex::Autolock AutoMutex;
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_MUTEX_H
diff --git a/include/utils/RWLock.h b/include/utils/RWLock.h
new file mode 100644
index 000000000000..a5abea2b8fa0
--- /dev/null
+++ b/include/utils/RWLock.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_RWLOCK_H
+#define _LIBS_UTILS_RWLOCK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+#include <utils/ThreadDefs.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+#if defined(HAVE_PTHREADS)
+
+/*
+ * Simple mutex class. The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it. They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class RWLock {
+public:
+ enum {
+ PRIVATE = 0,
+ SHARED = 1
+ };
+
+ RWLock();
+ RWLock(const char* name);
+ RWLock(int type, const char* name = NULL);
+ ~RWLock();
+
+ status_t readLock();
+ status_t tryReadLock();
+ status_t writeLock();
+ status_t tryWriteLock();
+ void unlock();
+
+ class AutoRLock {
+ public:
+ inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); }
+ inline ~AutoRLock() { mLock.unlock(); }
+ private:
+ RWLock& mLock;
+ };
+
+ class AutoWLock {
+ public:
+ inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); }
+ inline ~AutoWLock() { mLock.unlock(); }
+ private:
+ RWLock& mLock;
+ };
+
+private:
+ // A RWLock cannot be copied
+ RWLock(const RWLock&);
+ RWLock& operator = (const RWLock&);
+
+ pthread_rwlock_t mRWLock;
+};
+
+inline RWLock::RWLock() {
+ pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(const char* name) {
+ pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(int type, const char* name) {
+ if (type == SHARED) {
+ pthread_rwlockattr_t attr;
+ pthread_rwlockattr_init(&attr);
+ pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ pthread_rwlock_init(&mRWLock, &attr);
+ pthread_rwlockattr_destroy(&attr);
+ } else {
+ pthread_rwlock_init(&mRWLock, NULL);
+ }
+}
+inline RWLock::~RWLock() {
+ pthread_rwlock_destroy(&mRWLock);
+}
+inline status_t RWLock::readLock() {
+ return -pthread_rwlock_rdlock(&mRWLock);
+}
+inline status_t RWLock::tryReadLock() {
+ return -pthread_rwlock_tryrdlock(&mRWLock);
+}
+inline status_t RWLock::writeLock() {
+ return -pthread_rwlock_wrlock(&mRWLock);
+}
+inline status_t RWLock::tryWriteLock() {
+ return -pthread_rwlock_trywrlock(&mRWLock);
+}
+inline void RWLock::unlock() {
+ pthread_rwlock_unlock(&mRWLock);
+}
+
+#endif // HAVE_PTHREADS
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_RWLOCK_H
diff --git a/include/utils/Thread.h b/include/utils/Thread.h
new file mode 100644
index 000000000000..4a34abd78813
--- /dev/null
+++ b/include/utils/Thread.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_THREAD_H
+#define _LIBS_UTILS_THREAD_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Condition.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+#include <utils/ThreadDefs.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Thread : virtual public RefBase
+{
+public:
+ // Create a Thread object, but doesn't create or start the associated
+ // thread. See the run() method.
+ Thread(bool canCallJava = true);
+ virtual ~Thread();
+
+ // Start the thread in threadLoop() which needs to be implemented.
+ virtual status_t run( const char* name = 0,
+ int32_t priority = PRIORITY_DEFAULT,
+ size_t stack = 0);
+
+ // Ask this object's thread to exit. This function is asynchronous, when the
+ // function returns the thread might still be running. Of course, this
+ // function can be called from a different thread.
+ virtual void requestExit();
+
+ // Good place to do one-time initializations
+ virtual status_t readyToRun();
+
+ // Call requestExit() and wait until this object's thread exits.
+ // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
+ // this function from this object's thread. Will return WOULD_BLOCK in
+ // that case.
+ status_t requestExitAndWait();
+
+ // Wait until this object's thread exits. Returns immediately if not yet running.
+ // Do not call from this object's thread; will return WOULD_BLOCK in that case.
+ status_t join();
+
+#ifdef HAVE_ANDROID_OS
+ // Return the thread's kernel ID, same as the thread itself calling gettid() or
+ // androidGetTid(), or -1 if the thread is not running.
+ pid_t getTid() const;
+#endif
+
+protected:
+ // exitPending() returns true if requestExit() has been called.
+ bool exitPending() const;
+
+private:
+ // Derived class must implement threadLoop(). The thread starts its life
+ // here. There are two ways of using the Thread object:
+ // 1) loop: if threadLoop() returns true, it will be called again if
+ // requestExit() wasn't called.
+ // 2) once: if threadLoop() returns false, the thread will exit upon return.
+ virtual bool threadLoop() = 0;
+
+private:
+ Thread& operator=(const Thread&);
+ static int _threadLoop(void* user);
+ const bool mCanCallJava;
+ // always hold mLock when reading or writing
+ thread_id_t mThread;
+ mutable Mutex mLock;
+ Condition mThreadExitedCondition;
+ status_t mStatus;
+ // note that all accesses of mExitPending and mRunning need to hold mLock
+ volatile bool mExitPending;
+ volatile bool mRunning;
+ sp<Thread> mHoldSelf;
+#ifdef HAVE_ANDROID_OS
+ // legacy for debugging, not used by getTid() as it is set by the child thread
+ // and so is not initialized until the child reaches that point
+ pid_t mTid;
+#endif
+};
+
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+#endif // _LIBS_UTILS_THREAD_H
+// ---------------------------------------------------------------------------
diff --git a/include/utils/ThreadDefs.h b/include/utils/ThreadDefs.h
new file mode 100644
index 000000000000..3e563734ec66
--- /dev/null
+++ b/include/utils/ThreadDefs.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_THREAD_DEFS_H
+#define _LIBS_UTILS_THREAD_DEFS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <system/graphics.h>
+
+// ---------------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* android_thread_id_t;
+
+typedef int (*android_thread_func_t)(void*);
+
+enum {
+ /*
+ * ***********************************************
+ * ** Keep in sync with android.os.Process.java **
+ * ***********************************************
+ *
+ * This maps directly to the "nice" priorities we use in Android.
+ * A thread priority should be chosen inverse-proportionally to
+ * the amount of work the thread is expected to do. The more work
+ * a thread will do, the less favorable priority it should get so that
+ * it doesn't starve the system. Threads not behaving properly might
+ * be "punished" by the kernel.
+ * Use the levels below when appropriate. Intermediate values are
+ * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
+ */
+ ANDROID_PRIORITY_LOWEST = 19,
+
+ /* use for background tasks */
+ ANDROID_PRIORITY_BACKGROUND = 10,
+
+ /* most threads run at normal priority */
+ ANDROID_PRIORITY_NORMAL = 0,
+
+ /* threads currently running a UI that the user is interacting with */
+ ANDROID_PRIORITY_FOREGROUND = -2,
+
+ /* the main UI thread has a slightly more favorable priority */
+ ANDROID_PRIORITY_DISPLAY = -4,
+
+ /* ui service treads might want to run at a urgent display (uncommon) */
+ ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY,
+
+ /* all normal audio threads */
+ ANDROID_PRIORITY_AUDIO = -16,
+
+ /* service audio threads (uncommon) */
+ ANDROID_PRIORITY_URGENT_AUDIO = -19,
+
+ /* should never be used in practice. regular process might not
+ * be allowed to use this level */
+ ANDROID_PRIORITY_HIGHEST = -20,
+
+ ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL,
+ ANDROID_PRIORITY_MORE_FAVORABLE = -1,
+ ANDROID_PRIORITY_LESS_FAVORABLE = +1,
+};
+
+enum {
+ ANDROID_TGROUP_DEFAULT = 0,
+ ANDROID_TGROUP_BG_NONINTERACT = 1,
+ ANDROID_TGROUP_FG_BOOST = 2,
+ ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST,
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------------------------------------------------------------------
+// C++ API
+#ifdef __cplusplus
+namespace android {
+// ---------------------------------------------------------------------------
+
+typedef android_thread_id_t thread_id_t;
+typedef android_thread_func_t thread_func_t;
+
+enum {
+ PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST,
+ PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND,
+ PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL,
+ PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND,
+ PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY,
+ PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
+ PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO,
+ PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO,
+ PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST,
+ PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT,
+ PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
+ PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+#endif // __cplusplus
+// ---------------------------------------------------------------------------
+
+
+#endif // _LIBS_UTILS_THREAD_DEFS_H
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
new file mode 100644
index 000000000000..f33ddf652d40
--- /dev/null
+++ b/include/utils/Trace.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TRACE_H
+#define ANDROID_TRACE_H
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cutils/compiler.h>
+#include <utils/threads.h>
+
+// The ATRACE_TAG macro can be defined before including this header to trace
+// using one of the tags defined below. It must be defined to one of the
+// following ATRACE_TAG_* macros. The trace tag is used to filter tracing in
+// userland to avoid some of the runtime cost of tracing when it is not desired.
+//
+// Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always
+// being enabled - this should ONLY be done for debug code, as userland tracing
+// has a performance cost even when the trace is not being recorded. Defining
+// ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result
+// in the tracing always being disabled.
+#define ATRACE_TAG_NEVER 0 // The "never" tag is never enabled.
+#define ATRACE_TAG_ALWAYS (1<<0) // The "always" tag is always enabled.
+#define ATRACE_TAG_GRAPHICS (1<<1)
+#define ATRACE_TAG_LAST (1<<1)
+
+#define ATRACE_TAG_INVALID (~((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST))
+
+#ifndef ATRACE_TAG
+#define ATRACE_TAG ATRACE_TAG_NEVER
+#elif ATRACE_TAG > ATRACE_TAG_LAST
+#error ATRACE_TAG must be defined to be one of the tags defined in utils/Trace.h
+#endif
+
+// ATRACE_CALL traces the beginning and end of the current function. To trace
+// the correct start and end times this macro should be the first line of the
+// function body.
+#define ATRACE_CALL() android::ScopedTrace ___tracer(ATRACE_TAG, __FUNCTION__)
+
+// ATRACE_INT traces a named integer value. This can be used to track how the
+// value changes over time in a trace.
+#define ATRACE_INT(name, value) android::Tracer::traceCounter(ATRACE_TAG, name, value)
+
+namespace android {
+
+class Tracer {
+
+public:
+
+ static inline void traceCounter(uint64_t tag, const char* name,
+ int32_t value) {
+ if (!android_atomic_acquire_load(&sIsReady)) {
+ init();
+ }
+ int traceFD = sTraceFD;
+ if (CC_UNLIKELY(tagEnabled(tag) && traceFD != -1)) {
+ char buf[1024];
+ snprintf(buf, 1024, "C|%d|%s|%d", getpid(), name, value);
+ write(traceFD, buf, strlen(buf));
+ }
+ }
+
+ static inline void traceBegin(uint64_t tag, const char* name) {
+ if (CC_UNLIKELY(!android_atomic_acquire_load(&sIsReady))) {
+ init();
+ }
+ int traceFD = sTraceFD;
+ if (CC_UNLIKELY(tagEnabled(tag) && (traceFD != -1))) {
+ char buf[1024];
+ size_t len = snprintf(buf, 1024, "B|%d|%s", getpid(), name);
+ write(traceFD, buf, len);
+ }
+ }
+
+ static inline void traceEnd(uint64_t tag) {
+ if (CC_UNLIKELY(!android_atomic_acquire_load(&sIsReady))) {
+ init();
+ }
+ int traceFD = sTraceFD;
+ if (CC_UNLIKELY(tagEnabled(tag) && (traceFD != -1))) {
+ char buf = 'E';
+ write(traceFD, &buf, 1);
+ }
+ }
+
+private:
+
+ static inline bool tagEnabled(uint64_t tag) {
+ return !(tag & ATRACE_TAG_INVALID) && (tag & sEnabledTags);
+ }
+
+ // init opens the trace marker file for writing and reads the
+ // atrace.tags.enableflags system property. It does this only the first
+ // time it is run, using sMutex for synchronization.
+ static void init();
+
+ // sIsReady is a boolean value indicating whether a call to init() has
+ // completed in this process. It is initialized to 0 and set to 1 when the
+ // first init() call completes. It is set to 1 even if a failure occurred
+ // in init (e.g. the trace marker file couldn't be opened).
+ //
+ // This should be checked by all tracing functions using an atomic acquire
+ // load operation before calling init(). This check avoids the need to lock
+ // a mutex each time a trace function gets called.
+ static volatile int32_t sIsReady;
+
+ // sTraceFD is the file descriptor used to write to the kernel's trace
+ // buffer. It is initialized to -1 and set to an open file descriptor in
+ // init() while a lock on sMutex is held.
+ //
+ // This should only be used by a trace function after init() has
+ // successfully completed.
+ static int sTraceFD;
+
+ // sEnabledTags is the set of tag bits for which tracing is currently
+ // enabled. It is initialized to 0 and set based on the
+ // atrace.tags.enableflags system property in init() while a lock on sMutex
+ // is held.
+ //
+ // This should only be used by a trace function after init() has
+ // successfully completed.
+ static uint64_t sEnabledTags;
+
+ // sMutex is used to protect the execution of init().
+ static Mutex sMutex;
+};
+
+class ScopedTrace {
+
+public:
+ inline ScopedTrace(uint64_t tag, const char* name) :
+ mTag(tag) {
+ Tracer::traceBegin(mTag, name);
+ }
+
+ inline ~ScopedTrace() {
+ Tracer::traceEnd(mTag);
+ }
+
+private:
+
+ uint64_t mTag;
+};
+
+}; // namespace android
+
+#endif // ANDROID_TRACE_H
diff --git a/include/utils/threads.h b/include/utils/threads.h
index b4a8b7c0e12b..9de338211869 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -17,556 +17,22 @@
#ifndef _LIBS_UTILS_THREADS_H
#define _LIBS_UTILS_THREADS_H
-#include <stdint.h>
-#include <sys/types.h>
-#include <time.h>
-#include <system/graphics.h>
-
-#if defined(HAVE_PTHREADS)
-# include <pthread.h>
-#endif
-
-// ------------------------------------------------------------------
-// C API
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void* android_thread_id_t;
-
-typedef int (*android_thread_func_t)(void*);
-
-enum {
- /*
- * ***********************************************
- * ** Keep in sync with android.os.Process.java **
- * ***********************************************
- *
- * This maps directly to the "nice" priorities we use in Android.
- * A thread priority should be chosen inverse-proportionally to
- * the amount of work the thread is expected to do. The more work
- * a thread will do, the less favorable priority it should get so that
- * it doesn't starve the system. Threads not behaving properly might
- * be "punished" by the kernel.
- * Use the levels below when appropriate. Intermediate values are
- * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
- */
- ANDROID_PRIORITY_LOWEST = 19,
-
- /* use for background tasks */
- ANDROID_PRIORITY_BACKGROUND = 10,
-
- /* most threads run at normal priority */
- ANDROID_PRIORITY_NORMAL = 0,
-
- /* threads currently running a UI that the user is interacting with */
- ANDROID_PRIORITY_FOREGROUND = -2,
-
- /* the main UI thread has a slightly more favorable priority */
- ANDROID_PRIORITY_DISPLAY = -4,
-
- /* ui service treads might want to run at a urgent display (uncommon) */
- ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY,
-
- /* all normal audio threads */
- ANDROID_PRIORITY_AUDIO = -16,
-
- /* service audio threads (uncommon) */
- ANDROID_PRIORITY_URGENT_AUDIO = -19,
-
- /* should never be used in practice. regular process might not
- * be allowed to use this level */
- ANDROID_PRIORITY_HIGHEST = -20,
-
- ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL,
- ANDROID_PRIORITY_MORE_FAVORABLE = -1,
- ANDROID_PRIORITY_LESS_FAVORABLE = +1,
-};
-
-enum {
- ANDROID_TGROUP_DEFAULT = 0,
- ANDROID_TGROUP_BG_NONINTERACT = 1,
- ANDROID_TGROUP_FG_BOOST = 2,
- ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST,
-};
-
-// Create and run a new thread.
-extern int androidCreateThread(android_thread_func_t, void *);
-
-// Create thread with lots of parameters
-extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId);
-
-// Get some sort of unique identifier for the current thread.
-extern android_thread_id_t androidGetThreadId();
-
-// Low-level thread creation -- never creates threads that can
-// interact with the Java VM.
-extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId);
-
-// Used by the Java Runtime to control how threads are created, so that
-// they can be proper and lovely Java threads.
-typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
- void *userData,
- const char* threadName,
- int32_t threadPriority,
- size_t threadStackSize,
- android_thread_id_t *threadId);
-
-extern void androidSetCreateThreadFunc(android_create_thread_fn func);
-
-// ------------------------------------------------------------------
-// Extra functions working with raw pids.
-
-// Get pid for the current thread.
-extern pid_t androidGetTid();
-
-// Change the scheduling group of a particular thread. The group
-// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if
-// grp is out of range, else another non-zero value with errno set if
-// the operation failed. Thread ID zero means current thread.
-extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
-
-// Change the priority AND scheduling group of a particular thread. The priority
-// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
-// if the priority set failed, else another value if just the group set failed;
-// in either case errno is set. Thread ID zero means current thread.
-extern int androidSetThreadPriority(pid_t tid, int prio);
-
-// Get the current priority of a particular thread. Returns one of the
-// ANDROID_PRIORITY constants or a negative result in case of error.
-extern int androidGetThreadPriority(pid_t tid);
-
-// Get the current scheduling group of a particular thread. Normally returns
-// one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT.
-// Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if
-// scheduling groups are disabled. Returns INVALID_OPERATION if unexpected error.
-// Thread ID zero means current thread.
-extern int androidGetThreadSchedulingGroup(pid_t tid);
-
-#ifdef __cplusplus
-}
-#endif
-
-// ------------------------------------------------------------------
-// C++ API
-
-#ifdef __cplusplus
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-typedef android_thread_id_t thread_id_t;
-
-typedef android_thread_func_t thread_func_t;
-
-enum {
- PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST,
- PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND,
- PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL,
- PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND,
- PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY,
- PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
- PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO,
- PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO,
- PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST,
- PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT,
- PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
- PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
-};
-
-// Create and run a new thread.
-inline bool createThread(thread_func_t f, void *a) {
- return androidCreateThread(f, a) ? true : false;
-}
-
-// Create thread with lots of parameters
-inline bool createThreadEtc(thread_func_t entryFunction,
- void *userData,
- const char* threadName = "android:unnamed_thread",
- int32_t threadPriority = PRIORITY_DEFAULT,
- size_t threadStackSize = 0,
- thread_id_t *threadId = 0)
-{
- return androidCreateThreadEtc(entryFunction, userData, threadName,
- threadPriority, threadStackSize, threadId) ? true : false;
-}
-
-// Get some sort of unique identifier for the current thread.
-inline thread_id_t getThreadId() {
- return androidGetThreadId();
-}
-
-/*****************************************************************************/
-
/*
- * Simple mutex class. The implementation is system-dependent.
+ * Please, DO NOT USE!
*
- * The mutex must be unlocked by the thread that locked it. They are not
- * recursive, i.e. the same thread can't lock it multiple times.
- */
-class Mutex {
-public:
- enum {
- PRIVATE = 0,
- SHARED = 1
- };
-
- Mutex();
- Mutex(const char* name);
- Mutex(int type, const char* name = NULL);
- ~Mutex();
-
- // lock or unlock the mutex
- status_t lock();
- void unlock();
-
- // lock if possible; returns 0 on success, error otherwise
- status_t tryLock();
-
- // Manages the mutex automatically. It'll be locked when Autolock is
- // constructed and released when Autolock goes out of scope.
- class Autolock {
- public:
- inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
- inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
- inline ~Autolock() { mLock.unlock(); }
- private:
- Mutex& mLock;
- };
-
-private:
- friend class Condition;
-
- // A mutex cannot be copied
- Mutex(const Mutex&);
- Mutex& operator = (const Mutex&);
-
-#if defined(HAVE_PTHREADS)
- pthread_mutex_t mMutex;
-#else
- void _init();
- void* mState;
-#endif
-};
-
-#if defined(HAVE_PTHREADS)
-
-inline Mutex::Mutex() {
- pthread_mutex_init(&mMutex, NULL);
-}
-inline Mutex::Mutex(const char* name) {
- pthread_mutex_init(&mMutex, NULL);
-}
-inline Mutex::Mutex(int type, const char* name) {
- if (type == SHARED) {
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
- pthread_mutex_init(&mMutex, &attr);
- pthread_mutexattr_destroy(&attr);
- } else {
- pthread_mutex_init(&mMutex, NULL);
- }
-}
-inline Mutex::~Mutex() {
- pthread_mutex_destroy(&mMutex);
-}
-inline status_t Mutex::lock() {
- return -pthread_mutex_lock(&mMutex);
-}
-inline void Mutex::unlock() {
- pthread_mutex_unlock(&mMutex);
-}
-inline status_t Mutex::tryLock() {
- return -pthread_mutex_trylock(&mMutex);
-}
-
-#endif // HAVE_PTHREADS
-
-/*
- * Automatic mutex. Declare one of these at the top of a function.
- * When the function returns, it will go out of scope, and release the
- * mutex.
- */
-
-typedef Mutex::Autolock AutoMutex;
-
-/*****************************************************************************/
-
-#if defined(HAVE_PTHREADS)
-
-/*
- * Simple mutex class. The implementation is system-dependent.
- *
- * The mutex must be unlocked by the thread that locked it. They are not
- * recursive, i.e. the same thread can't lock it multiple times.
- */
-class RWLock {
-public:
- enum {
- PRIVATE = 0,
- SHARED = 1
- };
-
- RWLock();
- RWLock(const char* name);
- RWLock(int type, const char* name = NULL);
- ~RWLock();
-
- status_t readLock();
- status_t tryReadLock();
- status_t writeLock();
- status_t tryWriteLock();
- void unlock();
-
- class AutoRLock {
- public:
- inline AutoRLock(RWLock& rwlock) : mLock(rwlock) { mLock.readLock(); }
- inline ~AutoRLock() { mLock.unlock(); }
- private:
- RWLock& mLock;
- };
-
- class AutoWLock {
- public:
- inline AutoWLock(RWLock& rwlock) : mLock(rwlock) { mLock.writeLock(); }
- inline ~AutoWLock() { mLock.unlock(); }
- private:
- RWLock& mLock;
- };
-
-private:
- // A RWLock cannot be copied
- RWLock(const RWLock&);
- RWLock& operator = (const RWLock&);
-
- pthread_rwlock_t mRWLock;
-};
-
-inline RWLock::RWLock() {
- pthread_rwlock_init(&mRWLock, NULL);
-}
-inline RWLock::RWLock(const char* name) {
- pthread_rwlock_init(&mRWLock, NULL);
-}
-inline RWLock::RWLock(int type, const char* name) {
- if (type == SHARED) {
- pthread_rwlockattr_t attr;
- pthread_rwlockattr_init(&attr);
- pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
- pthread_rwlock_init(&mRWLock, &attr);
- pthread_rwlockattr_destroy(&attr);
- } else {
- pthread_rwlock_init(&mRWLock, NULL);
- }
-}
-inline RWLock::~RWLock() {
- pthread_rwlock_destroy(&mRWLock);
-}
-inline status_t RWLock::readLock() {
- return -pthread_rwlock_rdlock(&mRWLock);
-}
-inline status_t RWLock::tryReadLock() {
- return -pthread_rwlock_tryrdlock(&mRWLock);
-}
-inline status_t RWLock::writeLock() {
- return -pthread_rwlock_wrlock(&mRWLock);
-}
-inline status_t RWLock::tryWriteLock() {
- return -pthread_rwlock_trywrlock(&mRWLock);
-}
-inline void RWLock::unlock() {
- pthread_rwlock_unlock(&mRWLock);
-}
-
-#endif // HAVE_PTHREADS
-
-/*****************************************************************************/
-
-/*
- * Condition variable class. The implementation is system-dependent.
+ * This file is here only for legacy reasons. Instead, include directly
+ * the headers you need below.
*
- * Condition variables are paired up with mutexes. Lock the mutex,
- * call wait(), then either re-wait() if things aren't quite what you want,
- * or unlock the mutex and continue. All threads calling wait() must
- * use the same mutex for a given Condition.
- */
-class Condition {
-public:
- enum {
- PRIVATE = 0,
- SHARED = 1
- };
-
- Condition();
- Condition(int type);
- ~Condition();
- // Wait on the condition variable. Lock the mutex before calling.
- status_t wait(Mutex& mutex);
- // same with relative timeout
- status_t waitRelative(Mutex& mutex, nsecs_t reltime);
- // Signal the condition variable, allowing one thread to continue.
- void signal();
- // Signal the condition variable, allowing all threads to continue.
- void broadcast();
-
-private:
-#if defined(HAVE_PTHREADS)
- pthread_cond_t mCond;
-#else
- void* mState;
-#endif
-};
-
-#if defined(HAVE_PTHREADS)
-
-inline Condition::Condition() {
- pthread_cond_init(&mCond, NULL);
-}
-inline Condition::Condition(int type) {
- if (type == SHARED) {
- pthread_condattr_t attr;
- pthread_condattr_init(&attr);
- pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
- pthread_cond_init(&mCond, &attr);
- pthread_condattr_destroy(&attr);
- } else {
- pthread_cond_init(&mCond, NULL);
- }
-}
-inline Condition::~Condition() {
- pthread_cond_destroy(&mCond);
-}
-inline status_t Condition::wait(Mutex& mutex) {
- return -pthread_cond_wait(&mCond, &mutex.mMutex);
-}
-inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
-#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
- struct timespec ts;
- ts.tv_sec = reltime/1000000000;
- ts.tv_nsec = reltime%1000000000;
- return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
-#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
- struct timespec ts;
-#if defined(HAVE_POSIX_CLOCKS)
- clock_gettime(CLOCK_REALTIME, &ts);
-#else // HAVE_POSIX_CLOCKS
- // we don't support the clocks here.
- struct timeval t;
- gettimeofday(&t, NULL);
- ts.tv_sec = t.tv_sec;
- ts.tv_nsec= t.tv_usec*1000;
-#endif // HAVE_POSIX_CLOCKS
- ts.tv_sec += reltime/1000000000;
- ts.tv_nsec+= reltime%1000000000;
- if (ts.tv_nsec >= 1000000000) {
- ts.tv_nsec -= 1000000000;
- ts.tv_sec += 1;
- }
- return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
-#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
-}
-inline void Condition::signal() {
- pthread_cond_signal(&mCond);
-}
-inline void Condition::broadcast() {
- pthread_cond_broadcast(&mCond);
-}
-
-#endif // HAVE_PTHREADS
-
-/*****************************************************************************/
-
-/*
- * This is our spiffy thread object!
*/
-class Thread : virtual public RefBase
-{
-public:
- // Create a Thread object, but doesn't create or start the associated
- // thread. See the run() method.
- Thread(bool canCallJava = true);
- virtual ~Thread();
+#include <utils/AndroidThreads.h>
- // Start the thread in threadLoop() which needs to be implemented.
- virtual status_t run( const char* name = 0,
- int32_t priority = PRIORITY_DEFAULT,
- size_t stack = 0);
-
- // Ask this object's thread to exit. This function is asynchronous, when the
- // function returns the thread might still be running. Of course, this
- // function can be called from a different thread.
- virtual void requestExit();
-
- // Good place to do one-time initializations
- virtual status_t readyToRun();
-
- // Call requestExit() and wait until this object's thread exits.
- // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
- // this function from this object's thread. Will return WOULD_BLOCK in
- // that case.
- status_t requestExitAndWait();
-
- // Wait until this object's thread exits. Returns immediately if not yet running.
- // Do not call from this object's thread; will return WOULD_BLOCK in that case.
- status_t join();
-
-#ifdef HAVE_ANDROID_OS
- // Return the thread's kernel ID, same as the thread itself calling gettid() or
- // androidGetTid(), or -1 if the thread is not running.
- pid_t getTid() const;
-#endif
-
-protected:
- // exitPending() returns true if requestExit() has been called.
- bool exitPending() const;
-
-private:
- // Derived class must implement threadLoop(). The thread starts its life
- // here. There are two ways of using the Thread object:
- // 1) loop: if threadLoop() returns true, it will be called again if
- // requestExit() wasn't called.
- // 2) once: if threadLoop() returns false, the thread will exit upon return.
- virtual bool threadLoop() = 0;
-
-private:
- Thread& operator=(const Thread&);
- static int _threadLoop(void* user);
- const bool mCanCallJava;
- // always hold mLock when reading or writing
- thread_id_t mThread;
- mutable Mutex mLock;
- Condition mThreadExitedCondition;
- status_t mStatus;
- // note that all accesses of mExitPending and mRunning need to hold mLock
- volatile bool mExitPending;
- volatile bool mRunning;
- sp<Thread> mHoldSelf;
-#ifdef HAVE_ANDROID_OS
- // legacy for debugging, not used by getTid() as it is set by the child thread
- // and so is not initialized until the child reaches that point
- pid_t mTid;
+#ifdef __cplusplus
+#include <utils/Condition.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/RWLock.h>
+#include <utils/Thread.h>
#endif
-};
-
-
-}; // namespace android
-
-#endif // __cplusplus
#endif // _LIBS_UTILS_THREADS_H
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index c5f8a87659f1..4e89d87c0413 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -67,6 +67,7 @@ LOCAL_SRC_FILES:= \
$(commonSources) \
BackupData.cpp \
BackupHelpers.cpp \
+ CursorWindow.cpp \
InputTransport.cpp
LOCAL_SHARED_LIBRARIES := \
diff --git a/libs/binder/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
index a6e5f711da54..047a4c84457a 100644
--- a/libs/binder/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "CursorWindow"
#include <utils/Log.h>
-#include <binder/CursorWindow.h>
+#include <androidfw/CursorWindow.h>
#include <cutils/ashmem.h>
#include <sys/mman.h>
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 3a12e96c04a5..fd116b7aa5f3 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -16,7 +16,6 @@
sources := \
Binder.cpp \
BpBinder.cpp \
- CursorWindow.cpp \
IInterface.cpp \
IMemory.cpp \
IPCThreadState.cpp \
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index ee458f19fd25..d43cb0bb434f 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -27,7 +27,8 @@
#include <camera/ICameraRecordingProxyListener.h>
#include <camera/ICameraService.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
+#include <gui/Surface.h>
namespace android {
diff --git a/libs/camera/ICamera.cpp b/libs/camera/ICamera.cpp
index 70f5dbcf3f45..8d8408c815d2 100644
--- a/libs/camera/ICamera.cpp
+++ b/libs/camera/ICamera.cpp
@@ -22,6 +22,8 @@
#include <sys/types.h>
#include <binder/Parcel.h>
#include <camera/ICamera.h>
+#include <gui/ISurfaceTexture.h>
+#include <gui/Surface.h>
namespace android {
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 0791de2269ef..d76168023a62 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -15,6 +15,8 @@
*/
#define LOG_TAG "BufferQueue"
+//#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
@@ -23,10 +25,12 @@
#include <EGL/eglext.h>
#include <gui/BufferQueue.h>
+#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
-#include <surfaceflinger/ISurfaceComposer.h>
#include <utils/Log.h>
+#include <gui/SurfaceTexture.h>
+#include <utils/Trace.h>
// This compile option causes SurfaceTexture to return the buffer that is currently
// attached to the GL texture from dequeueBuffer when no other buffers are
@@ -34,6 +38,10 @@
// implicit cross-process synchronization to prevent the buffer from being
// written to before the buffer has (a) been detached from the GL texture and
// (b) all GL reads from the buffer have completed.
+
+// During refactoring, do not support dequeuing the current buffer
+#undef ALLOW_DEQUEUE_CURRENT_BUFFER
+
#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true
#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
@@ -42,11 +50,11 @@
#endif
// Macros for including the BufferQueue name in log messages
-#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
namespace android {
@@ -63,17 +71,17 @@ BufferQueue::BufferQueue( bool allowSynchronousMode ) :
mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
mClientBufferCount(0),
mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
- mCurrentTexture(INVALID_BUFFER_SLOT),
mNextTransform(0),
mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mSynchronousMode(false),
mAllowSynchronousMode(allowSynchronousMode),
mConnectedApi(NO_CONNECTED_API),
mAbandoned(false),
- mFrameCounter(0)
+ mFrameCounter(0),
+ mBufferHasBeenQueued(false)
{
// Choose a name using the PID and a process-unique ID.
- mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+ mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
ST_LOGV("BufferQueue");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
@@ -119,6 +127,23 @@ status_t BufferQueue::setBufferCountServerLocked(int bufferCount) {
return OK;
}
+bool BufferQueue::isSynchronousMode() const {
+ Mutex::Autolock lock(mMutex);
+ return mSynchronousMode;
+}
+
+void BufferQueue::setConsumerName(const String8& name) {
+ Mutex::Autolock lock(mMutex);
+ mConsumerName = name;
+}
+
+void BufferQueue::setFrameAvailableListener(
+ const sp<FrameAvailableListener>& listener) {
+ ST_LOGV("setFrameAvailableListener");
+ Mutex::Autolock lock(mMutex);
+ mFrameAvailableListener = listener;
+}
+
status_t BufferQueue::setBufferCount(int bufferCount) {
ST_LOGV("setBufferCount: count=%d", bufferCount);
Mutex::Autolock lock(mMutex);
@@ -160,7 +185,7 @@ status_t BufferQueue::setBufferCount(int bufferCount) {
freeAllBuffersLocked();
mBufferCount = bufferCount;
mClientBufferCount = bufferCount;
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mBufferHasBeenQueued = false;
mQueue.clear();
mDequeueCondition.signal();
return OK;
@@ -168,6 +193,7 @@ status_t BufferQueue::setBufferCount(int bufferCount) {
int BufferQueue::query(int what, int* outValue)
{
+ ATRACE_CALL();
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
@@ -198,6 +224,7 @@ int BufferQueue::query(int what, int* outValue)
}
status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
+ ATRACE_CALL();
ST_LOGV("requestBuffer: slot=%d", slot);
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
@@ -216,6 +243,7 @@ status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
+ ATRACE_CALL();
ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
if ((w && !h) || (!w && h)) {
@@ -276,7 +304,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
mBufferCount = mServerBufferCount;
if (mBufferCount < minBufferCountNeeded)
mBufferCount = minBufferCountNeeded;
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mBufferHasBeenQueued = false;
returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
}
@@ -290,19 +318,12 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
dequeuedCount++;
}
- // if buffer is FREE it CANNOT be current
- ALOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
- "dequeueBuffer: buffer %d is both FREE and current!",
- i);
-
- if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
- if (state == BufferSlot::FREE || i == mCurrentTexture) {
- foundSync = i;
- if (i != mCurrentTexture) {
- found = i;
- break;
- }
- }
+ // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER)
+ // but dequeuing the current buffer is disabled.
+ if (false) {
+ // This functionality has been temporarily removed so
+ // BufferQueue and SurfaceTexture can be refactored into
+ // separate objects
} else {
if (state == BufferSlot::FREE) {
/* We return the oldest of the free buffers to avoid
@@ -331,8 +352,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
// See whether a buffer has been queued since the last
// setBufferCount so we know whether to perform the
// MIN_UNDEQUEUED_BUFFERS check below.
- bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
- if (bufferHasBeenQueued) {
+ if (mBufferHasBeenQueued) {
// make sure the client is not trying to dequeue more buffers
// than allowed.
const int avail = mBufferCount - (dequeuedCount+1);
@@ -404,27 +424,23 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
if (updateFormat) {
mPixelFormat = format;
}
+
+ mSlots[buf].mAcquireCalled = false;
mSlots[buf].mGraphicBuffer = graphicBuffer;
mSlots[buf].mRequestBufferCalled = false;
mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mSlots[buf].mEglDisplay,
- mSlots[buf].mEglImage);
- mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
- mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
- }
- if (mCurrentTexture == buf) {
- // The current texture no longer references the buffer in this slot
- // since we just allocated a new buffer.
- mCurrentTexture = INVALID_BUFFER_SLOT;
- }
+ mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+
+
+
+
returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
}
dpy = mSlots[buf].mEglDisplay;
fence = mSlots[buf].mFence;
mSlots[buf].mFence = EGL_NO_SYNC_KHR;
- }
+ } // end lock scope
if (fence != EGL_NO_SYNC_KHR) {
EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
@@ -437,6 +453,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
ALOGE("dequeueBuffer: timeout waiting for fence");
}
eglDestroySyncKHR(dpy, fence);
+
}
ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
@@ -446,6 +463,7 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
}
status_t BufferQueue::setSynchronousMode(bool enabled) {
+ ATRACE_CALL();
ST_LOGV("setSynchronousMode: enabled=%d", enabled);
Mutex::Autolock lock(mMutex);
@@ -478,6 +496,7 @@ status_t BufferQueue::setSynchronousMode(bool enabled) {
status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+ ATRACE_CALL();
ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp);
sp<FrameAvailableListener> listener;
@@ -496,9 +515,6 @@ status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
ST_LOGE("queueBuffer: slot %d is not owned by the client "
"(state=%d)", buf, mSlots[buf].mBufferState);
return -EINVAL;
- } else if (buf == mCurrentTexture) {
- ST_LOGE("queueBuffer: slot %d is current!", buf);
- return -EINVAL;
} else if (!mSlots[buf].mRequestBufferCalled) {
ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
"buffer", buf);
@@ -538,11 +554,14 @@ status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
mFrameCounter++;
mSlots[buf].mFrameNumber = mFrameCounter;
+ mBufferHasBeenQueued = true;
mDequeueCondition.signal();
*outWidth = mDefaultWidth;
*outHeight = mDefaultHeight;
*outTransform = 0;
+
+ ATRACE_INT(mConsumerName.string(), mQueue.size());
} // scope for the lock
// call back without lock held
@@ -553,6 +572,7 @@ status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
}
void BufferQueue::cancelBuffer(int buf) {
+ ATRACE_CALL();
ST_LOGV("cancelBuffer: slot=%d", buf);
Mutex::Autolock lock(mMutex);
@@ -576,6 +596,7 @@ void BufferQueue::cancelBuffer(int buf) {
}
status_t BufferQueue::setCrop(const Rect& crop) {
+ ATRACE_CALL();
ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right,
crop.bottom);
@@ -589,6 +610,7 @@ status_t BufferQueue::setCrop(const Rect& crop) {
}
status_t BufferQueue::setTransform(uint32_t transform) {
+ ATRACE_CALL();
ST_LOGV("setTransform: xform=%#x", transform);
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
@@ -600,6 +622,7 @@ status_t BufferQueue::setTransform(uint32_t transform) {
}
status_t BufferQueue::setScalingMode(int mode) {
+ ATRACE_CALL();
ST_LOGV("setScalingMode: mode=%d", mode);
switch (mode) {
@@ -618,6 +641,7 @@ status_t BufferQueue::setScalingMode(int mode) {
status_t BufferQueue::connect(int api,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+ ATRACE_CALL();
ST_LOGV("connect: api=%d", api);
Mutex::Autolock lock(mMutex);
@@ -647,10 +671,14 @@ status_t BufferQueue::connect(int api,
err = -EINVAL;
break;
}
+
+ mBufferHasBeenQueued = false;
+
return err;
}
status_t BufferQueue::disconnect(int api) {
+ ATRACE_CALL();
ST_LOGV("disconnect: api=%d", api);
Mutex::Autolock lock(mMutex);
@@ -687,26 +715,188 @@ status_t BufferQueue::disconnect(int api) {
return err;
}
+void BufferQueue::dump(String8& result) const
+{
+ char buffer[1024];
+ BufferQueue::dump(result, "", buffer, 1024);
+}
+
+void BufferQueue::dump(String8& result, const char* prefix,
+ char* buffer, size_t SIZE) const
+{
+ Mutex::Autolock _l(mMutex);
+ snprintf(buffer, SIZE,
+ "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x}\n"
+ ,prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
+ mNextCrop.bottom, mNextTransform
+ );
+ result.append(buffer);
+
+ String8 fifo;
+ int fifoSize = 0;
+ Fifo::const_iterator i(mQueue.begin());
+ while (i != mQueue.end()) {
+ snprintf(buffer, SIZE, "%02d ", *i++);
+ fifoSize++;
+ fifo.append(buffer);
+ }
+
+ snprintf(buffer, SIZE,
+ "%s-BufferQueue mBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
+ "mPixelFormat=%d, FIFO(%d)={%s}\n",
+ prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
+ mDefaultHeight, mPixelFormat, fifoSize, fifo.string());
+ result.append(buffer);
+
+
+ struct {
+ const char * operator()(int state) const {
+ switch (state) {
+ case BufferSlot::DEQUEUED: return "DEQUEUED";
+ case BufferSlot::QUEUED: return "QUEUED";
+ case BufferSlot::FREE: return "FREE";
+ case BufferSlot::ACQUIRED: return "ACQUIRED";
+ default: return "Unknown";
+ }
+ }
+ } stateName;
+
+ for (int i=0 ; i<mBufferCount ; i++) {
+ const BufferSlot& slot(mSlots[i]);
+ snprintf(buffer, SIZE,
+ "%s%s[%02d] "
+ "state=%-8s, crop=[%d,%d,%d,%d], "
+ "transform=0x%02x, timestamp=%lld",
+ prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
+ stateName(slot.mBufferState),
+ slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
+ slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
+ );
+ result.append(buffer);
+
+ const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
+ if (buf != NULL) {
+ snprintf(buffer, SIZE,
+ ", %p [%4ux%4u:%4u,%3X]",
+ buf->handle, buf->width, buf->height, buf->stride,
+ buf->format);
+ result.append(buffer);
+ }
+ result.append("\n");
+ }
+}
+
void BufferQueue::freeBufferLocked(int i) {
mSlots[i].mGraphicBuffer = 0;
mSlots[i].mBufferState = BufferSlot::FREE;
mSlots[i].mFrameNumber = 0;
- if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
- mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
- mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+ mSlots[i].mAcquireCalled = false;
+
+ // destroy fence as BufferQueue now takes ownership
+ if (mSlots[i].mFence != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence);
+ mSlots[i].mFence = EGL_NO_SYNC_KHR;
}
}
void BufferQueue::freeAllBuffersLocked() {
ALOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersLocked called but mQueue is not empty");
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mQueue.clear();
+ mBufferHasBeenQueued = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
freeBufferLocked(i);
}
}
+status_t BufferQueue::acquire(BufferItem *buffer) {
+ Mutex::Autolock _l(mMutex);
+ // check if queue is empty
+ // In asynchronous mode the list is guaranteed to be one buffer
+ // deep, while in synchronous mode we use the oldest buffer.
+ if (!mQueue.empty()) {
+ Fifo::iterator front(mQueue.begin());
+ int buf = *front;
+
+ if (mSlots[buf].mAcquireCalled) {
+ buffer->mGraphicBuffer = NULL;
+ }
+ else {
+ buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
+ }
+ buffer->mCrop = mSlots[buf].mCrop;
+ buffer->mTransform = mSlots[buf].mTransform;
+ buffer->mScalingMode = mSlots[buf].mScalingMode;
+ buffer->mFrameNumber = mSlots[buf].mFrameNumber;
+ buffer->mBuf = buf;
+ mSlots[buf].mAcquireCalled = true;
+
+ mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
+ mQueue.erase(front);
+
+ ATRACE_INT(mConsumerName.string(), mQueue.size());
+ }
+ else {
+ return -EINVAL; //should be a better return code
+ }
+
+ return OK;
+}
+
+status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
+ EGLSyncKHR fence) {
+ Mutex::Autolock _l(mMutex);
+
+ if (buf == INVALID_BUFFER_SLOT) {
+ return -EINVAL;
+ }
+
+ mSlots[buf].mEglDisplay = display;
+ mSlots[buf].mFence = fence;
+
+ // The current buffer becomes FREE if it was still in the queued
+ // state. If it has already been given to the client
+ // (synchronous mode), then it stays in DEQUEUED state.
+ if (mSlots[buf].mBufferState == BufferSlot::QUEUED
+ || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
+ mSlots[buf].mBufferState = BufferSlot::FREE;
+ }
+ mDequeueCondition.signal();
+
+ return OK;
+}
+
+status_t BufferQueue::consumerDisconnect() {
+ Mutex::Autolock lock(mMutex);
+ // Once the SurfaceTexture disconnects, the BufferQueue
+ // is considered abandoned
+ mAbandoned = true;
+ freeAllBuffersLocked();
+ mDequeueCondition.signal();
+ return OK;
+}
+
+status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
+{
+ ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
+ if (!w || !h) {
+ ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
+ w, h);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+ mDefaultWidth = w;
+ mDefaultHeight = h;
+ return OK;
+}
+
+status_t BufferQueue::setBufferCountServer(int bufferCount) {
+ ATRACE_CALL();
+ Mutex::Autolock lock(mMutex);
+ return setBufferCountServerLocked(bufferCount);
+}
+
void BufferQueue::freeAllBuffersExceptHeadLocked() {
ALOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
@@ -715,7 +905,7 @@ void BufferQueue::freeAllBuffersExceptHeadLocked() {
Fifo::iterator front(mQueue.begin());
head = *front;
}
- mCurrentTexture = INVALID_BUFFER_SLOT;
+ mBufferHasBeenQueued = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (i != head) {
freeBufferLocked(i);
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index 6a4763d5a72b..a6790ad072c4 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -21,11 +21,10 @@
#include <gui/BitTube.h>
#include <gui/DisplayEventReceiver.h>
#include <gui/IDisplayEventConnection.h>
+#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 30f8d003c850..a70a5e8ad499 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -24,7 +24,7 @@
#include <ui/GraphicBuffer.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <gui/IGraphicBufferAlloc.h>
// ---------------------------------------------------------------------------
diff --git a/libs/gui/ISurface.cpp b/libs/gui/ISurface.cpp
index 96155d7458b1..c2ea18307723 100644
--- a/libs/gui/ISurface.cpp
+++ b/libs/gui/ISurface.cpp
@@ -22,8 +22,8 @@
#include <binder/Parcel.h>
+#include <gui/ISurface.h>
#include <gui/ISurfaceTexture.h>
-#include <surfaceflinger/ISurface.h>
namespace android {
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 95b23793440d..1f1794cbe41b 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -25,16 +25,14 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <private/surfaceflinger/LayerState.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-
#include <gui/BitTube.h>
#include <gui/IDisplayEventConnection.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceTexture.h>
-#include <ui/DisplayInfo.h>
+#include <private/gui/LayerState.h>
-#include <gui/ISurfaceTexture.h>
+#include <ui/DisplayInfo.h>
#include <utils/Log.h>
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 8fe96b182ebf..ca9ed5b545d0 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -29,9 +29,9 @@
#include <ui/Point.h>
#include <ui/Rect.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <private/surfaceflinger/LayerState.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <private/gui/LayerState.h>
// ---------------------------------------------------------------------------
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 87901e87f706..224c30587c21 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -16,8 +16,8 @@
#include <utils/Errors.h>
#include <binder/Parcel.h>
-#include <private/surfaceflinger/LayerState.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <private/gui/LayerState.h>
namespace android {
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 337950c3e6ee..72b27edaaada 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -28,16 +28,15 @@
#include <binder/IPCThreadState.h>
-#include <gui/SurfaceTextureClient.h>
-
#include <ui/DisplayInfo.h>
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
namespace android {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 699438c0d717..ceb1ba6d8999 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -31,15 +31,14 @@
#include <ui/DisplayInfo.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
-#include <private/surfaceflinger/LayerState.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
+#include <private/gui/LayerState.h>
+#include <private/gui/SharedBufferStack.h>
namespace android {
// ---------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index a7bfc613aa25..b42aa34d7652 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "SurfaceTexture"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
#define GL_GLEXT_PROTOTYPES
@@ -25,18 +26,18 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <gui/SurfaceTexture.h>
-
#include <hardware/hardware.h>
-#include <private/gui/ComposerService.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceTexture.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <private/gui/ComposerService.h>
#include <utils/Log.h>
#include <utils/String8.h>
+#include <utils/Trace.h>
// This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension
// to synchronize access to the buffers. It will cause dequeueBuffer to stall,
@@ -97,6 +98,11 @@ static float mtxRot270[16] = {
static void mtxMul(float out[16], const float a[16], const float b[16]);
+// Get an ID that's unique within this process.
+static int32_t createProcessUniqueId() {
+ static volatile int32_t globalCounter = 0;
+ return android_atomic_inc(&globalCounter);
+}
SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
GLenum texTarget, bool useFenceSync) :
@@ -109,8 +115,13 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
#else
mUseFenceSync(false),
#endif
- mTexTarget(texTarget)
+ mTexTarget(texTarget),
+ mAbandoned(false),
+ mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT)
{
+ // Choose a name using the PID and a process-unique ID.
+ mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+ BufferQueue::setConsumerName(mName);
ST_LOGV("SurfaceTexture");
memcpy(mCurrentTransformMatrix, mtxIdentity,
@@ -119,31 +130,22 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
SurfaceTexture::~SurfaceTexture() {
ST_LOGV("~SurfaceTexture");
- freeAllBuffersLocked();
+ abandon();
}
status_t SurfaceTexture::setBufferCountServer(int bufferCount) {
Mutex::Autolock lock(mMutex);
- return setBufferCountServerLocked(bufferCount);
+ return BufferQueue::setBufferCountServer(bufferCount);
}
status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
{
- ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
- if (!w || !h) {
- ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
- w, h);
- return BAD_VALUE;
- }
-
- Mutex::Autolock lock(mMutex);
- mDefaultWidth = w;
- mDefaultHeight = h;
- return OK;
+ return BufferQueue::setDefaultBufferSize(w, h);
}
status_t SurfaceTexture::updateTexImage() {
+ ATRACE_CALL();
ST_LOGV("updateTexImage");
Mutex::Autolock lock(mMutex);
@@ -152,23 +154,35 @@ status_t SurfaceTexture::updateTexImage() {
return NO_INIT;
}
+ BufferItem item;
+
// In asynchronous mode the list is guaranteed to be one buffer
// deep, while in synchronous mode we use the oldest buffer.
- if (!mQueue.empty()) {
- Fifo::iterator front(mQueue.begin());
- int buf = *front;
+ if (acquire(&item) == NO_ERROR) {
+ int buf = item.mBuf;
+ // This buffer was newly allocated, so we need to clean up on our side
+ if (item.mGraphicBuffer != NULL) {
+ mEGLSlots[buf].mGraphicBuffer = 0;
+ if (mEGLSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mEGLSlots[buf].mEglDisplay,
+ mEGLSlots[buf].mEglImage);
+ mEGLSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
+ mEGLSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+ }
+ mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
+ }
// Update the GL texture object.
- EGLImageKHR image = mSlots[buf].mEglImage;
+ EGLImageKHR image = mEGLSlots[buf].mEglImage;
EGLDisplay dpy = eglGetCurrentDisplay();
if (image == EGL_NO_IMAGE_KHR) {
- if (mSlots[buf].mGraphicBuffer == 0) {
+ if (item.mGraphicBuffer == 0) {
ST_LOGE("buffer at slot %d is null", buf);
return BAD_VALUE;
}
- image = createImage(dpy, mSlots[buf].mGraphicBuffer);
- mSlots[buf].mEglImage = image;
- mSlots[buf].mEglDisplay = dpy;
+ image = createImage(dpy, item.mGraphicBuffer);
+ mEGLSlots[buf].mEglImage = image;
+ mEGLSlots[buf].mEglDisplay = dpy;
if (image == EGL_NO_IMAGE_KHR) {
// NOTE: if dpy was invalid, createImage() is guaranteed to
// fail. so we'd end up here.
@@ -191,6 +205,8 @@ status_t SurfaceTexture::updateTexImage() {
failed = true;
}
if (failed) {
+ releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
+ mEGLSlots[buf].mFence);
return -EINVAL;
}
@@ -201,40 +217,37 @@ status_t SurfaceTexture::updateTexImage() {
if (fence == EGL_NO_SYNC_KHR) {
ALOGE("updateTexImage: error creating fence: %#x",
eglGetError());
+ releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
+ mEGLSlots[buf].mFence);
return -EINVAL;
}
glFlush();
- mSlots[mCurrentTexture].mFence = fence;
+ mEGLSlots[mCurrentTexture].mFence = fence;
}
}
ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)",
mCurrentTexture,
mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0,
- buf, mSlots[buf].mGraphicBuffer->handle);
+ buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0);
- if (mCurrentTexture != INVALID_BUFFER_SLOT) {
- // The current buffer becomes FREE if it was still in the queued
- // state. If it has already been given to the client
- // (synchronous mode), then it stays in DEQUEUED state.
- if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED) {
- mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE;
- }
- }
+ // release old buffer
+ releaseBuffer(mCurrentTexture,
+ mEGLSlots[mCurrentTexture].mEglDisplay,
+ mEGLSlots[mCurrentTexture].mFence);
// Update the SurfaceTexture state.
mCurrentTexture = buf;
- mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
- mCurrentCrop = mSlots[buf].mCrop;
- mCurrentTransform = mSlots[buf].mTransform;
- mCurrentScalingMode = mSlots[buf].mScalingMode;
- mCurrentTimestamp = mSlots[buf].mTimestamp;
+ mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer;
+ mCurrentCrop = item.mCrop;
+ mCurrentTransform = item.mTransform;
+ mCurrentScalingMode = item.mScalingMode;
+ mCurrentTimestamp = item.mTimestamp;
computeCurrentTransformMatrix();
// Now that we've passed the point at which failures can happen,
// it's safe to remove the buffer from the front of the queue.
- mQueue.erase(front);
- mDequeueCondition.signal();
+
} else {
// We always bind the texture even if we don't update its contents.
glBindTexture(mTexTarget, mTexName);
@@ -300,7 +313,7 @@ void SurfaceTexture::computeCurrentTransformMatrix() {
}
}
- sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
+ sp<GraphicBuffer>& buf(mCurrentTextureBuf);
float tx, ty, sx, sy;
if (!mCurrentCrop.isEmpty()) {
// In order to prevent bilinear sampling at the of the crop rectangle we
@@ -372,7 +385,7 @@ void SurfaceTexture::setFrameAvailableListener(
const sp<FrameAvailableListener>& listener) {
ST_LOGV("setFrameAvailableListener");
Mutex::Autolock lock(mMutex);
- mFrameAvailableListener = listener;
+ BufferQueue::setFrameAvailableListener(listener);
}
EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
@@ -413,22 +426,33 @@ uint32_t SurfaceTexture::getCurrentScalingMode() const {
bool SurfaceTexture::isSynchronousMode() const {
Mutex::Autolock lock(mMutex);
- return mSynchronousMode;
+ return BufferQueue::isSynchronousMode();
}
-
-
void SurfaceTexture::abandon() {
Mutex::Autolock lock(mMutex);
- mQueue.clear();
mAbandoned = true;
mCurrentTextureBuf.clear();
- freeAllBuffersLocked();
- mDequeueCondition.signal();
+
+ // destroy all egl buffers
+ for (int i =0; i < NUM_BUFFER_SLOTS; i++) {
+ mEGLSlots[i].mGraphicBuffer = 0;
+ if (mEGLSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mEGLSlots[i].mEglDisplay,
+ mEGLSlots[i].mEglImage);
+ mEGLSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
+ mEGLSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+ }
+ }
+
+ // disconnect from the BufferQueue
+ BufferQueue::consumerDisconnect();
}
void SurfaceTexture::setName(const String8& name) {
+ Mutex::Autolock _l(mMutex);
mName = name;
+ BufferQueue::setConsumerName(name);
}
void SurfaceTexture::dump(String8& result) const
@@ -441,68 +465,19 @@ void SurfaceTexture::dump(String8& result, const char* prefix,
char* buffer, size_t SIZE) const
{
Mutex::Autolock _l(mMutex);
- snprintf(buffer, SIZE,
- "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
- "mPixelFormat=%d, mTexName=%d\n",
- prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
- mDefaultHeight, mPixelFormat, mTexName);
+ snprintf(buffer, SIZE, "%smTexName=%d\n", prefix, mTexName);
result.append(buffer);
- String8 fifo;
- int fifoSize = 0;
- Fifo::const_iterator i(mQueue.begin());
- while (i != mQueue.end()) {
- snprintf(buffer, SIZE, "%02d ", *i++);
- fifoSize++;
- fifo.append(buffer);
- }
-
snprintf(buffer, SIZE,
- "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
- "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n"
- ,
- prefix, mCurrentCrop.left,
+ "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
+ ,prefix, mCurrentCrop.left,
mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
- mCurrentTransform, mCurrentTexture,
- prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
- mNextCrop.bottom, mNextTransform, fifoSize, fifo.string()
+ mCurrentTransform, mCurrentTexture
);
result.append(buffer);
- struct {
- const char * operator()(int state) const {
- switch (state) {
- case BufferSlot::DEQUEUED: return "DEQUEUED";
- case BufferSlot::QUEUED: return "QUEUED";
- case BufferSlot::FREE: return "FREE";
- default: return "Unknown";
- }
- }
- } stateName;
-
- for (int i=0 ; i<mBufferCount ; i++) {
- const BufferSlot& slot(mSlots[i]);
- snprintf(buffer, SIZE,
- "%s%s[%02d] "
- "state=%-8s, crop=[%d,%d,%d,%d], "
- "transform=0x%02x, timestamp=%lld",
- prefix, (i==mCurrentTexture)?">":" ", i,
- stateName(slot.mBufferState),
- slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
- slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
- );
- result.append(buffer);
-
- const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
- if (buf != NULL) {
- snprintf(buffer, SIZE,
- ", %p [%4ux%4u:%4u,%3X]",
- buf->handle, buf->width, buf->height, buf->stride,
- buf->format);
- result.append(buffer);
- }
- result.append("\n");
- }
+
+ BufferQueue::dump(result, prefix, buffer, SIZE);
}
static void mtxMul(float out[16], const float a[16], const float b[16]) {
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index d0934ba8aa73..f88dcaf02abe 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -15,13 +15,15 @@
*/
#define LOG_TAG "SurfaceTextureClient"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
-#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
#include <private/gui/ComposerService.h>
@@ -121,6 +123,7 @@ int SurfaceTextureClient::hook_perform(ANativeWindow* window, int operation, ...
}
int SurfaceTextureClient::setSwapInterval(int interval) {
+ ATRACE_CALL();
// EGL specification states:
// interval is silently clamped to minimum and maximum implementation
// dependent values before being stored.
@@ -138,6 +141,7 @@ int SurfaceTextureClient::setSwapInterval(int interval) {
}
int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::dequeueBuffer");
Mutex::Autolock lock(mMutex);
int buf = -1;
@@ -167,6 +171,7 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
}
int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::cancelBuffer");
Mutex::Autolock lock(mMutex);
int i = getSlotFromBufferLocked(buffer);
@@ -213,6 +218,7 @@ int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
}
int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::queueBuffer");
Mutex::Autolock lock(mMutex);
int64_t timestamp;
@@ -236,6 +242,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
}
int SurfaceTextureClient::query(int what, int* value) const {
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::query");
{ // scope for the lock
Mutex::Autolock lock(mMutex);
@@ -404,6 +411,7 @@ int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) {
int SurfaceTextureClient::connect(int api) {
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::connect");
Mutex::Autolock lock(mMutex);
int err = mSurfaceTexture->connect(api,
@@ -415,6 +423,7 @@ int SurfaceTextureClient::connect(int api) {
}
int SurfaceTextureClient::disconnect(int api) {
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::disconnect");
Mutex::Autolock lock(mMutex);
freeAllBuffers();
@@ -441,6 +450,7 @@ int SurfaceTextureClient::setUsage(uint32_t reqUsage)
int SurfaceTextureClient::setCrop(Rect const* rect)
{
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::setCrop");
Mutex::Autolock lock(mMutex);
@@ -459,6 +469,7 @@ int SurfaceTextureClient::setCrop(Rect const* rect)
int SurfaceTextureClient::setBufferCount(int bufferCount)
{
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::setBufferCount");
Mutex::Autolock lock(mMutex);
@@ -475,6 +486,7 @@ int SurfaceTextureClient::setBufferCount(int bufferCount)
int SurfaceTextureClient::setBuffersDimensions(int w, int h)
{
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::setBuffersDimensions");
Mutex::Autolock lock(mMutex);
@@ -508,6 +520,7 @@ int SurfaceTextureClient::setBuffersFormat(int format)
int SurfaceTextureClient::setScalingMode(int mode)
{
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
Mutex::Autolock lock(mMutex);
// mode is validated on the server
@@ -520,6 +533,7 @@ int SurfaceTextureClient::setScalingMode(int mode)
int SurfaceTextureClient::setBuffersTransform(int transform)
{
+ ATRACE_CALL();
ALOGV("SurfaceTextureClient::setBuffersTransform");
Mutex::Autolock lock(mMutex);
status_t err = mSurfaceTexture->setTransform(transform);
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index b18e7b057e54..8c6defec0cf0 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -24,9 +24,9 @@
#include <utils/String8.h>
#include <utils/threads.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ea527504b160..b585d68ded75 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -17,9 +17,9 @@
#include <gtest/gtest.h>
#include <binder/IMemory.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <utils/String8.h>
#include <private/gui/ComposerService.h>
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 16a3d73a121f..55a860ebc69b 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -30,7 +30,7 @@
#define DEBUG_MEMORY_USAGE 0
// Turn on to enable debugging of cache flushes
-#define DEBUG_CACHE_FLUSH 1
+#define DEBUG_CACHE_FLUSH 0
// Turn on to enable layers debugging when rendered as regions
#define DEBUG_LAYERS_AS_REGIONS 0
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f9088aca3718..815382362468 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -61,6 +61,7 @@ const char* DisplayList::OP_NAMES[] = {
"DrawLines",
"DrawPoints",
"DrawText",
+ "DrawTextOnPath",
"DrawPosText",
"ResetShader",
"SetupShader",
@@ -483,7 +484,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
break;
case DrawText: {
getText(&text);
- int count = getInt();
+ int32_t count = getInt();
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
@@ -492,6 +493,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
text.text(), text.length(), count, x, y, paint, length);
}
break;
+ case DrawTextOnPath: {
+ getText(&text);
+ int32_t count = getInt();
+ SkPath* path = getPath();
+ float hOffset = getFloat();
+ float vOffset = getFloat();
+ SkPaint* paint = getPaint(renderer);
+ ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+ text.text(), text.length(), count, paint);
+ }
+ break;
case DrawPosText: {
getText(&text);
int count = getInt();
@@ -890,6 +902,19 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, u
renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
}
break;
+ case DrawTextOnPath: {
+ getText(&text);
+ int32_t count = getInt();
+ SkPath* path = getPath();
+ float hOffset = getFloat();
+ float vOffset = getFloat();
+ SkPaint* paint = getPaint(renderer);
+ DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+ text.text(), text.length(), count, paint);
+ renderer.drawTextOnPath(text.text(), text.length(), count, path,
+ hOffset, vOffset, paint);
+ }
+ break;
case DrawPosText: {
getText(&text);
int32_t count = getInt();
@@ -1331,6 +1356,19 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
addSkip(location);
}
+void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+ SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
+ if (!text || count <= 0) return;
+ addOp(DisplayList::DrawTextOnPath);
+ addText(text, bytesCount);
+ addInt(count);
+ addPath(path);
+ addFloat(hOffset);
+ addFloat(vOffset);
+ paint->setAntiAlias(true);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
if (!text || count <= 0) return;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 90a714526623..5d1b46012d51 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -99,6 +99,7 @@ public:
DrawLines,
DrawPoints,
DrawText,
+ DrawTextOnPath,
DrawPosText,
ResetShader,
SetupShader,
@@ -310,6 +311,8 @@ public:
virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint, float length = 1.0f);
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ float hOffset, float vOffset, SkPaint* paint);
virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
SkPaint* paint);
@@ -462,6 +465,7 @@ private:
SkPath* pathCopy = mPathMap.valueFor(path);
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
pathCopy = new SkPath(*path);
+ pathCopy->setSourcePath(path);
// replaceValueFor() performs an add if the entry doesn't exist
mPathMap.replaceValueFor(path, pathCopy);
mPaths.add(pathCopy);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 55e2ca5d7f24..ebb6d88a0f77 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <SkCanvas.h>
+#include <SkPathMeasure.h>
#include <SkTypeface.h>
#include <utils/Log.h>
@@ -2292,6 +2293,76 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
}
+void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ float hOffset, float vOffset, SkPaint* paint) {
+ if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
+ (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
+ return;
+ }
+
+ float x = 0.0f;
+ float y = 0.0f;
+
+ const bool pureTranslate = mSnapshot->transform->isPureTranslate();
+ if (CC_LIKELY(pureTranslate)) {
+ x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
+ y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
+ }
+
+ FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
+ fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
+ paint->getTextSize());
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ mCaches.activeTexture(0);
+ setupDraw();
+ setupDrawDirtyRegionsDisabled();
+ setupDrawWithTexture(true);
+ setupDrawAlpha8Color(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(true, mode);
+ setupDrawProgram();
+ setupDrawModelView(x, y, x, y, pureTranslate, true);
+ setupDrawTexture(fontRenderer.getTexture(true));
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawShaderUniforms(pureTranslate);
+
+// mat4 pathTransform;
+// pathTransform.loadTranslate(hOffset, vOffset, 0.0f);
+//
+// float offset = 0.0f;
+// SkPathMeasure pathMeasure(*path, false);
+//
+// if (paint->getTextAlign() != SkPaint::kLeft_Align) {
+// SkScalar pathLength = pathMeasure.getLength();
+// if (paint->getTextAlign() == SkPaint::kCenter_Align) {
+// pathLength = SkScalarHalf(pathLength);
+// }
+// offset += SkScalarToFloat(pathLength);
+// }
+
+// SkScalar x;
+// SkPath tmp;
+// SkMatrix m(scaledMatrix);
+//
+// m.postTranslate(xpos + hOffset, 0);
+// if (matrix) {
+// m.postConcat(*matrix);
+// }
+// morphpath(&tmp, *iterPath, meas, m);
+// if (fDevice) {
+// fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true);
+// } else {
+// this->drawPath(tmp, iter.getPaint(), NULL, true);
+// }
+// }
+}
+
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 3f63c3fe11a1..4d7a4911e1e1 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -124,8 +124,10 @@ public:
virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint, float length = -1.0f);
- virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
- SkPaint* paint);
+ virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+ float hOffset, float vOffset, SkPaint* paint);
+ virtual void drawPosText(const char* text, int bytesCount, int count,
+ const float* positions, SkPaint* paint);
virtual void resetShader();
virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index e09c24381d9d..e363b73498df 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -83,6 +83,11 @@ void PathCache::clearGarbage() {
}
PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
+ const SkPath* sourcePath = path->getSourcePath();
+ if (sourcePath && sourcePath->getGenerationID() == path->getGenerationID()) {
+ path = const_cast<SkPath*>(sourcePath);
+ }
+
PathCacheEntry entry(path, paint);
PathTexture* texture = mCache.get(entry);
diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp
new file mode 100644
index 000000000000..d69c55ff2749
--- /dev/null
+++ b/libs/rs/Allocation.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#define LOG_TAG "libRS_cpp"
+
+#include <utils/Log.h>
+#include <malloc.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+#include "Allocation.h"
+
+
+void * Allocation::getIDSafe() const {
+ //if (mAdaptedAllocation != NULL) {
+ //return mAdaptedAllocation.getID();
+ //}
+ return getID();
+}
+
+void Allocation::updateCacheInfo(const Type *t) {
+ mCurrentDimX = t->getX();
+ mCurrentDimY = t->getY();
+ mCurrentDimZ = t->getZ();
+ mCurrentCount = mCurrentDimX;
+ if (mCurrentDimY > 1) {
+ mCurrentCount *= mCurrentDimY;
+ }
+ if (mCurrentDimZ > 1) {
+ mCurrentCount *= mCurrentDimZ;
+ }
+}
+
+Allocation::Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage) : BaseObj(id, rs) {
+ if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
+ RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
+ RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
+ RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
+ RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
+ RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+ RS_ALLOCATION_USAGE_IO_INPUT |
+ RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) {
+ ALOGE("Unknown usage specified.");
+ }
+
+ if ((usage & (RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+ RS_ALLOCATION_USAGE_IO_INPUT)) != 0) {
+ mWriteAllowed = false;
+ if ((usage & ~(RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+ RS_ALLOCATION_USAGE_IO_INPUT |
+ RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
+ RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
+ ALOGE("Invalid usage combination.");
+ }
+ }
+
+ mType = t;
+ mUsage = usage;
+
+ if (t != NULL) {
+ updateCacheInfo(t);
+ }
+}
+
+void Allocation::validateIsInt32() {
+ RsDataType dt = mType->getElement()->getDataType();
+ if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
+ return;
+ }
+ ALOGE("32 bit integer source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsInt16() {
+ RsDataType dt = mType->getElement()->getDataType();
+ if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) {
+ return;
+ }
+ ALOGE("16 bit integer source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsInt8() {
+ RsDataType dt = mType->getElement()->getDataType();
+ if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) {
+ return;
+ }
+ ALOGE("8 bit integer source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsFloat32() {
+ RsDataType dt = mType->getElement()->getDataType();
+ if (dt == RS_TYPE_FLOAT_32) {
+ return;
+ }
+ ALOGE("32 bit float source does not match allocation type %i", dt);
+}
+
+void Allocation::validateIsObject() {
+ RsDataType dt = mType->getElement()->getDataType();
+ if ((dt == RS_TYPE_ELEMENT) ||
+ (dt == RS_TYPE_TYPE) ||
+ (dt == RS_TYPE_ALLOCATION) ||
+ (dt == RS_TYPE_SAMPLER) ||
+ (dt == RS_TYPE_SCRIPT) ||
+ (dt == RS_TYPE_MESH) ||
+ (dt == RS_TYPE_PROGRAM_FRAGMENT) ||
+ (dt == RS_TYPE_PROGRAM_VERTEX) ||
+ (dt == RS_TYPE_PROGRAM_RASTER) ||
+ (dt == RS_TYPE_PROGRAM_STORE)) {
+ return;
+ }
+ ALOGE("Object source does not match allocation type %i", dt);
+}
+
+void Allocation::updateFromNative() {
+ BaseObj::updateFromNative();
+
+ const void *typeID = rsaAllocationGetType(mRS->mContext, getID());
+ if(typeID != NULL) {
+ const Type *old = mType;
+ Type *t = new Type((void *)typeID, mRS);
+ t->updateFromNative();
+ updateCacheInfo(t);
+ mType = t;
+ delete old;
+ }
+}
+
+void Allocation::syncAll(RsAllocationUsageType srcLocation) {
+ switch (srcLocation) {
+ case RS_ALLOCATION_USAGE_SCRIPT:
+ case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS:
+ case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE:
+ case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX:
+ break;
+ default:
+ ALOGE("Source must be exactly one usage type.");
+ }
+ rsAllocationSyncAll(mRS->mContext, getIDSafe(), srcLocation);
+}
+
+void Allocation::ioSendOutput() {
+ if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
+ ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
+ }
+ rsAllocationIoSend(mRS->mContext, getID());
+}
+
+void Allocation::ioGetInput() {
+ if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
+ ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
+ }
+ rsAllocationIoReceive(mRS->mContext, getID());
+}
+
+/*
+void copyFrom(BaseObj[] d) {
+ mRS.validate();
+ validateIsObject();
+ if (d.length != mCurrentCount) {
+ ALOGE("Array size mismatch, allocation sizeX = " +
+ mCurrentCount + ", array length = " + d.length);
+ }
+ int i[] = new int[d.length];
+ for (int ct=0; ct < d.length; ct++) {
+ i[ct] = d[ct].getID();
+ }
+ copy1DRangeFromUnchecked(0, mCurrentCount, i);
+}
+*/
+
+
+/*
+void Allocation::setFromFieldPacker(int xoff, FieldPacker fp) {
+ mRS.validate();
+ int eSize = mType.mElement.getSizeBytes();
+ final byte[] data = fp.getData();
+
+ int count = data.length / eSize;
+ if ((eSize * count) != data.length) {
+ ALOGE("Field packer length " + data.length +
+ " not divisible by element size " + eSize + ".");
+ }
+ copy1DRangeFromUnchecked(xoff, count, data);
+}
+
+void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
+ mRS.validate();
+ if (component_number >= mType.mElement.mElements.length) {
+ ALOGE("Component_number " + component_number + " out of range.");
+ }
+ if(xoff < 0) {
+ ALOGE("Offset must be >= 0.");
+ }
+
+ final byte[] data = fp.getData();
+ int eSize = mType.mElement.mElements[component_number].getSizeBytes();
+ eSize *= mType.mElement.mArraySizes[component_number];
+
+ if (data.length != eSize) {
+ ALOGE("Field packer sizelength " + data.length +
+ " does not match component size " + eSize + ".");
+ }
+
+ mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
+ component_number, data, data.length);
+}
+*/
+
+void Allocation::generateMipmaps() {
+ rsAllocationGenerateMipmaps(mRS->mContext, getID());
+}
+
+void Allocation::copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen) {
+ if(count < 1) {
+ ALOGE("Count must be >= 1.");
+ return;
+ }
+ if((off + count) > mCurrentCount) {
+ ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off);
+ return;
+ }
+ if((count * mType->getElement()->getSizeBytes()) > dataLen) {
+ ALOGE("Array too small for allocation type.");
+ return;
+ }
+
+ rsAllocation1DData(mRS->mContext, getIDSafe(), off, mSelectedLOD, count, data, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int32_t *d, size_t dataLen) {
+ validateIsInt32();
+ copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int16_t *d, size_t dataLen) {
+ validateIsInt16();
+ copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int8_t *d, size_t dataLen) {
+ validateIsInt8();
+ copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const float *d, size_t dataLen) {
+ validateIsFloat32();
+ copy1DRangeFromUnchecked(off, count, d, dataLen);
+}
+
+void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff) {
+ rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), off, 0,
+ mSelectedLOD, mSelectedFace,
+ count, 1, data->getIDSafe(), dataOff, 0,
+ data->mSelectedLOD, data->mSelectedFace);
+}
+
+void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) {
+ if (mAdaptedAllocation != NULL) {
+
+ } else {
+ if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
+ ALOGE("Updated region larger than allocation.");
+ }
+ }
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const int8_t *data, size_t dataLen) {
+ validate2DRange(xoff, yoff, w, h);
+ rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+ w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const int16_t *data, size_t dataLen) {
+ validate2DRange(xoff, yoff, w, h);
+ rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+ w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const int32_t *data, size_t dataLen) {
+ validate2DRange(xoff, yoff, w, h);
+ rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+ w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const float *data, size_t dataLen) {
+ validate2DRange(xoff, yoff, w, h);
+ rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+ w, h, data, dataLen);
+}
+
+void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const Allocation *data, size_t dataLen,
+ uint32_t dataXoff, uint32_t dataYoff) {
+ validate2DRange(xoff, yoff, w, h);
+ rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), xoff, yoff,
+ mSelectedLOD, mSelectedFace,
+ w, h, data->getIDSafe(), dataXoff, dataYoff,
+ data->mSelectedLOD, data->mSelectedFace);
+}
+
+/*
+void copyTo(byte[] d) {
+ validateIsInt8();
+ mRS.validate();
+ mRS.nAllocationRead(getID(), d);
+}
+
+void copyTo(short[] d) {
+ validateIsInt16();
+ mRS.validate();
+ mRS.nAllocationRead(getID(), d);
+}
+
+void copyTo(int[] d) {
+ validateIsInt32();
+ mRS.validate();
+ mRS.nAllocationRead(getID(), d);
+}
+
+void copyTo(float[] d) {
+ validateIsFloat32();
+ mRS.validate();
+ mRS.nAllocationRead(getID(), d);
+}
+
+void resize(int dimX) {
+ if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
+ throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
+ }
+ mRS.nAllocationResize1D(getID(), dimX);
+ mRS.finish(); // Necessary because resize is fifoed and update is async.
+
+ int typeID = mRS.nAllocationGetType(getID());
+ mType = new Type(typeID, mRS);
+ mType.updateFromNative();
+ updateCacheInfo(mType);
+}
+
+void resize(int dimX, int dimY) {
+ if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
+ throw new RSInvalidStateException(
+ "Resize only support for 2D allocations at this time.");
+ }
+ if (mType.getY() == 0) {
+ throw new RSInvalidStateException(
+ "Resize only support for 2D allocations at this time.");
+ }
+ mRS.nAllocationResize2D(getID(), dimX, dimY);
+ mRS.finish(); // Necessary because resize is fifoed and update is async.
+
+ int typeID = mRS.nAllocationGetType(getID());
+ mType = new Type(typeID, mRS);
+ mType.updateFromNative();
+ updateCacheInfo(mType);
+}
+*/
+
+
+Allocation *Allocation::createTyped(RenderScript *rs, const Type *type,
+ RsAllocationMipmapControl mips, uint32_t usage) {
+ void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, 0);
+ if (id == 0) {
+ ALOGE("Allocation creation failed.");
+ return NULL;
+ }
+ return new Allocation(id, rs, type, usage);
+}
+
+Allocation *Allocation::createTyped(RenderScript *rs, const Type *type,
+ RsAllocationMipmapControl mips, uint32_t usage, void *pointer) {
+ void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, (uint32_t)pointer);
+ if (id == 0) {
+ ALOGE("Allocation creation failed.");
+ }
+ return new Allocation(id, rs, type, usage);
+}
+
+Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, uint32_t usage) {
+ return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
+}
+
+Allocation *Allocation::createSized(RenderScript *rs, const Element *e, size_t count, uint32_t usage) {
+ Type::Builder b(rs, e);
+ b.setX(count);
+ const Type *t = b.create();
+
+ void *id = rsAllocationCreateTyped(rs->mContext, t->getID(), RS_ALLOCATION_MIPMAP_NONE, usage, 0);
+ if (id == 0) {
+ ALOGE("Allocation creation failed.");
+ }
+ return new Allocation(id, rs, t, usage);
+}
+
+
+/*
+SurfaceTexture getSurfaceTexture() {
+ if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) {
+ throw new RSInvalidStateException("Allocation is not a surface texture.");
+ }
+
+ int id = mRS.nAllocationGetSurfaceTextureID(getID());
+ return new SurfaceTexture(id);
+
+}
+
+void setSurfaceTexture(SurfaceTexture sur) {
+ if ((mUsage & USAGE_IO_OUTPUT) == 0) {
+ throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
+ }
+
+ mRS.validate();
+ mRS.nAllocationSetSurfaceTexture(getID(), sur);
+}
+
+
+static Allocation createFromBitmapResource(RenderScript rs,
+ Resources res,
+ int id,
+ MipmapControl mips,
+ int usage) {
+
+ rs.validate();
+ Bitmap b = BitmapFactory.decodeResource(res, id);
+ Allocation alloc = createFromBitmap(rs, b, mips, usage);
+ b.recycle();
+ return alloc;
+}
+
+static Allocation createFromBitmapResource(RenderScript rs,
+ Resources res,
+ int id) {
+ return createFromBitmapResource(rs, res, id,
+ MipmapControl.MIPMAP_NONE,
+ USAGE_GRAPHICS_TEXTURE);
+}
+
+static Allocation createFromString(RenderScript rs,
+ String str,
+ int usage) {
+ rs.validate();
+ byte[] allocArray = NULL;
+ try {
+ allocArray = str.getBytes("UTF-8");
+ Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
+ alloc.copyFrom(allocArray);
+ return alloc;
+ }
+ catch (Exception e) {
+ throw new RSRuntimeException("Could not convert string to utf-8.");
+ }
+}
+*/
+
diff --git a/libs/rs/Allocation.h b/libs/rs/Allocation.h
new file mode 100644
index 000000000000..c9e00a4b2446
--- /dev/null
+++ b/libs/rs/Allocation.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#ifndef __ANDROID_ALLOCATION_H__
+#define __ANDROID_ALLOCATION_H__
+
+#include <pthread.h>
+#include <rs.h>
+
+#include "RenderScript.h"
+#include "Type.h"
+#include "Element.h"
+
+class Allocation : public BaseObj {
+protected:
+ const Type *mType;
+ uint32_t mUsage;
+ Allocation *mAdaptedAllocation;
+
+ bool mConstrainedLOD;
+ bool mConstrainedFace;
+ bool mConstrainedY;
+ bool mConstrainedZ;
+ bool mReadAllowed;
+ bool mWriteAllowed;
+ uint32_t mSelectedY;
+ uint32_t mSelectedZ;
+ uint32_t mSelectedLOD;
+ RsAllocationCubemapFace mSelectedFace;
+
+ uint32_t mCurrentDimX;
+ uint32_t mCurrentDimY;
+ uint32_t mCurrentDimZ;
+ uint32_t mCurrentCount;
+
+
+ void * getIDSafe() const;
+ void updateCacheInfo(const Type *t);
+
+ Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage);
+
+ void validateIsInt32();
+ void validateIsInt16();
+ void validateIsInt8();
+ void validateIsFloat32();
+ void validateIsObject();
+
+ virtual void updateFromNative();
+
+ void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h);
+
+public:
+ const Type * getType() {
+ return mType;
+ }
+
+ void syncAll(RsAllocationUsageType srcLocation);
+ void ioSendOutput();
+ void ioGetInput();
+
+ //void copyFrom(BaseObj[] d);
+ //void copyFromUnchecked(int[] d);
+ //void copyFromUnchecked(short[] d);
+ //void copyFromUnchecked(byte[] d);
+ //void copyFromUnchecked(float[] d);
+ //void copyFrom(int[] d);
+ //void copyFrom(short[] d);
+ //void copyFrom(byte[] d);
+ //void copyFrom(float[] d);
+ //void setFromFieldPacker(int xoff, FieldPacker fp);
+ //void setFromFieldPacker(int xoff, int component_number, FieldPacker fp);
+ void generateMipmaps();
+ void copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen);
+ void copy1DRangeFrom(uint32_t off, size_t count, const int32_t* d, size_t dataLen);
+ void copy1DRangeFrom(uint32_t off, size_t count, const int16_t* d, size_t dataLen);
+ void copy1DRangeFrom(uint32_t off, size_t count, const int8_t* d, size_t dataLen);
+ void copy1DRangeFrom(uint32_t off, size_t count, const float* d, size_t dataLen);
+ void copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff);
+
+ void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const int32_t *data, size_t dataLen);
+ void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const int16_t *data, size_t dataLen);
+ void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const int8_t *data, size_t dataLen);
+ void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const float *data, size_t dataLen);
+ void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+ const Allocation *data, size_t dataLen,
+ uint32_t dataXoff, uint32_t dataYoff);
+
+ //void copyTo(byte[] d);
+ //void copyTo(short[] d);
+ //void copyTo(int[] d);
+ //void copyTo(float[] d);
+ void resize(int dimX);
+ void resize(int dimX, int dimY);
+
+ static Allocation *createTyped(RenderScript *rs, const Type *type,
+ RsAllocationMipmapControl mips, uint32_t usage);
+ static Allocation *createTyped(RenderScript *rs, const Type *type,
+ RsAllocationMipmapControl mips, uint32_t usage, void * pointer);
+
+ static Allocation *createTyped(RenderScript *rs, const Type *type,
+ uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+ static Allocation *createSized(RenderScript *rs, const Element *e, size_t count,
+ uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
+ //SurfaceTexture *getSurfaceTexture();
+ //void setSurfaceTexture(SurfaceTexture *sur);
+
+};
+
+#endif
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 9c5d06b7333f..45ed453e60a7 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -127,7 +127,14 @@ LOCAL_SRC_FILES:= \
driver/rsdSampler.cpp \
driver/rsdShader.cpp \
driver/rsdShaderCache.cpp \
- driver/rsdVertexArray.cpp
+ driver/rsdVertexArray.cpp \
+ RenderScript.cpp \
+ BaseObj.cpp \
+ Element.cpp \
+ Type.cpp \
+ Allocation.cpp \
+ Script.cpp \
+ ScriptC.cpp
LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui
diff --git a/libs/rs/BaseObj.cpp b/libs/rs/BaseObj.cpp
new file mode 100644
index 000000000000..82e51e773248
--- /dev/null
+++ b/libs/rs/BaseObj.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#define LOG_TAG "libRS_cpp"
+
+#include <rs.h>
+
+#include "RenderScript.h"
+#include "BaseObj.h"
+
+void * BaseObj::getID() const {
+ if (mID == NULL) {
+ ALOGE("Internal error: Object id 0.");
+ }
+ return mID;
+}
+
+void * BaseObj::getObjID(const BaseObj *o) {
+ return o == NULL ? NULL : o->getID();
+}
+
+
+BaseObj::BaseObj(void *id, RenderScript *rs) {
+ mRS = rs;
+ mID = id;
+}
+
+void BaseObj::checkValid() {
+ if (mID == 0) {
+ ALOGE("Invalid object.");
+ }
+}
+
+BaseObj::~BaseObj() {
+ rsObjDestroy(mRS->mContext, mID);
+ mRS = NULL;
+ mID = NULL;
+}
+
+void BaseObj::updateFromNative() {
+ const char *name = NULL;
+ rsaGetName(mRS, mID, &name);
+ mName = name;
+}
+
+bool BaseObj::equals(const BaseObj *obj) {
+ // Early-out check to see if both BaseObjs are actually the same
+ if (this == obj)
+ return true;
+ return mID == obj->mID;
+}
+
+
+
diff --git a/libs/rs/BaseObj.h b/libs/rs/BaseObj.h
new file mode 100644
index 000000000000..79761b1aa902
--- /dev/null
+++ b/libs/rs/BaseObj.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#ifndef __ANDROID_BASE_OBJ_H__
+#define __ANDROID_BASE_OBJ_H__
+
+
+#include <pthread.h>
+#include <rs.h>
+
+#include "RenderScript.h"
+
+class BaseObj {
+protected:
+ friend class Element;
+ friend class Type;
+ friend class Allocation;
+ friend class Script;
+ friend class ScriptC;
+
+ void *mID;
+ RenderScript *mRS;
+ android::String8 mName;
+
+ void * getID() const;
+
+ BaseObj(void *id, RenderScript *rs);
+ void checkValid();
+
+ static void * getObjID(const BaseObj *o);
+
+public:
+
+ virtual ~BaseObj();
+ virtual void updateFromNative();
+ virtual bool equals(const BaseObj *obj);
+};
+
+#endif
diff --git a/libs/rs/Element.cpp b/libs/rs/Element.cpp
new file mode 100644
index 000000000000..f318d40b77c0
--- /dev/null
+++ b/libs/rs/Element.cpp
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#define LOG_TAG "libRS_cpp"
+
+#include <utils/Log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+
+
+const Element * Element::getSubElement(uint32_t index) {
+ if (!mVisibleElementMap.size()) {
+ mRS->throwError("Element contains no sub-elements");
+ }
+ if (index >= mVisibleElementMap.size()) {
+ mRS->throwError("Illegal sub-element index");
+ }
+ return mElements[mVisibleElementMap[index]];
+}
+
+const char * Element::getSubElementName(uint32_t index) {
+ if (!mVisibleElementMap.size()) {
+ mRS->throwError("Element contains no sub-elements");
+ }
+ if (index >= mVisibleElementMap.size()) {
+ mRS->throwError("Illegal sub-element index");
+ }
+ return mElementNames[mVisibleElementMap[index]];
+}
+
+size_t Element::getSubElementArraySize(uint32_t index) {
+ if (!mVisibleElementMap.size()) {
+ mRS->throwError("Element contains no sub-elements");
+ }
+ if (index >= mVisibleElementMap.size()) {
+ mRS->throwError("Illegal sub-element index");
+ }
+ return mArraySizes[mVisibleElementMap[index]];
+}
+
+uint32_t Element::getSubElementOffsetBytes(uint32_t index) {
+ if (mVisibleElementMap.size()) {
+ mRS->throwError("Element contains no sub-elements");
+ }
+ if (index >= mVisibleElementMap.size()) {
+ mRS->throwError("Illegal sub-element index");
+ }
+ return mOffsetInBytes[mVisibleElementMap[index]];
+}
+
+
+#define CREATE_USER(N, T) const Element * Element::N(RenderScript *rs) { \
+ return createUser(rs, RS_TYPE_##T); \
+}
+CREATE_USER(BOOLEAN, BOOLEAN);
+CREATE_USER(U8, UNSIGNED_8);
+CREATE_USER(I8, SIGNED_8);
+CREATE_USER(U16, UNSIGNED_16);
+CREATE_USER(I16, SIGNED_16);
+CREATE_USER(U32, UNSIGNED_32);
+CREATE_USER(I32, SIGNED_32);
+CREATE_USER(U64, UNSIGNED_64);
+CREATE_USER(I64, SIGNED_64);
+CREATE_USER(F32, FLOAT_32);
+CREATE_USER(F64, FLOAT_64);
+CREATE_USER(ELEMENT, ELEMENT);
+CREATE_USER(TYPE, TYPE);
+CREATE_USER(ALLOCATION, ALLOCATION);
+CREATE_USER(SAMPLER, SAMPLER);
+CREATE_USER(SCRIPT, SCRIPT);
+CREATE_USER(MESH, MESH);
+CREATE_USER(PROGRAM_FRAGMENT, PROGRAM_FRAGMENT);
+CREATE_USER(PROGRAM_VERTEX, PROGRAM_VERTEX);
+CREATE_USER(PROGRAM_RASTER, PROGRAM_RASTER);
+CREATE_USER(PROGRAM_STORE, PROGRAM_STORE);
+CREATE_USER(MATRIX_4X4, MATRIX_4X4);
+CREATE_USER(MATRIX_3X3, MATRIX_3X3);
+CREATE_USER(MATRIX_2X2, MATRIX_2X2);
+
+#define CREATE_PIXEL(N, T, K) const Element * Element::N(RenderScript *rs) { \
+ return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \
+}
+CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A);
+CREATE_PIXEL(RGB_565, UNSIGNED_5_6_5, PIXEL_RGB);
+CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB);
+CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA);
+CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA);
+
+#define CREATE_VECTOR(N, T) const Element * Element::N##_2(RenderScript *rs) { \
+ return createVector(rs, RS_TYPE_##T, 2); \
+} \
+const Element * Element::N##_3(RenderScript *rs) { \
+ return createVector(rs, RS_TYPE_##T, 3); \
+} \
+const Element * Element::N##_4(RenderScript *rs) { \
+ return createVector(rs, RS_TYPE_##T, 4); \
+}
+CREATE_VECTOR(U8, UNSIGNED_8);
+CREATE_VECTOR(I8, SIGNED_8);
+CREATE_VECTOR(U16, UNSIGNED_16);
+CREATE_VECTOR(I16, SIGNED_16);
+CREATE_VECTOR(U32, UNSIGNED_32);
+CREATE_VECTOR(I32, SIGNED_32);
+CREATE_VECTOR(U64, UNSIGNED_64);
+CREATE_VECTOR(I64, SIGNED_64);
+CREATE_VECTOR(F32, FLOAT_32);
+CREATE_VECTOR(F64, FLOAT_64);
+
+
+void Element::updateVisibleSubElements() {
+ if (!mElements.size()) {
+ return;
+ }
+ mVisibleElementMap.clear();
+
+ int noPaddingFieldCount = 0;
+ size_t fieldCount = mElementNames.size();
+ // Find out how many elements are not padding
+ for (size_t ct = 0; ct < fieldCount; ct ++) {
+ if (mElementNames[ct].string()[0] != '#') {
+ noPaddingFieldCount ++;
+ }
+ }
+
+ // Make a map that points us at non-padding elements
+ for (size_t ct = 0; ct < fieldCount; ct ++) {
+ if (mElementNames[ct].string()[0] != '#') {
+ mVisibleElementMap.push((uint32_t)ct);
+ }
+ }
+}
+
+Element::Element(void *id, RenderScript *rs,
+ android::Vector<const Element *> &elements,
+ android::Vector<android::String8> &elementNames,
+ android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) {
+ mSizeBytes = 0;
+ mVectorSize = 1;
+ mElements = elements;
+ mArraySizes = arraySizes;
+ mElementNames = elementNames;
+
+ mType = RS_TYPE_NONE;
+ mKind = RS_KIND_USER;
+
+ for (size_t ct = 0; ct < mElements.size(); ct++ ) {
+ mOffsetInBytes.push(mSizeBytes);
+ mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct];
+ }
+ updateVisibleSubElements();
+}
+
+
+static uint32_t GetSizeInBytesForType(RsDataType dt) {
+ switch(dt) {
+ case RS_TYPE_NONE:
+ return 0;
+ case RS_TYPE_SIGNED_8:
+ case RS_TYPE_UNSIGNED_8:
+ case RS_TYPE_BOOLEAN:
+ return 1;
+
+ case RS_TYPE_FLOAT_16:
+ case RS_TYPE_SIGNED_16:
+ case RS_TYPE_UNSIGNED_16:
+ case RS_TYPE_UNSIGNED_5_6_5:
+ case RS_TYPE_UNSIGNED_5_5_5_1:
+ case RS_TYPE_UNSIGNED_4_4_4_4:
+ return 2;
+
+ case RS_TYPE_FLOAT_32:
+ case RS_TYPE_SIGNED_32:
+ case RS_TYPE_UNSIGNED_32:
+ return 4;
+
+ case RS_TYPE_FLOAT_64:
+ case RS_TYPE_SIGNED_64:
+ case RS_TYPE_UNSIGNED_64:
+ return 8;
+
+ case RS_TYPE_MATRIX_4X4:
+ return 16 * 4;
+ case RS_TYPE_MATRIX_3X3:
+ return 9 * 4;
+ case RS_TYPE_MATRIX_2X2:
+ return 4 * 4;
+
+ case RS_TYPE_TYPE:
+ case RS_TYPE_ALLOCATION:
+ case RS_TYPE_SAMPLER:
+ case RS_TYPE_SCRIPT:
+ case RS_TYPE_MESH:
+ case RS_TYPE_PROGRAM_FRAGMENT:
+ case RS_TYPE_PROGRAM_VERTEX:
+ case RS_TYPE_PROGRAM_RASTER:
+ case RS_TYPE_PROGRAM_STORE:
+ return 4;
+
+ default:
+ break;
+ }
+
+ ALOGE("Missing type %i", dt);
+ return 0;
+}
+
+Element::Element(void *id, RenderScript *rs,
+ RsDataType dt, RsDataKind dk, bool norm, uint32_t size) :
+ BaseObj(id, rs)
+{
+ uint32_t tsize = GetSizeInBytesForType(dt);
+ if ((dt != RS_TYPE_UNSIGNED_5_6_5) &&
+ (dt != RS_TYPE_UNSIGNED_4_4_4_4) &&
+ (dt != RS_TYPE_UNSIGNED_5_5_5_1)) {
+ if (size == 3) {
+ mSizeBytes = tsize * 4;
+ } else {
+ mSizeBytes = tsize * size;
+ }
+ } else {
+ mSizeBytes = tsize;
+ }
+ mType = dt;
+ mKind = dk;
+ mNormalized = norm;
+ mVectorSize = size;
+}
+
+Element::~Element() {
+}
+
+ /*
+ Element(int id, RenderScript rs) {
+ super(id, rs);
+ }
+ */
+
+void Element::updateFromNative() {
+ BaseObj::updateFromNative();
+/*
+ // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
+ int[] dataBuffer = new int[5];
+ mRS.nElementGetNativeData(getID(), dataBuffer);
+
+ mNormalized = dataBuffer[2] == 1 ? true : false;
+ mVectorSize = dataBuffer[3];
+ mSize = 0;
+ for (DataType dt: DataType.values()) {
+ if(dt.mID == dataBuffer[0]){
+ mType = dt;
+ mSize = mType.mSize * mVectorSize;
+ }
+ }
+ for (DataKind dk: DataKind.values()) {
+ if(dk.mID == dataBuffer[1]){
+ mKind = dk;
+ }
+ }
+
+ int numSubElements = dataBuffer[4];
+ if(numSubElements > 0) {
+ mElements = new Element[numSubElements];
+ mElementNames = new String[numSubElements];
+ mArraySizes = new int[numSubElements];
+ mOffsetInBytes = new int[numSubElements];
+
+ int[] subElementIds = new int[numSubElements];
+ mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes);
+ for(int i = 0; i < numSubElements; i ++) {
+ mElements[i] = new Element(subElementIds[i], mRS);
+ mElements[i].updateFromNative();
+ mOffsetInBytes[i] = mSize;
+ mSize += mElements[i].mSize * mArraySizes[i];
+ }
+ }
+ */
+ updateVisibleSubElements();
+}
+
+const Element * Element::createUser(RenderScript *rs, RsDataType dt) {
+ void * id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, 1);
+ return new Element(id, rs, dt, RS_KIND_USER, false, 1);
+}
+
+const Element * Element::createVector(RenderScript *rs, RsDataType dt, uint32_t size) {
+ if (size < 2 || size > 4) {
+ rs->throwError("Vector size out of range 2-4.");
+ }
+ void *id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, size);
+ return new Element(id, rs, dt, RS_KIND_USER, false, size);
+}
+
+const Element * Element::createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk) {
+ if (!(dk == RS_KIND_PIXEL_L ||
+ dk == RS_KIND_PIXEL_A ||
+ dk == RS_KIND_PIXEL_LA ||
+ dk == RS_KIND_PIXEL_RGB ||
+ dk == RS_KIND_PIXEL_RGBA ||
+ dk == RS_KIND_PIXEL_DEPTH)) {
+ rs->throwError("Unsupported DataKind");
+ }
+ if (!(dt == RS_TYPE_UNSIGNED_8 ||
+ dt == RS_TYPE_UNSIGNED_16 ||
+ dt == RS_TYPE_UNSIGNED_5_6_5 ||
+ dt == RS_TYPE_UNSIGNED_4_4_4_4 ||
+ dt == RS_TYPE_UNSIGNED_5_5_5_1)) {
+ rs->throwError("Unsupported DataType");
+ }
+ if (dt == RS_TYPE_UNSIGNED_5_6_5 && dk != RS_KIND_PIXEL_RGB) {
+ rs->throwError("Bad kind and type combo");
+ }
+ if (dt == RS_TYPE_UNSIGNED_5_5_5_1 && dk != RS_KIND_PIXEL_RGBA) {
+ rs->throwError("Bad kind and type combo");
+ }
+ if (dt == RS_TYPE_UNSIGNED_4_4_4_4 && dk != RS_KIND_PIXEL_RGBA) {
+ rs->throwError("Bad kind and type combo");
+ }
+ if (dt == RS_TYPE_UNSIGNED_16 && dk != RS_KIND_PIXEL_DEPTH) {
+ rs->throwError("Bad kind and type combo");
+ }
+
+ int size = 1;
+ switch (dk) {
+ case RS_KIND_PIXEL_LA:
+ size = 2;
+ break;
+ case RS_KIND_PIXEL_RGB:
+ size = 3;
+ break;
+ case RS_KIND_PIXEL_RGBA:
+ size = 4;
+ break;
+ case RS_KIND_PIXEL_DEPTH:
+ size = 2;
+ break;
+ default:
+ break;
+ }
+
+ void * id = rsElementCreate(rs->mContext, dt, dk, true, size);
+ return new Element(id, rs, dt, dk, true, size);
+}
+
+bool Element::isCompatible(const Element *e) {
+ // Try strict BaseObj equality to start with.
+ if (this == e) {
+ return true;
+ }
+
+ // Ignore mKind because it is allowed to be different (user vs. pixel).
+ // We also ignore mNormalized because it can be different. The mType
+ // field must be non-null since we require name equivalence for
+ // user-created Elements.
+ return ((mSizeBytes == e->mSizeBytes) &&
+ (mType != NULL) &&
+ (mType == e->mType) &&
+ (mVectorSize == e->mVectorSize));
+}
+
+Element::Builder::Builder(RenderScript *rs) {
+ mRS = rs;
+ mSkipPadding = false;
+}
+
+void Element::Builder::add(const Element *e, android::String8 &name, uint32_t arraySize) {
+ // Skip padding fields after a vector 3 type.
+ if (mSkipPadding) {
+ const char *s1 = "#padding_";
+ const char *s2 = name;
+ size_t len = strlen(s1);
+ if (strlen(s2) >= len) {
+ if (!memcmp(s1, s2, len)) {
+ mSkipPadding = false;
+ return;
+ }
+ }
+ }
+
+ if (e->mVectorSize == 3) {
+ mSkipPadding = true;
+ } else {
+ mSkipPadding = false;
+ }
+
+ mElements.add(e);
+ mElementNames.add(name);
+ mArraySizes.add(arraySize);
+}
+
+const Element * Element::Builder::create() {
+ size_t fieldCount = mElements.size();
+ const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
+ size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t));
+
+ for (size_t ct = 0; ct < fieldCount; ct++) {
+ nameArray[ct] = mElementNames[ct].string();
+ sizeArray[ct] = mElementNames[ct].length();
+ }
+
+ void *id = rsElementCreate2(mRS->mContext,
+ (RsElement *)mElements.array(), fieldCount,
+ nameArray, fieldCount * sizeof(size_t), sizeArray,
+ (const uint32_t *)mArraySizes.array(), fieldCount);
+
+
+ free(nameArray);
+ free(sizeArray);
+
+ Element *e = new Element(id, mRS, mElements, mElementNames, mArraySizes);
+ return e;
+}
+
diff --git a/libs/rs/Element.h b/libs/rs/Element.h
new file mode 100644
index 000000000000..a579dc3003f3
--- /dev/null
+++ b/libs/rs/Element.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#ifndef __ANDROID_ELEMENT_H__
+#define __ANDROID_ELEMENT_H__
+
+#include <rs.h>
+#include "RenderScript.h"
+#include "BaseObj.h"
+
+class Element : public BaseObj {
+public:
+ /**
+ * Return if a element is too complex for use as a data source for a Mesh or
+ * a Program.
+ *
+ * @return boolean
+ */
+ bool isComplex();
+
+ /**
+ * @hide
+ * @return number of sub-elements in this element
+ */
+ size_t getSubElementCount() {
+ return mVisibleElementMap.size();
+ }
+
+ /**
+ * @hide
+ * @param index index of the sub-element to return
+ * @return sub-element in this element at given index
+ */
+ const Element * getSubElement(uint32_t index);
+
+ /**
+ * @hide
+ * @param index index of the sub-element
+ * @return sub-element in this element at given index
+ */
+ const char * getSubElementName(uint32_t index);
+
+ /**
+ * @hide
+ * @param index index of the sub-element
+ * @return array size of sub-element in this element at given index
+ */
+ size_t getSubElementArraySize(uint32_t index);
+
+ /**
+ * @hide
+ * @param index index of the sub-element
+ * @return offset in bytes of sub-element in this element at given index
+ */
+ uint32_t getSubElementOffsetBytes(uint32_t index);
+
+ /**
+ * @hide
+ * @return element data type
+ */
+ RsDataType getDataType() const {
+ return mType;
+ }
+
+ /**
+ * @hide
+ * @return element data kind
+ */
+ RsDataKind getDataKind() const {
+ return mKind;
+ }
+
+ size_t getSizeBytes() const {
+ return mSizeBytes;
+ }
+
+
+ static const Element * BOOLEAN(RenderScript *rs);
+ static const Element * U8(RenderScript *rs);
+ static const Element * I8(RenderScript *rs);
+ static const Element * U16(RenderScript *rs);
+ static const Element * I16(RenderScript *rs);
+ static const Element * U32(RenderScript *rs);
+ static const Element * I32(RenderScript *rs);
+ static const Element * U64(RenderScript *rs);
+ static const Element * I64(RenderScript *rs);
+ static const Element * F32(RenderScript *rs);
+ static const Element * F64(RenderScript *rs);
+ static const Element * ELEMENT(RenderScript *rs);
+ static const Element * TYPE(RenderScript *rs);
+ static const Element * ALLOCATION(RenderScript *rs);
+ static const Element * SAMPLER(RenderScript *rs);
+ static const Element * SCRIPT(RenderScript *rs);
+ static const Element * MESH(RenderScript *rs);
+ static const Element * PROGRAM_FRAGMENT(RenderScript *rs);
+ static const Element * PROGRAM_VERTEX(RenderScript *rs);
+ static const Element * PROGRAM_RASTER(RenderScript *rs);
+ static const Element * PROGRAM_STORE(RenderScript *rs);
+
+ static const Element * A_8(RenderScript *rs);
+ static const Element * RGB_565(RenderScript *rs);
+ static const Element * RGB_888(RenderScript *rs);
+ static const Element * RGBA_5551(RenderScript *rs);
+ static const Element * RGBA_4444(RenderScript *rs);
+ static const Element * RGBA_8888(RenderScript *rs);
+
+ static const Element * F32_2(RenderScript *rs);
+ static const Element * F32_3(RenderScript *rs);
+ static const Element * F32_4(RenderScript *rs);
+ static const Element * F64_2(RenderScript *rs);
+ static const Element * F64_3(RenderScript *rs);
+ static const Element * F64_4(RenderScript *rs);
+ static const Element * U8_2(RenderScript *rs);
+ static const Element * U8_3(RenderScript *rs);
+ static const Element * U8_4(RenderScript *rs);
+ static const Element * I8_2(RenderScript *rs);
+ static const Element * I8_3(RenderScript *rs);
+ static const Element * I8_4(RenderScript *rs);
+ static const Element * U16_2(RenderScript *rs);
+ static const Element * U16_3(RenderScript *rs);
+ static const Element * U16_4(RenderScript *rs);
+ static const Element * I16_2(RenderScript *rs);
+ static const Element * I16_3(RenderScript *rs);
+ static const Element * I16_4(RenderScript *rs);
+ static const Element * U32_2(RenderScript *rs);
+ static const Element * U32_3(RenderScript *rs);
+ static const Element * U32_4(RenderScript *rs);
+ static const Element * I32_2(RenderScript *rs);
+ static const Element * I32_3(RenderScript *rs);
+ static const Element * I32_4(RenderScript *rs);
+ static const Element * U64_2(RenderScript *rs);
+ static const Element * U64_3(RenderScript *rs);
+ static const Element * U64_4(RenderScript *rs);
+ static const Element * I64_2(RenderScript *rs);
+ static const Element * I64_3(RenderScript *rs);
+ static const Element * I64_4(RenderScript *rs);
+ static const Element * MATRIX_4X4(RenderScript *rs);
+ static const Element * MATRIX_3X3(RenderScript *rs);
+ static const Element * MATRIX_2X2(RenderScript *rs);
+
+ Element(void *id, RenderScript *rs,
+ android::Vector<const Element *> &elements,
+ android::Vector<android::String8> &elementNames,
+ android::Vector<uint32_t> &arraySizes);
+ Element(void *id, RenderScript *rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size);
+ Element(RenderScript *rs);
+ virtual ~Element();
+
+ void updateFromNative();
+ static const Element * createUser(RenderScript *rs, RsDataType dt);
+ static const Element * createVector(RenderScript *rs, RsDataType dt, uint32_t size);
+ static const Element * createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk);
+ bool isCompatible(const Element *e);
+
+ class Builder {
+ private:
+ RenderScript *mRS;
+ android::Vector<const Element *> mElements;
+ android::Vector<android::String8> mElementNames;
+ android::Vector<uint32_t> mArraySizes;
+ bool mSkipPadding;
+
+ public:
+ Builder(RenderScript *rs);
+ ~Builder();
+ void add(const Element *, android::String8 &name, uint32_t arraySize = 1);
+ const Element * create();
+ };
+
+private:
+ void updateVisibleSubElements();
+
+ android::Vector<const Element *> mElements;
+ android::Vector<android::String8> mElementNames;
+ android::Vector<uint32_t> mArraySizes;
+ android::Vector<uint32_t> mVisibleElementMap;
+ android::Vector<uint32_t> mOffsetInBytes;
+
+ RsDataType mType;
+ RsDataKind mKind;
+ bool mNormalized;
+ size_t mSizeBytes;
+ size_t mVectorSize;
+};
+
+#endif
diff --git a/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp
new file mode 100644
index 000000000000..0b4205559959
--- /dev/null
+++ b/libs/rs/RenderScript.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#define LOG_TAG "libRS_cpp"
+
+#include <utils/Log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "RenderScript.h"
+
+bool RenderScript::gInitialized = false;
+pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+
+RenderScript::RenderScript() {
+ mDev = NULL;
+ mContext = NULL;
+ mErrorFunc = NULL;
+ mMessageFunc = NULL;
+ mMessageRun = false;
+
+ memset(&mElements, 0, sizeof(mElements));
+}
+
+RenderScript::~RenderScript() {
+ mMessageRun = false;
+
+ rsContextDeinitToClient(mContext);
+
+ void *res = NULL;
+ int status = pthread_join(mMessageThreadId, &res);
+
+ rsContextDestroy(mContext);
+ mContext = NULL;
+ rsDeviceDestroy(mDev);
+ mDev = NULL;
+}
+
+bool RenderScript::init(int targetApi) {
+ mDev = rsDeviceCreate();
+ if (mDev == 0) {
+ ALOGE("Device creation failed");
+ return false;
+ }
+
+ mContext = rsContextCreate(mDev, 0, targetApi);
+ if (mContext == 0) {
+ ALOGE("Context creation failed");
+ return false;
+ }
+
+
+ pid_t mNativeMessageThreadId;
+
+ int status = pthread_create(&mMessageThreadId, NULL, threadProc, this);
+ if (status) {
+ ALOGE("Failed to start RenderScript message thread.");
+ return false;
+ }
+ // Wait for the message thread to be active.
+ while (!mMessageRun) {
+ usleep(1000);
+ }
+
+ return true;
+}
+
+void RenderScript::throwError(const char *err) const {
+ ALOGE("RS CPP error: %s", err);
+ int * v = NULL;
+ v[0] = 0;
+}
+
+
+void * RenderScript::threadProc(void *vrsc) {
+ RenderScript *rs = static_cast<RenderScript *>(vrsc);
+ size_t rbuf_size = 256;
+ void * rbuf = malloc(rbuf_size);
+
+ rsContextInitToClient(rs->mContext);
+ rs->mMessageRun = true;
+
+ while (rs->mMessageRun) {
+ size_t receiveLen = 0;
+ uint32_t usrID = 0;
+ uint32_t subID = 0;
+ RsMessageToClientType r = rsContextPeekMessage(rs->mContext,
+ &receiveLen, sizeof(receiveLen),
+ &usrID, sizeof(usrID));
+
+ if (receiveLen >= rbuf_size) {
+ rbuf_size = receiveLen + 32;
+ rbuf = realloc(rbuf, rbuf_size);
+ }
+ if (!rbuf) {
+ ALOGE("RenderScript::message handler realloc error %zu", rbuf_size);
+ // No clean way to recover now?
+ }
+ rsContextGetMessage(rs->mContext, rbuf, rbuf_size, &receiveLen, sizeof(receiveLen),
+ &subID, sizeof(subID));
+
+ switch(r) {
+ case RS_MESSAGE_TO_CLIENT_ERROR:
+ ALOGE("RS Error %s", (const char *)rbuf);
+
+ if(rs->mMessageFunc != NULL) {
+ rs->mErrorFunc(usrID, (const char *)rbuf);
+ }
+ break;
+ case RS_MESSAGE_TO_CLIENT_EXCEPTION:
+ // teardown. But we want to avoid starving other threads during
+ // teardown by yielding until the next line in the destructor can
+ // execute to set mRun = false
+ usleep(1000);
+ break;
+ case RS_MESSAGE_TO_CLIENT_USER:
+ if(rs->mMessageFunc != NULL) {
+ rs->mMessageFunc(usrID, rbuf, receiveLen);
+ } else {
+ ALOGE("Received a message from the script with no message handler installed.");
+ }
+ break;
+
+ default:
+ ALOGE("RenderScript unknown message type %i", r);
+ }
+ }
+
+ if (rbuf) {
+ free(rbuf);
+ }
+ ALOGE("RenderScript Message thread exiting.");
+ return NULL;
+}
+
+void RenderScript::setErrorHandler(ErrorHandlerFunc_t func) {
+ mErrorFunc = func;
+}
+
+void RenderScript::setMessageHandler(MessageHandlerFunc_t func) {
+ mMessageFunc = func;
+}
+
+void RenderScript::contextDump() {
+}
+
+void RenderScript::finish() {
+
+}
+
+
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
new file mode 100644
index 000000000000..0eb6a6d6c82f
--- /dev/null
+++ b/libs/rs/RenderScript.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#ifndef ANDROID_RENDERSCRIPT_H
+#define ANDROID_RENDERSCRIPT_H
+
+
+#include <pthread.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include "rs.h"
+
+class Element;
+class Type;
+class Allocation;
+
+class RenderScript {
+ friend class BaseObj;
+ friend class Allocation;
+ friend class Element;
+ friend class Type;
+ friend class Script;
+ friend class ScriptC;
+
+public:
+ RenderScript();
+ virtual ~RenderScript();
+
+ typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText);
+ typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen);
+
+
+ void setErrorHandler(ErrorHandlerFunc_t func);
+ ErrorHandlerFunc_t getErrorHandler() {return mErrorFunc;}
+
+ void setMessageHandler(MessageHandlerFunc_t func);
+ MessageHandlerFunc_t getMessageHandler() {return mMessageFunc;}
+
+ bool init(int targetApi);
+ void contextDump();
+ void finish();
+
+private:
+ static bool gInitialized;
+ static pthread_mutex_t gInitMutex;
+
+ pthread_t mMessageThreadId;
+ pid_t mNativeMessageThreadId;
+ bool mMessageRun;
+
+ RsDevice mDev;
+ RsContext mContext;
+
+ ErrorHandlerFunc_t mErrorFunc;
+ MessageHandlerFunc_t mMessageFunc;
+
+ struct {
+ Element *U8;
+ Element *I8;
+ Element *U16;
+ Element *I16;
+ Element *U32;
+ Element *I32;
+ Element *U64;
+ Element *I64;
+ Element *F32;
+ Element *F64;
+ Element *BOOLEAN;
+
+ Element *ELEMENT;
+ Element *TYPE;
+ Element *ALLOCATION;
+ Element *SAMPLER;
+ Element *SCRIPT;
+ Element *MESH;
+ Element *PROGRAM_FRAGMENT;
+ Element *PROGRAM_VERTEX;
+ Element *PROGRAM_RASTER;
+ Element *PROGRAM_STORE;
+
+ Element *A_8;
+ Element *RGB_565;
+ Element *RGB_888;
+ Element *RGBA_5551;
+ Element *RGBA_4444;
+ Element *RGBA_8888;
+
+ Element *FLOAT_2;
+ Element *FLOAT_3;
+ Element *FLOAT_4;
+
+ Element *DOUBLE_2;
+ Element *DOUBLE_3;
+ Element *DOUBLE_4;
+
+ Element *UCHAR_2;
+ Element *UCHAR_3;
+ Element *UCHAR_4;
+
+ Element *CHAR_2;
+ Element *CHAR_3;
+ Element *CHAR_4;
+
+ Element *USHORT_2;
+ Element *USHORT_3;
+ Element *USHORT_4;
+
+ Element *SHORT_2;
+ Element *SHORT_3;
+ Element *SHORT_4;
+
+ Element *UINT_2;
+ Element *UINT_3;
+ Element *UINT_4;
+
+ Element *INT_2;
+ Element *INT_3;
+ Element *INT_4;
+
+ Element *ULONG_2;
+ Element *ULONG_3;
+ Element *ULONG_4;
+
+ Element *LONG_2;
+ Element *LONG_3;
+ Element *LONG_4;
+
+ Element *MATRIX_4X4;
+ Element *MATRIX_3X3;
+ Element *MATRIX_2X2;
+ } mElements;
+
+
+
+ void throwError(const char *err) const;
+
+ static void * threadProc(void *);
+
+};
+
+#endif
+
diff --git a/libs/rs/Script.cpp b/libs/rs/Script.cpp
new file mode 100644
index 000000000000..25fa673c53f9
--- /dev/null
+++ b/libs/rs/Script.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#define LOG_TAG "libRS_cpp"
+
+#include <utils/Log.h>
+#include <malloc.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+#include "Allocation.h"
+#include "Script.h"
+
+void Script::invoke(uint32_t slot, const void *v, size_t len) {
+ rsScriptInvokeV(mRS->mContext, getID(), slot, v, len);
+}
+
+void Script::forEach(uint32_t slot, const Allocation *ain, const Allocation *aout,
+ const void *usr, size_t usrLen) {
+ if ((ain == NULL) && (aout == NULL)) {
+ mRS->throwError("At least one of ain or aout is required to be non-null.");
+ }
+ void *in_id = BaseObj::getObjID(ain);
+ void *out_id = BaseObj::getObjID(aout);
+ rsScriptForEach(mRS->mContext, getID(), slot, in_id, out_id, usr, usrLen);
+}
+
+
+Script::Script(void *id, RenderScript *rs) : BaseObj(id, rs) {
+}
+
+
+void Script::bindAllocation(const Allocation *va, uint32_t slot) {
+ rsScriptBindAllocation(mRS->mContext, getID(), BaseObj::getObjID(va), slot);
+}
+
+
+void Script::setVar(uint32_t index, const BaseObj *o) {
+ rsScriptSetVarObj(mRS->mContext, getID(), index, (o == NULL) ? 0 : o->getID());
+}
+
+void Script::setVar(uint32_t index, const void *v, size_t len) {
+ rsScriptSetVarV(mRS->mContext, getID(), index, v, len);
+}
+
+
+
+void Script::FieldBase::init(RenderScript *rs, uint32_t dimx, uint32_t usages) {
+ mAllocation = Allocation::createSized(rs, mElement, dimx, RS_ALLOCATION_USAGE_SCRIPT | usages);
+}
+
+//Script::FieldBase::FieldBase() {
+//}
+
+
diff --git a/libs/rs/Script.h b/libs/rs/Script.h
new file mode 100644
index 000000000000..54d1e40cfd2f
--- /dev/null
+++ b/libs/rs/Script.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#ifndef __ANDROID_SCRIPT_H__
+#define __ANDROID_SCRIPT_H__
+
+#include <pthread.h>
+#include <rs.h>
+
+#include "RenderScript.h"
+#include "Allocation.h"
+
+class Type;
+class Element;
+class Allocation;
+
+class Script : public BaseObj {
+protected:
+ Script(void *id, RenderScript *rs);
+ void forEach(uint32_t slot, const Allocation *in, const Allocation *out, const void *v, size_t);
+ void bindAllocation(const Allocation *va, uint32_t slot);
+ void setVar(uint32_t index, const void *, size_t len);
+ void setVar(uint32_t index, const BaseObj *o);
+ void invoke(uint32_t slot, const void *v, size_t len);
+
+
+ void invoke(uint32_t slot) {
+ invoke(slot, NULL, 0);
+ }
+ void setVar(uint32_t index, float v) {
+ setVar(index, &v, sizeof(v));
+ }
+ void setVar(uint32_t index, double v) {
+ setVar(index, &v, sizeof(v));
+ }
+ void setVar(uint32_t index, int32_t v) {
+ setVar(index, &v, sizeof(v));
+ }
+ void setVar(uint32_t index, int64_t v) {
+ setVar(index, &v, sizeof(v));
+ }
+ void setVar(uint32_t index, bool v) {
+ setVar(index, &v, sizeof(v));
+ }
+
+public:
+ class FieldBase {
+ protected:
+ const Element *mElement;
+ Allocation *mAllocation;
+
+ void init(RenderScript *rs, uint32_t dimx, uint32_t usages = 0);
+
+ public:
+ const Element *getElement() {
+ return mElement;
+ }
+
+ const Type *getType() {
+ return mAllocation->getType();
+ }
+
+ const Allocation *getAllocation() {
+ return mAllocation;
+ }
+
+ //void updateAllocation();
+ };
+};
+
+#endif
diff --git a/include/private/ui/android_natives_priv.h b/libs/rs/ScriptC.cpp
index 6b9f524dcfd1..ad82ff46acf1 100644
--- a/include/private/ui/android_natives_priv.h
+++ b/libs/rs/ScriptC.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2008-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.
@@ -14,4 +14,19 @@
* limitations under the License.
*/
-#include <ui/android_native_buffer.h>
+#define LOG_TAG "libRS_cpp"
+
+#include <utils/Log.h>
+#include <malloc.h>
+
+#include "ScriptC.h"
+
+ScriptC::ScriptC(RenderScript *rs,
+ const char *codeTxt, size_t codeLength,
+ const char *cachedName, size_t cachedNameLength,
+ const char *cacheDir, size_t cacheDirLength)
+: Script(NULL, rs) {
+ mID = rsScriptCCreate(rs->mContext, cachedName, cachedNameLength,
+ cacheDir, cacheDirLength, codeTxt, codeLength);
+}
+
diff --git a/services/audioflinger/AudioBufferProvider.cpp b/libs/rs/ScriptC.h
index 678fd58b4e47..dcbbe10ef5e3 100644
--- a/services/audioflinger/AudioBufferProvider.cpp
+++ b/libs/rs/ScriptC.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2008-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.
@@ -14,15 +14,21 @@
* limitations under the License.
*/
-#undef __STRICT_ANSI__
-#define __STDINT_LIMITS
-#define __STDC_LIMIT_MACROS
-#include <stdint.h>
+#ifndef __ANDROID_SCRIPTC_H__
+#define __ANDROID_SCRIPTC_H__
-#include "AudioBufferProvider.h"
+#include <pthread.h>
+#include <rs.h>
-namespace android {
+#include "Script.h"
-const int64_t AudioBufferProvider::kInvalidPTS = INT64_MAX;
+class ScriptC : public Script {
+protected:
+ ScriptC(RenderScript *rs,
+ const char *codeTxt, size_t codeLength,
+ const char *cachedName, size_t cachedNameLength,
+ const char *cacheDir, size_t cacheDirLength);
-}; // namespace android
+};
+
+#endif
diff --git a/libs/rs/Type.cpp b/libs/rs/Type.cpp
new file mode 100644
index 000000000000..1352bd7eef10
--- /dev/null
+++ b/libs/rs/Type.cpp
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "libRS_cpp"
+
+#include <utils/Log.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+
+void Type::calcElementCount() {
+ bool hasLod = hasMipmaps();
+ uint32_t x = getX();
+ uint32_t y = getY();
+ uint32_t z = getZ();
+ uint32_t faces = 1;
+ if (hasFaces()) {
+ faces = 6;
+ }
+ if (x == 0) {
+ x = 1;
+ }
+ if (y == 0) {
+ y = 1;
+ }
+ if (z == 0) {
+ z = 1;
+ }
+
+ uint32_t count = x * y * z * faces;
+ while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
+ if(x > 1) {
+ x >>= 1;
+ }
+ if(y > 1) {
+ y >>= 1;
+ }
+ if(z > 1) {
+ z >>= 1;
+ }
+
+ count += x * y * z * faces;
+ }
+ mElementCount = count;
+}
+
+
+Type::Type(void *id, RenderScript *rs) : BaseObj(id, rs) {
+ mDimX = 0;
+ mDimY = 0;
+ mDimZ = 0;
+ mDimMipmaps = false;
+ mDimFaces = false;
+ mElement = NULL;
+}
+
+void Type::updateFromNative() {
+ // We have 6 integer to obtain mDimX; mDimY; mDimZ;
+ // mDimLOD; mDimFaces; mElement;
+
+ /*
+ int[] dataBuffer = new int[6];
+ mRS.nTypeGetNativeData(getID(), dataBuffer);
+
+ mDimX = dataBuffer[0];
+ mDimY = dataBuffer[1];
+ mDimZ = dataBuffer[2];
+ mDimMipmaps = dataBuffer[3] == 1 ? true : false;
+ mDimFaces = dataBuffer[4] == 1 ? true : false;
+
+ int elementID = dataBuffer[5];
+ if(elementID != 0) {
+ mElement = new Element(elementID, mRS);
+ mElement.updateFromNative();
+ }
+ calcElementCount();
+ */
+}
+
+Type::Builder::Builder(RenderScript *rs, const Element *e) {
+ mRS = rs;
+ mElement = e;
+ mDimX = 0;
+ mDimY = 0;
+ mDimZ = 0;
+ mDimMipmaps = false;
+ mDimFaces = false;
+}
+
+void Type::Builder::setX(uint32_t value) {
+ if(value < 1) {
+ ALOGE("Values of less than 1 for Dimension X are not valid.");
+ }
+ mDimX = value;
+}
+
+void Type::Builder::setY(int value) {
+ if(value < 1) {
+ ALOGE("Values of less than 1 for Dimension Y are not valid.");
+ }
+ mDimY = value;
+}
+
+void Type::Builder::setMipmaps(bool value) {
+ mDimMipmaps = value;
+}
+
+void Type::Builder::setFaces(bool value) {
+ mDimFaces = value;
+}
+
+const Type * Type::Builder::create() {
+ if (mDimZ > 0) {
+ if ((mDimX < 1) || (mDimY < 1)) {
+ ALOGE("Both X and Y dimension required when Z is present.");
+ }
+ if (mDimFaces) {
+ ALOGE("Cube maps not supported with 3D types.");
+ }
+ }
+ if (mDimY > 0) {
+ if (mDimX < 1) {
+ ALOGE("X dimension required when Y is present.");
+ }
+ }
+ if (mDimFaces) {
+ if (mDimY < 1) {
+ ALOGE("Cube maps require 2D Types.");
+ }
+ }
+
+ void * id = rsTypeCreate(mRS->mContext, mElement->getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces);
+ Type *t = new Type(id, mRS);
+ t->mElement = mElement;
+ t->mDimX = mDimX;
+ t->mDimY = mDimY;
+ t->mDimZ = mDimZ;
+ t->mDimMipmaps = mDimMipmaps;
+ t->mDimFaces = mDimFaces;
+
+ t->calcElementCount();
+ return t;
+}
+
diff --git a/libs/rs/Type.h b/libs/rs/Type.h
new file mode 100644
index 000000000000..53481c3078de
--- /dev/null
+++ b/libs/rs/Type.h
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+#ifndef __ANDROID_TYPE_H__
+#define __ANDROID_TYPE_H__
+
+#include <rs.h>
+#include "RenderScript.h"
+#include "Element.h"
+
+class Type : public BaseObj {
+protected:
+ friend class Allocation;
+
+ uint32_t mDimX;
+ uint32_t mDimY;
+ uint32_t mDimZ;
+ bool mDimMipmaps;
+ bool mDimFaces;
+ size_t mElementCount;
+ const Element *mElement;
+
+ void calcElementCount();
+ virtual void updateFromNative();
+
+public:
+
+ const Element* getElement() const {
+ return mElement;
+ }
+
+ uint32_t getX() const {
+ return mDimX;
+ }
+
+ uint32_t getY() const {
+ return mDimY;
+ }
+
+ uint32_t getZ() const {
+ return mDimZ;
+ }
+
+ bool hasMipmaps() const {
+ return mDimMipmaps;
+ }
+
+ bool hasFaces() const {
+ return mDimFaces;
+ }
+
+ size_t getCount() const {
+ return mElementCount;
+ }
+
+ size_t getSizeBytes() const {
+ return mElementCount * mElement->getSizeBytes();
+ }
+
+
+ Type(void *id, RenderScript *rs);
+
+
+ class Builder {
+ protected:
+ RenderScript *mRS;
+ uint32_t mDimX;
+ uint32_t mDimY;
+ uint32_t mDimZ;
+ bool mDimMipmaps;
+ bool mDimFaces;
+ const Element *mElement;
+
+ public:
+ Builder(RenderScript *rs, const Element *e);
+
+ void setX(uint32_t value);
+ void setY(int value);
+ void setMipmaps(bool value);
+ void setFaces(bool value);
+ const Type * create();
+ };
+
+};
+
+#endif
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index bec6ffffce01..dd7868408235 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-
#include "rsdCore.h"
#include "rsdBcc.h"
#include "rsdRuntime.h"
@@ -30,7 +29,6 @@ extern "C" {
#include "libdex/ZipArchive.h"
}
-
using namespace android;
using namespace android::renderscript;
@@ -45,6 +43,7 @@ struct DrvScript {
bcinfo::MetadataExtractor *ME;
InvokeFunc_t *mInvokeFunctions;
+ ForEachFunc_t *mForEachFunctions;
void ** mFieldAddress;
bool * mFieldIsObject;
const uint32_t *mExportForEachSignatureList;
@@ -162,8 +161,16 @@ bool rsdScriptInit(const Context *rsc,
}
exportForEachSignatureCount = drv->ME->getExportForEachSignatureCount();
- rsAssert(exportForEachSignatureCount <= 1);
drv->mExportForEachSignatureList = drv->ME->getExportForEachSignatureList();
+ if (exportForEachSignatureCount > 0) {
+ drv->mForEachFunctions =
+ (ForEachFunc_t*) calloc(exportForEachSignatureCount,
+ sizeof(ForEachFunc_t));
+ bccGetExportForEachList(drv->mBccScript, exportForEachSignatureCount,
+ (void **) drv->mForEachFunctions);
+ } else {
+ drv->mForEachFunctions = NULL;
+ }
// Copy info over to runtime
script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount();
@@ -196,6 +203,7 @@ error:
typedef struct {
Context *rsc;
Script *script;
+ ForEachFunc_t kernel;
uint32_t sig;
const Allocation * ain;
Allocation * aout;
@@ -235,7 +243,7 @@ static void wc_xy(void *usr, uint32_t idx) {
RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
uint32_t sig = mtls->sig;
- outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root;
+ outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
@@ -265,7 +273,7 @@ static void wc_x(void *usr, uint32_t idx) {
RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv;
uint32_t sig = mtls->sig;
- outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root;
+ outer_foreach_t fn = (outer_foreach_t) mtls->kernel;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
@@ -299,8 +307,8 @@ void rsdScriptInvokeForEach(const Context *rsc,
memset(&mtls, 0, sizeof(mtls));
DrvScript *drv = (DrvScript *)s->mHal.drv;
- // We only support slot 0 (root) at this point in time.
- rsAssert(slot == 0);
+ mtls.kernel = drv->mForEachFunctions[slot];
+ rsAssert(mtls.kernel != NULL);
mtls.sig = 0x1f; // temp fix for old apps, full table in slang_rs_export_foreach.cpp
if (drv->mExportForEachSignatureList) {
mtls.sig = drv->mExportForEachSignatureList[slot];
@@ -391,7 +399,7 @@ void rsdScriptInvokeForEach(const Context *rsc,
uint32_t sig = mtls.sig;
//ALOGE("launch 3");
- outer_foreach_t fn = (outer_foreach_t) mtls.script->mHal.info.root;
+ outer_foreach_t fn = (outer_foreach_t) mtls.kernel;
for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
@@ -517,6 +525,11 @@ void rsdScriptDestroy(const Context *dc, Script *script) {
drv->mInvokeFunctions = NULL;
}
+ if (drv->mForEachFunctions) {
+ free(drv->mForEachFunctions);
+ drv->mForEachFunctions = NULL;
+ }
+
delete drv->ME;
drv->ME = NULL;
diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h
index 168bdf36e1cb..05ca13bb35a2 100644
--- a/libs/rs/driver/rsdCore.h
+++ b/libs/rs/driver/rsdCore.h
@@ -25,6 +25,7 @@
#include "rsdGL.h"
typedef void (* InvokeFunc_t)(void);
+typedef void (* ForEachFunc_t)(void);
typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
typedef struct RsdSymbolTableRec {
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index b136cc7d767c..1b12235248c9 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -16,8 +16,8 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/PixelFormat.h>
-#include <ui/EGLUtils.h>
-#include <ui/egl/android_natives.h>
+
+#include <system/window.h>
#include <sys/types.h>
#include <sys/resource.h>
@@ -47,6 +47,29 @@ using namespace android::renderscript;
static int32_t gGLContextCount = 0;
static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+ struct EGLUtils {
+ static const char *strerror(EGLint err) {
+ switch (err){
+ case EGL_SUCCESS: return "EGL_SUCCESS";
+ case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
+ case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
+ case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
+ case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
+ case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
+ case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+ case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
+ case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
+ case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+ case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
+ case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
+ case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
+ default: return "UNKNOWN";
+ }
+ }
+ };
+
if (returnVal != EGL_TRUE) {
fprintf(stderr, "%s() returned %d\n", op, returnVal);
}
@@ -455,3 +478,37 @@ void rsdGLCheckError(const android::renderscript::Context *rsc,
}
}
+
+void rsdGLClearColor(const android::renderscript::Context *rsc,
+ float r, float g, float b, float a) {
+ RSD_CALL_GL(glClearColor, r, g, b, a);
+ RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
+}
+
+void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
+ RSD_CALL_GL(glClearDepthf, v);
+ RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
+}
+
+void rsdGLFinish(const android::renderscript::Context *rsc) {
+ RSD_CALL_GL(glFinish);
+}
+
+void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
+ float x1, float y1, float z1, float u1, float v1,
+ float x2, float y2, float z2, float u2, float v2,
+ float x3, float y3, float z3, float u3, float v3,
+ float x4, float y4, float z4, float u4, float v4) {
+
+ float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
+ const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
+
+ RsdVertexArray::Attrib attribs[2];
+ attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
+ attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
+
+ RsdVertexArray va(attribs, 2);
+ va.setup(rsc);
+
+ RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
+}
diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h
index e015cb170246..1e5b40fcafa5 100644
--- a/libs/rs/driver/rsdGL.h
+++ b/libs/rs/driver/rsdGL.h
@@ -84,6 +84,15 @@ void rsdGLCheckError(const android::renderscript::Context *rsc,
const char *msg, bool isFatal = false);
void rsdGLSetPriority(const android::renderscript::Context *rsc,
int32_t priority);
+void rsdGLClearColor(const android::renderscript::Context *rsc,
+ float r, float g, float b, float a);
+void rsdGLClearDepth(const android::renderscript::Context *rsc, float v);
+void rsdGLFinish(const android::renderscript::Context *rsc);
+void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
+ float x1, float y1, float z1, float u1, float v1,
+ float x2, float y2, float z2, float u2, float v2,
+ float x3, float y3, float z3, float u3, float v3,
+ float x4, float y4, float z4, float u4, float v4);
#endif
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index 44bfb1c8fe9f..aa9f1594d587 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -257,17 +257,19 @@ static void SC_Color(float r, float g, float b, float a) {
static void SC_Finish() {
GET_TLS();
- rsrFinish(rsc, sc);
+ rsdGLFinish(rsc);
}
static void SC_ClearColor(float r, float g, float b, float a) {
GET_TLS();
- rsrClearColor(rsc, sc, r, g, b, a);
+ rsrPrepareClear(rsc, sc);
+ rsdGLClearColor(rsc, r, g, b, a);
}
static void SC_ClearDepth(float v) {
GET_TLS();
- rsrClearDepth(rsc, sc, v);
+ rsrPrepareClear(rsc, sc);
+ rsdGLClearDepth(rsc, v);
}
static uint32_t SC_GetWidth() {
diff --git a/libs/rs/rsRuntime.h b/libs/rs/rsRuntime.h
index 3bded620e0d3..64f2de8aed6e 100644
--- a/libs/rs/rsRuntime.h
+++ b/libs/rs/rsRuntime.h
@@ -86,7 +86,6 @@ void rsrMeshComputeBoundingBox(Context *, Script *, Mesh *,
void rsrColor(Context *, Script *, float r, float g, float b, float a);
-void rsrFinish(Context *, Script *);
void rsrAllocationSyncAll(Context *, Script *, Allocation *);
void rsrAllocationCopy1DRange(Context *, Allocation *dstAlloc,
@@ -103,8 +102,7 @@ void rsrAllocationCopy2DRange(Context *, Allocation *dstAlloc,
uint32_t srcXoff, uint32_t srcYoff,
uint32_t srcMip, uint32_t srcFace);
-void rsrClearColor(Context *, Script *, float r, float g, float b, float a);
-void rsrClearDepth(Context *, Script *, float v);
+void rsrPrepareClear(Context *, Script *);
uint32_t rsrGetWidth(Context *, Script *);
uint32_t rsrGetHeight(Context *, Script *);
void rsrDrawTextAlloc(Context *, Script *, Allocation *, int x, int y);
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 357dbe32e18e..6a3bd4bf7a08 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -113,7 +113,7 @@ void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
RsAllocation vain, RsAllocation vaout,
const void *params, size_t paramLen) {
Script *s = static_cast<Script *>(vs);
- s->runForEach(rsc,
+ s->runForEach(rsc, slot,
static_cast<const Allocation *>(vain), static_cast<Allocation *>(vaout),
params, paramLen);
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 99dceafaba37..7879ea61c50e 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -74,6 +74,7 @@ public:
virtual bool freeChildren();
virtual void runForEach(Context *rsc,
+ uint32_t slot,
const Allocation * ain,
Allocation * aout,
const void * usr,
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index b4eb995aed2f..79725b97e03f 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -128,6 +128,7 @@ uint32_t ScriptC::run(Context *rsc) {
void ScriptC::runForEach(Context *rsc,
+ uint32_t slot,
const Allocation * ain,
Allocation * aout,
const void * usr,
@@ -138,7 +139,7 @@ void ScriptC::runForEach(Context *rsc,
setupGLState(rsc);
setupScript(rsc);
- rsc->mHal.funcs.script.invokeForEach(rsc, this, 0, ain, aout, usr, usrBytes, sc);
+ rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc);
}
void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) {
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index fc4df5132c23..92e1f4ff3ec0 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -47,6 +47,7 @@ public:
virtual uint32_t run(Context *);
virtual void runForEach(Context *rsc,
+ uint32_t slot,
const Allocation * ain,
Allocation * aout,
const void * usr,
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 183e207c7470..a5a0fae9bf57 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009-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.
@@ -157,7 +157,7 @@ void rsrForEach(Context *rsc, Script *sc,
Allocation *in, Allocation *out,
const void *usr, uint32_t usrBytes,
const RsScriptCall *call) {
- target->runForEach(rsc, in, out, usr, usrBytes, call);
+ target->runForEach(rsc, /* root slot */ 0, in, out, usr, usrBytes, call);
}
void rsrAllocationSyncAll(Context *rsc, Script *sc, Allocation *a, RsAllocationUsageType usage) {
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 97469d370553..bda18fdfbef1 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -269,25 +269,9 @@ void rsrColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
pf->setConstantColor(rsc, r, g, b, a);
}
-void rsrFinish(Context *rsc, Script *sc) {
- RSD_CALL_GL(glFinish);
-}
-
-
-void rsrClearColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
+void rsrPrepareClear(Context *rsc, Script *sc) {
rsc->mFBOCache.setup(rsc);
rsc->setupProgramStore();
-
- RSD_CALL_GL(glClearColor, r, g, b, a);
- RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
-}
-
-void rsrClearDepth(Context *rsc, Script *sc, float v) {
- rsc->mFBOCache.setup(rsc);
- rsc->setupProgramStore();
-
- RSD_CALL_GL(glClearDepthf, v);
- RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
}
uint32_t rsrGetWidth(Context *rsc, Script *sc) {
diff --git a/libs/rs/tests/Android.mk b/libs/rs/tests/Android.mk
new file mode 100644
index 000000000000..197e8623ec82
--- /dev/null
+++ b/libs/rs/tests/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ compute.cpp \
+ ScriptC_mono.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libRS \
+ libz \
+ libcutils \
+ libutils \
+ libEGL \
+ libGLESv1_CM \
+ libGLESv2 \
+ libui \
+ libbcc \
+ libbcinfo \
+ libgui
+
+LOCAL_MODULE:= rstest-compute
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES += .. \
+ frameworks/base/libs/rs \
+ out/target/product/stingray/obj/SHARED_LIBRARIES/libRS_intermediates
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/libs/rs/tests/ScriptC_mono.cpp b/libs/rs/tests/ScriptC_mono.cpp
new file mode 100644
index 000000000000..7f83616acf6f
--- /dev/null
+++ b/libs/rs/tests/ScriptC_mono.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008-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.
+ */
+
+#include "ScriptC_mono.h"
+
+static const char mono[] = \
+ "\xDE\xC0\x17\x0B\x00\x00\x00\x00\x18\x00\x00\x00\xFC\x03\x00\x00\x00\x00\x00\x00" \
+ "\x10\x00\x00\x00\x42\x43\xC0\xDE\x21\x0C\x00\x00\xFC\x00\x00\x00\x01\x10\x00\x00" \
+ "\x12\x00\x00\x00\x07\x81\x23\x91\x41\xC8\x04\x49\x06\x10\x32\x39\x92\x01\x84\x0C" \
+ "\x25\x05\x08\x19\x1E\x04\x8B\x62\x80\x14\x45\x02\x42\x92\x0B\x42\xA4\x10\x32\x14" \
+ "\x38\x08\x18\x49\x0A\x32\x44\x24\x48\x0A\x90\x21\x23\xC4\x52\x80\x0C\x19\x21\x72" \
+ "\x24\x07\xC8\x48\x11\x62\xA8\xA0\xA8\x40\xC6\xF0\x01\x00\x00\x00\x49\x18\x00\x00" \
+ "\x08\x00\x00\x00\x0B\x8C\x00\x04\x41\x10\x04\x09\x01\x04\x41\x10\x04\x89\xFF\xFF" \
+ "\xFF\xFF\x1F\xC0\x60\x81\xF0\xFF\xFF\xFF\xFF\x03\x18\x00\x00\x00\x89\x20\x00\x00" \
+ "\x13\x00\x00\x00\x32\x22\x48\x09\x20\x64\x85\x04\x93\x22\xA4\x84\x04\x93\x22\xE3" \
+ "\x84\xA1\x90\x14\x12\x4C\x8A\x8C\x0B\x84\xA4\x4C\x10\x48\x23\x00\x73\x04\xC8\x30" \
+ "\x02\x11\x90\x28\x03\x18\x83\xC8\x0C\xC0\x30\x02\x61\x14\xE1\x08\x42\xC3\x08\x83" \
+ "\x51\x06\xA3\x14\xAD\x22\x08\x45\x6D\x20\x60\x8E\x00\x0C\x86\x11\x06\x08\x00\x00" \
+ "\x13\xB0\x70\x90\x87\x76\xB0\x87\x3B\x68\x03\x77\x78\x07\x77\x28\x87\x36\x60\x87" \
+ "\x74\x70\x87\x7A\xC0\x87\x36\x38\x07\x77\xA8\x87\x72\x08\x07\x71\x48\x87\x0D\xF2" \
+ "\x50\x0E\x6D\x00\x0F\x7A\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06" \
+ "\xE9\x10\x07\x7A\x80\x07\x7A\x80\x07\x6D\x90\x0E\x78\xA0\x07\x78\xA0\x07\x78\xD0" \
+ "\x06\xE9\x10\x07\x76\xA0\x07\x71\x60\x07\x7A\x10\x07\x76\xD0\x06\xE9\x30\x07\x72" \
+ "\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06\xE9\x60\x07\x74\xA0\x07\x76\x40\x07" \
+ "\x7A\x60\x07\x74\xD0\x06\xE6\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0" \
+ "\x06\xE6\x60\x07\x74\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x60\x07\x74" \
+ "\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x10\x07\x72\x80\x07\x7A\x60\x07" \
+ "\x74\xA0\x07\x71\x20\x07\x78\xD0\x06\xE1\x00\x07\x7A\x00\x07\x7A\x60\x07\x74\xD0" \
+ "\x06\xEE\x30\x07\x72\xD0\x06\xB3\x60\x07\x74\x30\x44\x29\x00\x00\x08\x00\x00\x00" \
+ "\x80\x21\x4A\x02\x04\x00\x00\x00\x00\x00\x0C\x51\x18\x20\x00\x00\x00\x00\x00\x60" \
+ "\x88\xE2\x00\x01\x00\x00\x00\x00\x00\x79\x18\x00\x45\x00\x00\x00\x43\x88\x27\x78" \
+ "\x84\x05\x87\x3D\x94\x83\x3C\xCC\x43\x3A\xBC\x83\x3B\x2C\x08\xE2\x60\x08\xF1\x10" \
+ "\x4F\xB1\x20\x52\x87\x70\xB0\x87\x70\xF8\x05\x78\x08\x87\x71\x58\x87\x70\x38\x87" \
+ "\x72\xF8\x05\x77\x08\x87\x76\x28\x87\x05\x63\x30\x0E\xEF\xD0\x0E\x6E\x50\x0E\xF8" \
+ "\x10\x0E\xED\x00\x0F\xEC\x50\x0E\x6E\x10\x0E\xEE\x40\x0E\xF2\xF0\x0E\xE9\x40\x0E" \
+ "\x6E\x20\x0F\xF3\xE0\x06\xE8\x50\x0E\xEC\xC0\x0E\xEF\x30\x0E\xEF\xD0\x0E\xF0\x50" \
+ "\x0F\xF4\x50\x0E\x43\x84\xE7\x58\x40\xC8\xC3\x3B\xBC\x03\x3D\x0C\x11\x9E\x64\x41" \
+ "\x30\x07\x43\x88\x67\x79\x98\x05\xCF\x3B\xB4\x83\x3B\xA4\x03\x3C\xBC\x03\x3D\x94" \
+ "\x83\x3B\xD0\x03\x18\x8C\x03\x3A\x84\x83\x3C\x0C\x21\x9E\x06\x00\x16\x44\xB3\x90" \
+ "\x0E\xED\x00\x0F\xEC\x50\x0E\x60\x30\x0A\x6F\x30\x0A\x6B\xB0\x06\x60\x40\x0B\xA2" \
+ "\x10\x0A\xA1\x30\xE2\x18\x03\x78\x90\x87\x70\x38\x87\x76\x08\x87\x29\x02\x30\x8C" \
+ "\xB8\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE" \
+ "\x41\x1E\xCA\x21\x1C\xC6\x01\x1D\x7E\xC1\x1D\xC2\xA1\x1D\xCA\x61\x4A\x60\x8C\x90" \
+ "\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE\x41" \
+ "\x1E\xCA\x21\x1C\xC6\x01\x1D\xA6\x04\x08\x00\x00\x61\x20\x00\x00\x24\x00\x00\x00" \
+ "\x13\x04\x41\x2C\x10\x00\x00\x00\x0C\x00\x00\x00\x04\x8B\xA0\x04\x46\x00\xE8\xCC" \
+ "\x00\x90\x9A\x01\x98\x63\x70\x1A\x86\xCC\x18\x41\x6D\xFA\xB2\xEF\x8D\x11\x88\x6D" \
+ "\xCC\xC6\xDF\x18\xC1\x49\x97\x72\xFA\x51\x9C\x63\x40\x0E\x63\x04\x00\x00\x00\x00" \
+ "\x44\x8C\x11\x03\x42\x08\x82\x68\x90\x41\x4A\x9E\x11\x83\x42\x08\x84\x69\x99\x63" \
+ "\x50\x28\x64\x90\xA1\x52\xA0\x11\x03\x42\x08\x06\x6B\x30\xA2\xB8\x06\x00\xC3\x81" \
+ "\x00\x00\x00\x00\x03\x00\x00\x00\x46\x40\x54\x3F\xD2\x58\x41\x51\xFD\x0E\x35\x01" \
+ "\x01\x31\x00\x00\x03\x00\x00\x00\x5B\x06\x20\x50\xB6\x0C\x47\xA0\x00\x00\x00\x00" \
+ "\x00\x00\x00\x00\x79\x18\x00\x00\x0B\x00\x00\x00\x33\x08\x80\x1C\xC4\xE1\x1C\x66" \
+ "\x14\x01\x3D\x88\x43\x38\x84\xC3\x8C\x42\x80\x07\x79\x78\x07\x73\x98\xB1\x0C\xE6" \
+ "\x00\x0F\xE1\x30\x0E\xE3\x50\x0F\xF2\x10\x0E\xE3\x90\x0F\x00\x00\x71\x20\x00\x00" \
+ "\x0E\x00\x00\x00\x06\x40\x44\x8E\x33\x59\x40\x14\x49\x6E\xF3\x00\x82\xC2\x39\x8B" \
+ "\x13\xF1\x3C\xCF\x9B\x40\xF3\xCF\xF7\xE0\x4C\x5D\x75\xFF\x05\xFB\xDB\x80\xF6\xCF" \
+ "\xF5\x1E\x49\x29\x20\x28\x9C\xB3\x38\x51\xEB\xF0\x3C\xCF\x77\xD5\xFD\x17\x00\x00" \
+ "\x00\x00\x00\x00";
+
+
+ScriptC_mono::ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :
+ ScriptC(rs, mono, sizeof(mono) - 1, "mono", 4, cacheDir, cacheDirLength) {
+
+ printf("sizeof text %i", sizeof(mono));
+
+
+
+}
+
+void ScriptC_mono::forEach_root(const Allocation *ain, const Allocation *aout) {
+ forEach(0, ain, aout, NULL, 0);
+}
+
diff --git a/include/ui/android_native_buffer.h b/libs/rs/tests/ScriptC_mono.h
index b6e1db460063..7e4f601e78fd 100644
--- a/include/ui/android_native_buffer.h
+++ b/libs/rs/tests/ScriptC_mono.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2008-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.
@@ -14,9 +14,13 @@
* limitations under the License.
*/
-#ifndef ANDROID_ANDROID_NATIVES_PRIV_H
-#define ANDROID_ANDROID_NATIVES_PRIV_H
+#include "ScriptC.h"
-#include <ui/egl/android_natives.h>
+class ScriptC_mono : protected ScriptC {
+public:
+ ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength);
+
+ void forEach_root(const Allocation *ain, const Allocation *aout);
+
+};
-#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */
diff --git a/libs/rs/tests/compute.cpp b/libs/rs/tests/compute.cpp
new file mode 100644
index 000000000000..42eaa52009fb
--- /dev/null
+++ b/libs/rs/tests/compute.cpp
@@ -0,0 +1,58 @@
+
+#include "RenderScript.h"
+#include "Element.h"
+#include "Type.h"
+#include "Allocation.h"
+
+#include "ScriptC_mono.h"
+
+int main(int argc, char** argv)
+{
+
+ RenderScript *rs = new RenderScript();
+ printf("New RS %p\n", rs);
+
+ bool r = rs->init(16);
+ printf("Init returned %i\n", r);
+
+ const Element *e = Element::RGBA_8888(rs);
+ printf("Element %p\n", e);
+
+ Type::Builder tb(rs, e);
+ tb.setX(128);
+ tb.setY(128);
+ const Type *t = tb.create();
+ printf("Type %p\n", t);
+
+
+ Allocation *a1 = Allocation::createSized(rs, e, 1000);
+ printf("Allocation %p\n", a1);
+
+ Allocation *ain = Allocation::createTyped(rs, t);
+ Allocation *aout = Allocation::createTyped(rs, t);
+ printf("Allocation %p %p\n", ain, aout);
+
+ ScriptC_mono * sc = new ScriptC_mono(rs, NULL, 0);
+ printf("new script\n");
+
+ uint32_t *buf = new uint32_t[t->getCount()];
+ for (uint32_t ct=0; ct < t->getCount(); ct++) {
+ buf[ct] = ct | (ct << 16);
+ }
+ //ain->copy1DRangeFrom(0, 128*128, (int32_t *)buf, 128*128*4);
+ ain->copy1DRangeFromUnchecked(0, t->getCount(), buf, t->getCount()*4);
+
+
+
+ sc->forEach_root(ain, aout);
+ printf("for each done\n");
+
+
+ printf("Deleting stuff\n");
+ delete sc;
+ delete t;
+ delete a1;
+ delete e;
+ delete rs;
+ printf("Delete OK\n");
+}
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
deleted file mode 100644
index 5fca1ce5b3bb..000000000000
--- a/libs/surfaceflinger_client/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=
-
-LOCAL_SHARED_LIBRARIES :=
-
-LOCAL_MODULE:= libsurfaceflinger_client
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index f0d7b02e67b5..5aff7a461442 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -16,7 +16,6 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- EGLUtils.cpp \
FramebufferNativeWindow.cpp \
GraphicBuffer.cpp \
GraphicBufferAllocator.cpp \
@@ -28,9 +27,12 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
- libEGL \
libhardware
+ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
+LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
+endif
+
LOCAL_MODULE:= libui
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index d1dca0c906db..dec99b6c7064 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -27,25 +27,21 @@
#include <utils/threads.h>
#include <utils/RefBase.h>
-#include <ui/Rect.h>
+#include <ui/ANativeObjectBase.h>
#include <ui/FramebufferNativeWindow.h>
+#include <ui/Rect.h>
#include <EGL/egl.h>
-#include <pixelflinger/format.h>
-#include <pixelflinger/pixelflinger.h>
-
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
-#include <private/ui/android_natives_priv.h>
-
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
class NativeBuffer
- : public EGLNativeBase<
+ : public ANativeObjectBase<
ANativeWindowBuffer,
NativeBuffer,
LightRefBase<NativeBuffer> >
@@ -100,6 +96,18 @@ FramebufferNativeWindow::FramebufferNativeWindow()
mNumFreeBuffers = NUM_FRAME_BUFFERS;
mBufferHead = mNumBuffers-1;
+ /*
+ * This does not actually change the framebuffer format. It merely
+ * fakes this format to surfaceflinger so that when it creates
+ * framebuffer surfaces it will use this format. It's really a giant
+ * HACK to allow interworking with buggy gralloc+GPU driver
+ * implementations. You should *NEVER* need to set this for shipping
+ * devices.
+ */
+#ifdef FRAMEBUFFER_FORCE_FORMAT
+ *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT;
+#endif
+
for (i = 0; i < mNumBuffers; i++)
{
buffers[i] = new NativeBuffer(
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index f549a3795f0e..57063e524620 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -28,8 +28,6 @@
#include <ui/GraphicBufferMapper.h>
#include <ui/PixelFormat.h>
-#include <pixelflinger/pixelflinger.h>
-
namespace android {
// ===========================================================================
@@ -182,21 +180,6 @@ status_t GraphicBuffer::unlock()
return res;
}
-status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage)
-{
- void* vaddr;
- status_t res = GraphicBuffer::lock(usage, &vaddr);
- if (res == NO_ERROR && sur) {
- sur->version = sizeof(GGLSurface);
- sur->width = width;
- sur->height = height;
- sur->stride = stride;
- sur->format = format;
- sur->data = static_cast<GGLubyte*>(vaddr);
- }
- return res;
-}
-
size_t GraphicBuffer::getFlattenedSize() const {
return (8 + (handle ? handle->numInts : 0))*sizeof(int);
}
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 6993dac6998a..fc1d3c29db11 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -48,7 +48,10 @@ static Info const sPixelFormatInfos[] = {
{ 4, 32, {32,24, 24,16, 16, 8, 8, 0 }, PixelFormatInfo::RGBA },
{ 2, 16, { 1, 0, 16,11, 11, 6, 6, 1 }, PixelFormatInfo::RGBA },
{ 2, 16, { 4, 0, 16,12, 12, 8, 8, 4 }, PixelFormatInfo::RGBA },
- { 1, 8, { 8, 0, 0, 0, 0, 0, 0, 0 }, PixelFormatInfo::ALPHA}
+ { 1, 8, { 8, 0, 0, 0, 0, 0, 0, 0 }, PixelFormatInfo::ALPHA},
+ { 1, 8, { 0, 0, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::L },
+ { 2, 16, {16, 8, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::LA },
+ { 1, 8, { 0, 0, 8, 5, 5, 2, 2, 0 }, PixelFormatInfo::RGB },
};
static const Info* gGetPixelFormatTable(size_t* numEntries) {
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index a96c8e604d2e..57c048a3eaa2 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -77,7 +77,8 @@ include $(CLEAR_VARS)
# we have the common sources, plus some device-specific stuff
LOCAL_SRC_FILES:= \
$(commonSources) \
- Looper.cpp
+ Looper.cpp \
+ Trace.cpp
ifeq ($(TARGET_OS),linux)
LOCAL_LDLIBS += -lrt -ldl
diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp
new file mode 100644
index 000000000000..c49278ae45fb
--- /dev/null
+++ b/libs/utils/Trace.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#include <cutils/properties.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+namespace android {
+
+volatile int32_t Tracer::sIsReady = 0;
+int Tracer::sTraceFD = -1;
+uint64_t Tracer::sEnabledTags = 0;
+Mutex Tracer::sMutex;
+
+void Tracer::init() {
+ Mutex::Autolock lock(sMutex);
+
+ if (!sIsReady) {
+ const char* const traceFileName =
+ "/sys/kernel/debug/tracing/trace_marker";
+ sTraceFD = open(traceFileName, O_WRONLY);
+ if (sTraceFD == -1) {
+ ALOGE("error opening trace file: %s (%d)", strerror(errno), errno);
+ } else {
+ char value[PROPERTY_VALUE_MAX];
+ property_get("atrace.tags.enableflags", value, "0");
+ sEnabledTags = strtoll(value, NULL, 0) | ATRACE_TAG_ALWAYS;
+ }
+
+ android_atomic_release_store(1, &sIsReady);
+ }
+}
+
+} // namespace andoid
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
new file mode 100644
index 000000000000..7f496ca41cf0
--- /dev/null
+++ b/media/java/android/media/MediaCodec.java
@@ -0,0 +1,210 @@
+/*
+ * 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.media;
+
+import android.view.Surface;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+/**
+ * MediaCodec class can be used to access low-level media codec, i.e.
+ * encoder/decoder components.
+ * @hide
+*/
+public class MediaCodec
+{
+ /** Per buffer metadata includes an offset and size specifying
+ the range of valid data in the associated codec buffer.
+ */
+ public final static class BufferInfo {
+ public void set(
+ int offset, int size, long timeUs, int flags) {
+ mOffset = offset;
+ mSize = size;
+ mPresentationTimeUs = timeUs;
+ mFlags = flags;
+ }
+
+ public int mOffset;
+ public int mSize;
+ public long mPresentationTimeUs;
+ public int mFlags;
+ };
+
+ public static int FLAG_SYNCFRAME = 1;
+ public static int FLAG_CODECCONFIG = 2;
+ public static int FLAG_EOS = 4;
+
+ /** Instantiate a codec component by mime type. For decoder components
+ this is the mime type of media that this decoder should be able to
+ decoder, for encoder components it's the type of media this encoder
+ should encode _to_.
+ */
+ public static MediaCodec CreateByType(String type, boolean encoder) {
+ return new MediaCodec(type, true /* nameIsType */, encoder);
+ }
+
+ /** If you know the exact name of the component you want to instantiate
+ use this method to instantiate it. Use with caution.
+ */
+ public static MediaCodec CreateByComponentName(String name) {
+ return new MediaCodec(
+ name, false /* nameIsType */, false /* unused */);
+ }
+
+ private MediaCodec(
+ String name, boolean nameIsType, boolean encoder) {
+ native_setup(name, nameIsType, encoder);
+ }
+
+ @Override
+ protected void finalize() {
+ native_finalize();
+ }
+
+ // Make sure you call this when you're done to free up any opened
+ // component instance instead of relying on the garbage collector
+ // to do this for you at some point in the future.
+ public native final void release();
+
+ public static int CONFIGURE_FLAG_ENCODE = 1;
+
+ /** Configures a component.
+ * @param format A map of string/value pairs describing the input format
+ * (decoder) or the desired output format.
+ *
+ * Video formats have the following fields:
+ * "mime" - String
+ * "width" - Integer
+ * "height" - Integer
+ * optional "max-input-size" - Integer
+ * optional "csd-0", "csd-1" ... - ByteBuffer
+ *
+ * Audio formats have the following fields:
+ * "mime" - String
+ * "channel-count" - Integer
+ * "sample-rate" - Integer
+ * optional "max-input-size" - Integer
+ * optional "csd-0", "csd-1" ... - ByteBuffer
+ *
+ * If the format is used to configure an encoder, additional
+ * fields must be included:
+ * "bitrate" - Integer (in bits/sec)
+ *
+ * for video formats:
+ * "color-format" - Integer
+ * "frame-rate" - Integer or Float
+ * "i-frame-interval" - Integer
+ * optional "stride" - Integer, defaults to "width"
+ * optional "slice-height" - Integer, defaults to "height"
+ *
+ * @param surface Specify a surface on which to render the output of this
+ * decoder.
+ * @param flags Specify {@see #CONFIGURE_FLAG_ENCODE} to configure the
+ * component as an encoder.
+ */
+ public void configure(
+ Map<String, Object> format, Surface surface, int flags) {
+ String[] keys = null;
+ Object[] values = null;
+
+ if (format != null) {
+ keys = new String[format.size()];
+ values = new Object[format.size()];
+
+ int i = 0;
+ for (Map.Entry<String, Object> entry: format.entrySet()) {
+ keys[i] = entry.getKey();
+ values[i] = entry.getValue();
+ ++i;
+ }
+ }
+
+ native_configure(keys, values, surface, flags);
+ }
+
+ private native final void native_configure(
+ String[] keys, Object[] values, Surface surface, int flags);
+
+ /** After successfully configuring the component, call start. On return
+ * you can query the component for its input/output buffers.
+ */
+ public native final void start();
+
+ public native final void stop();
+
+ /** Flush both input and output ports of the component, all indices
+ * previously returned in calls to dequeueInputBuffer and
+ * dequeueOutputBuffer become invalid.
+ */
+ public native final void flush();
+
+ /** After filling a range of the input buffer at the specified index
+ * submit it to the component.
+ */
+ public native final void queueInputBuffer(
+ int index,
+ int offset, int size, long presentationTimeUs, int flags);
+
+ // Returns the index of an input buffer to be filled with valid data
+ // or -1 if no such buffer is currently available.
+ // This method will return immediately if timeoutUs == 0, wait indefinitely
+ // for the availability of an input buffer if timeoutUs < 0 or wait up
+ // to "timeoutUs" microseconds if timeoutUs > 0.
+ public native final int dequeueInputBuffer(long timeoutUs);
+
+ // Returns the index of an output buffer that has been successfully
+ // decoded or one of the INFO_* constants below.
+ // The provided "info" will be filled with buffer meta data.
+ public static final int INFO_TRY_AGAIN_LATER = -1;
+ public static final int INFO_OUTPUT_FORMAT_CHANGED = -2;
+ public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;
+
+ /** Dequeue an output buffer, block at most "timeoutUs" microseconds. */
+ public native final int dequeueOutputBuffer(
+ BufferInfo info, long timeoutUs);
+
+ // If you are done with a buffer, use this call to return the buffer to
+ // the codec. If you previously specified a surface when configuring this
+ // video decoder you can optionally render the buffer.
+ public native final void releaseOutputBuffer(int index, boolean render);
+
+ /** Call this after dequeueOutputBuffer signals a format change by returning
+ * {@see #INFO_OUTPUT_FORMAT_CHANGED}
+ */
+ public native final Map<String, Object> getOutputFormat();
+
+ /** Call this after start() returns and whenever dequeueOutputBuffer
+ * signals an output buffer change by returning
+ * {@see #INFO_OUTPUT_BUFFERS_CHANGED}
+ */
+ public native final ByteBuffer[] getBuffers(boolean input);
+
+ private static native final void native_init();
+
+ private native final void native_setup(
+ String name, boolean nameIsType, boolean encoder);
+
+ private native final void native_finalize();
+
+ static {
+ System.loadLibrary("media_jni");
+ native_init();
+ }
+
+ private int mNativeContext;
+}
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
new file mode 100644
index 000000000000..6a7f2f57f3dc
--- /dev/null
+++ b/media/java/android/media/MediaExtractor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.media;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+/**
+ * MediaExtractor
+ * @hide
+*/
+public class MediaExtractor
+{
+ public MediaExtractor(String path) {
+ native_setup(path);
+ }
+
+ @Override
+ protected void finalize() {
+ native_finalize();
+ }
+
+ // Make sure you call this when you're done to free up any resources
+ // instead of relying on the garbage collector to do this for you at
+ // some point in the future.
+ public native final void release();
+
+ public native int countTracks();
+ public native Map<String, Object> getTrackFormat(int index);
+
+ // Subsequent calls to "readSampleData", "getSampleTrackIndex" and
+ // "getSampleTime" only retrieve information for the subset of tracks
+ // selected by the call below.
+ // Selecting the same track multiple times has no effect, the track
+ // is only selected once.
+ public native void selectTrack(int index);
+
+ // All selected tracks seek near the requested time. The next sample
+ // returned for each selected track will be a sync sample.
+ public native void seekTo(long timeUs);
+
+ public native boolean advance();
+
+ // Retrieve the current encoded sample and store it in the byte buffer
+ // starting at the given offset.
+ public native int readSampleData(ByteBuffer byteBuf, int offset);
+
+ // Returns the track index the current sample originates from.
+ public native int getSampleTrackIndex();
+
+ // Returns the current sample's presentation time in microseconds.
+ public native long getSampleTime();
+
+ private static native final void native_init();
+ private native final void native_setup(String path);
+ private native final void native_finalize();
+
+ static {
+ System.loadLibrary("media_jni");
+ native_init();
+ }
+
+ private int mNativeContext;
+}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 23cc0e2f3228..070d2d93a8c2 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -2,6 +2,8 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
+ android_media_MediaCodec.cpp \
+ android_media_MediaExtractor.cpp \
android_media_MediaPlayer.cpp \
android_media_MediaRecorder.cpp \
android_media_MediaScanner.cpp \
@@ -25,6 +27,7 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \
libgui \
libstagefright \
+ libstagefright_foundation \
libcamera_client \
libmtp \
libusbhost \
@@ -39,10 +42,12 @@ LOCAL_C_INCLUDES += \
external/tremor/Tremor \
frameworks/base/core/jni \
frameworks/base/media/libmedia \
+ frameworks/base/media/libstagefright \
frameworks/base/media/libstagefright/codecs/amrnb/enc/src \
frameworks/base/media/libstagefright/codecs/amrnb/common \
frameworks/base/media/libstagefright/codecs/amrnb/common/include \
frameworks/base/media/mtp \
+ frameworks/base/include/media/stagefright/openmax \
$(PV_INCLUDES) \
$(JNI_H_INCLUDE) \
$(call include-path-for, corecg graphics)
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
new file mode 100644
index 000000000000..675339eee70e
--- /dev/null
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -0,0 +1,552 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaCodec-JNI"
+#include <utils/Log.h>
+
+#include "android_media_MediaCodec.h"
+
+#include "android_media_Utils.h"
+#include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/android_view_Surface.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <gui/Surface.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+// Keep these in sync with their equivalents in MediaCodec.java !!!
+enum {
+ DEQUEUE_INFO_TRY_AGAIN_LATER = -1,
+ DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED = -2,
+ DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED = -3,
+};
+
+struct fields_t {
+ jfieldID context;
+};
+
+static fields_t gFields;
+
+////////////////////////////////////////////////////////////////////////////////
+
+JMediaCodec::JMediaCodec(
+ JNIEnv *env, jobject thiz,
+ const char *name, bool nameIsType, bool encoder)
+ : mClass(NULL),
+ mObject(NULL) {
+ jclass clazz = env->GetObjectClass(thiz);
+ CHECK(clazz != NULL);
+
+ mClass = (jclass)env->NewGlobalRef(clazz);
+ mObject = env->NewWeakGlobalRef(thiz);
+
+ mLooper = new ALooper;
+ mLooper->setName("MediaCodec_looper");
+
+ mLooper->start(
+ false, // runOnCallingThread
+ false, // canCallJava
+ PRIORITY_DEFAULT);
+
+ if (nameIsType) {
+ mCodec = MediaCodec::CreateByType(mLooper, name, encoder);
+ } else {
+ mCodec = MediaCodec::CreateByComponentName(mLooper, name);
+ }
+}
+
+status_t JMediaCodec::initCheck() const {
+ return mCodec != NULL ? OK : NO_INIT;
+}
+
+JMediaCodec::~JMediaCodec() {
+ mCodec->stop();
+
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ env->DeleteWeakGlobalRef(mObject);
+ mObject = NULL;
+ env->DeleteGlobalRef(mClass);
+ mClass = NULL;
+}
+
+status_t JMediaCodec::configure(
+ const sp<AMessage> &format,
+ const sp<ISurfaceTexture> &surfaceTexture,
+ int flags) {
+ sp<SurfaceTextureClient> client;
+ if (surfaceTexture != NULL) {
+ client = new SurfaceTextureClient(surfaceTexture);
+ }
+ return mCodec->configure(format, client, flags);
+}
+
+status_t JMediaCodec::start() {
+ return mCodec->start();
+}
+
+status_t JMediaCodec::stop() {
+ return mCodec->stop();
+}
+
+status_t JMediaCodec::flush() {
+ return mCodec->flush();
+}
+
+status_t JMediaCodec::queueInputBuffer(
+ size_t index,
+ size_t offset, size_t size, int64_t timeUs, uint32_t flags) {
+ return mCodec->queueInputBuffer(index, offset, size, timeUs, flags);
+}
+
+status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
+ return mCodec->dequeueInputBuffer(index, timeoutUs);
+}
+
+status_t JMediaCodec::dequeueOutputBuffer(
+ JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs) {
+ size_t size, offset;
+ int64_t timeUs;
+ uint32_t flags;
+ status_t err;
+ if ((err = mCodec->dequeueOutputBuffer(
+ index, &size, &offset, &timeUs, &flags, timeoutUs)) != OK) {
+ return err;
+ }
+
+ jclass clazz = env->FindClass("android/media/MediaCodec$BufferInfo");
+
+ jmethodID method = env->GetMethodID(clazz, "set", "(IIJI)V");
+ env->CallVoidMethod(bufferInfo, method, offset, size, timeUs, flags);
+
+ return OK;
+}
+
+status_t JMediaCodec::releaseOutputBuffer(size_t index, bool render) {
+ return render
+ ? mCodec->renderOutputBufferAndRelease(index)
+ : mCodec->releaseOutputBuffer(index);
+}
+
+status_t JMediaCodec::getOutputFormat(JNIEnv *env, jobject *format) const {
+ sp<AMessage> msg;
+ status_t err;
+ if ((err = mCodec->getOutputFormat(&msg)) != OK) {
+ return err;
+ }
+
+ return ConvertMessageToMap(env, msg, format);
+}
+
+status_t JMediaCodec::getBuffers(
+ JNIEnv *env, bool input, jobjectArray *bufArray) const {
+ Vector<sp<ABuffer> > buffers;
+
+ status_t err =
+ input
+ ? mCodec->getInputBuffers(&buffers)
+ : mCodec->getOutputBuffers(&buffers);
+
+ if (err != OK) {
+ return err;
+ }
+
+ jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer");
+
+ *bufArray = (jobjectArray)env->NewObjectArray(
+ buffers.size(), byteBufferClass, NULL);
+
+ for (size_t i = 0; i < buffers.size(); ++i) {
+ const sp<ABuffer> &buffer = buffers.itemAt(i);
+
+ jobject byteBuffer =
+ env->NewDirectByteBuffer(
+ buffer->base(),
+ buffer->capacity());
+
+ env->SetObjectArrayElement(
+ *bufArray, i, byteBuffer);
+
+ env->DeleteLocalRef(byteBuffer);
+ byteBuffer = NULL;
+ }
+
+ return OK;
+}
+
+} // namespace android
+
+////////////////////////////////////////////////////////////////////////////////
+
+using namespace android;
+
+static sp<JMediaCodec> setMediaCodec(
+ JNIEnv *env, jobject thiz, const sp<JMediaCodec> &codec) {
+ sp<JMediaCodec> old = (JMediaCodec *)env->GetIntField(thiz, gFields.context);
+ if (codec != NULL) {
+ codec->incStrong(thiz);
+ }
+ if (old != NULL) {
+ old->decStrong(thiz);
+ }
+ env->SetIntField(thiz, gFields.context, (int)codec.get());
+
+ return old;
+}
+
+static sp<JMediaCodec> getMediaCodec(JNIEnv *env, jobject thiz) {
+ return (JMediaCodec *)env->GetIntField(thiz, gFields.context);
+}
+
+static void android_media_MediaCodec_release(JNIEnv *env, jobject thiz) {
+ setMediaCodec(env, thiz, NULL);
+}
+
+static jint throwExceptionAsNecessary(JNIEnv *env, status_t err) {
+ switch (err) {
+ case OK:
+ return 0;
+
+ case -EAGAIN:
+ return DEQUEUE_INFO_TRY_AGAIN_LATER;
+
+ case INFO_FORMAT_CHANGED:
+ return DEQUEUE_INFO_OUTPUT_FORMAT_CHANGED;
+
+ case INFO_OUTPUT_BUFFERS_CHANGED:
+ return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;
+
+ default:
+ {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void android_media_MediaCodec_native_configure(
+ JNIEnv *env,
+ jobject thiz,
+ jobjectArray keys, jobjectArray values,
+ jobject jsurface,
+ jint flags) {
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ sp<AMessage> format;
+ status_t err = ConvertKeyValueArraysToMessage(env, keys, values, &format);
+
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ sp<ISurfaceTexture> surfaceTexture;
+ if (jsurface != NULL) {
+ sp<Surface> surface(Surface_getSurface(env, jsurface));
+ if (surface != NULL) {
+ surfaceTexture = surface->getSurfaceTexture();
+ } else {
+ jniThrowException(
+ env,
+ "java/lang/IllegalArgumentException",
+ "The surface has been released");
+ return;
+ }
+ }
+
+ err = codec->configure(format, surfaceTexture, flags);
+
+ throwExceptionAsNecessary(env, err);
+}
+
+static void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
+ ALOGV("android_media_MediaCodec_start");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = codec->start();
+
+ throwExceptionAsNecessary(env, err);
+}
+
+static void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
+ ALOGV("android_media_MediaCodec_stop");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = codec->stop();
+
+ throwExceptionAsNecessary(env, err);
+}
+
+static void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) {
+ ALOGV("android_media_MediaCodec_flush");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = codec->flush();
+
+ throwExceptionAsNecessary(env, err);
+}
+
+static void android_media_MediaCodec_queueInputBuffer(
+ JNIEnv *env,
+ jobject thiz,
+ jint index,
+ jint offset,
+ jint size,
+ jlong timestampUs,
+ jint flags) {
+ ALOGV("android_media_MediaCodec_queueInputBuffer");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = codec->queueInputBuffer(
+ index, offset, size, timestampUs, flags);
+
+ throwExceptionAsNecessary(env, err);
+}
+
+static jint android_media_MediaCodec_dequeueInputBuffer(
+ JNIEnv *env, jobject thiz, jlong timeoutUs) {
+ ALOGV("android_media_MediaCodec_dequeueInputBuffer");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1;
+ }
+
+ size_t index;
+ status_t err = codec->dequeueInputBuffer(&index, timeoutUs);
+
+ if (err == OK) {
+ return index;
+ }
+
+ return throwExceptionAsNecessary(env, err);
+}
+
+static jint android_media_MediaCodec_dequeueOutputBuffer(
+ JNIEnv *env, jobject thiz, jobject bufferInfo, jlong timeoutUs) {
+ ALOGV("android_media_MediaCodec_dequeueOutputBuffer");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+
+ size_t index;
+ status_t err = codec->dequeueOutputBuffer(
+ env, bufferInfo, &index, timeoutUs);
+
+ if (err == OK) {
+ return index;
+ }
+
+ return throwExceptionAsNecessary(env, err);
+}
+
+static void android_media_MediaCodec_releaseOutputBuffer(
+ JNIEnv *env, jobject thiz, jint index, jboolean render) {
+ ALOGV("android_media_MediaCodec_renderOutputBufferAndRelease");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = codec->releaseOutputBuffer(index, render);
+
+ throwExceptionAsNecessary(env, err);
+}
+
+static jobject android_media_MediaCodec_getOutputFormat(
+ JNIEnv *env, jobject thiz) {
+ ALOGV("android_media_MediaCodec_getOutputFormat");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+
+ jobject format;
+ status_t err = codec->getOutputFormat(env, &format);
+
+ if (err == OK) {
+ return format;
+ }
+
+ throwExceptionAsNecessary(env, err);
+
+ return NULL;
+}
+
+static jobjectArray android_media_MediaCodec_getBuffers(
+ JNIEnv *env, jobject thiz, jboolean input) {
+ ALOGV("android_media_MediaCodec_getBuffers");
+
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+ if (codec == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+
+ jobjectArray buffers;
+ status_t err = codec->getBuffers(env, input, &buffers);
+
+ if (err == OK) {
+ return buffers;
+ }
+
+ throwExceptionAsNecessary(env, err);
+
+ return NULL;
+}
+
+static void android_media_MediaCodec_native_init(JNIEnv *env) {
+ jclass clazz = env->FindClass("android/media/MediaCodec");
+ CHECK(clazz != NULL);
+
+ gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+ CHECK(gFields.context != NULL);
+}
+
+static void android_media_MediaCodec_native_setup(
+ JNIEnv *env, jobject thiz,
+ jstring name, jboolean nameIsType, jboolean encoder) {
+ if (name == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ const char *tmp = env->GetStringUTFChars(name, NULL);
+
+ if (tmp == NULL) {
+ return;
+ }
+
+ sp<JMediaCodec> codec = new JMediaCodec(env, thiz, tmp, nameIsType, encoder);
+
+ status_t err = codec->initCheck();
+
+ env->ReleaseStringUTFChars(name, tmp);
+ tmp = NULL;
+
+ if (err != OK) {
+ jniThrowException(
+ env,
+ "java/io/IOException",
+ "Failed to allocate component instance");
+ return;
+ }
+
+ setMediaCodec(env,thiz, codec);
+}
+
+static void android_media_MediaCodec_native_finalize(
+ JNIEnv *env, jobject thiz) {
+ android_media_MediaCodec_release(env, thiz);
+}
+
+static JNINativeMethod gMethods[] = {
+ { "release", "()V", (void *)android_media_MediaCodec_release },
+
+ { "native_configure",
+ "([Ljava/lang/String;[Ljava/lang/Object;Landroid/view/Surface;I)V",
+ (void *)android_media_MediaCodec_native_configure },
+
+ { "start", "()V", (void *)android_media_MediaCodec_start },
+ { "stop", "()V", (void *)android_media_MediaCodec_stop },
+ { "flush", "()V", (void *)android_media_MediaCodec_flush },
+
+ { "queueInputBuffer", "(IIIJI)V",
+ (void *)android_media_MediaCodec_queueInputBuffer },
+
+ { "dequeueInputBuffer", "(J)I",
+ (void *)android_media_MediaCodec_dequeueInputBuffer },
+
+ { "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I",
+ (void *)android_media_MediaCodec_dequeueOutputBuffer },
+
+ { "releaseOutputBuffer", "(IZ)V",
+ (void *)android_media_MediaCodec_releaseOutputBuffer },
+
+ { "getOutputFormat", "()Ljava/util/Map;",
+ (void *)android_media_MediaCodec_getOutputFormat },
+
+ { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;",
+ (void *)android_media_MediaCodec_getBuffers },
+
+ { "native_init", "()V", (void *)android_media_MediaCodec_native_init },
+
+ { "native_setup", "(Ljava/lang/String;ZZ)V",
+ (void *)android_media_MediaCodec_native_setup },
+
+ { "native_finalize", "()V",
+ (void *)android_media_MediaCodec_native_finalize },
+};
+
+int register_android_media_MediaCodec(JNIEnv *env) {
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/media/MediaCodec", gMethods, NELEM(gMethods));
+}
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
new file mode 100644
index 000000000000..6b1257db74b1
--- /dev/null
+++ b/media/jni/android_media_MediaCodec.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIACODEC_H_
+#define _ANDROID_MEDIA_MEDIACODEC_H_
+
+#include "jni.h"
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct ALooper;
+struct AMessage;
+struct ISurfaceTexture;
+struct MediaCodec;
+
+struct JMediaCodec : public RefBase {
+ JMediaCodec(
+ JNIEnv *env, jobject thiz,
+ const char *name, bool nameIsType, bool encoder);
+
+ status_t initCheck() const;
+
+ status_t configure(
+ const sp<AMessage> &format,
+ const sp<ISurfaceTexture> &surfaceTexture,
+ int flags);
+
+ status_t start();
+ status_t stop();
+
+ status_t flush();
+
+ status_t queueInputBuffer(
+ size_t index,
+ size_t offset, size_t size, int64_t timeUs, uint32_t flags);
+
+ status_t dequeueInputBuffer(size_t *index, int64_t timeoutUs);
+
+ status_t dequeueOutputBuffer(
+ JNIEnv *env, jobject bufferInfo, size_t *index, int64_t timeoutUs);
+
+ status_t releaseOutputBuffer(size_t index, bool render);
+
+ status_t getOutputFormat(JNIEnv *env, jobject *format) const;
+
+ status_t getBuffers(
+ JNIEnv *env, bool input, jobjectArray *bufArray) const;
+
+protected:
+ virtual ~JMediaCodec();
+
+private:
+ jclass mClass;
+ jweak mObject;
+
+ sp<ALooper> mLooper;
+ sp<MediaCodec> mCodec;
+
+ DISALLOW_EVIL_CONSTRUCTORS(JMediaCodec);
+};
+
+} // namespace android
+
+#endif // _ANDROID_MEDIA_MEDIACODEC_H_
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
new file mode 100644
index 000000000000..4757adfc6429
--- /dev/null
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -0,0 +1,400 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaExtractor-JNI"
+#include <utils/Log.h>
+
+#include "android_media_MediaExtractor.h"
+
+#include "android_media_Utils.h"
+#include "android_runtime/AndroidRuntime.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/NuMediaExtractor.h>
+
+namespace android {
+
+struct fields_t {
+ jfieldID context;
+};
+
+static fields_t gFields;
+
+////////////////////////////////////////////////////////////////////////////////
+
+JMediaExtractor::JMediaExtractor(JNIEnv *env, jobject thiz)
+ : mClass(NULL),
+ mObject(NULL) {
+ jclass clazz = env->GetObjectClass(thiz);
+ CHECK(clazz != NULL);
+
+ mClass = (jclass)env->NewGlobalRef(clazz);
+ mObject = env->NewWeakGlobalRef(thiz);
+
+ mImpl = new NuMediaExtractor;
+}
+
+JMediaExtractor::~JMediaExtractor() {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ env->DeleteWeakGlobalRef(mObject);
+ mObject = NULL;
+ env->DeleteGlobalRef(mClass);
+ mClass = NULL;
+}
+
+status_t JMediaExtractor::setDataSource(const char *path) {
+ return mImpl->setDataSource(path);
+}
+
+size_t JMediaExtractor::countTracks() const {
+ return mImpl->countTracks();
+}
+
+status_t JMediaExtractor::getTrackFormat(size_t index, jobject *format) const {
+ sp<AMessage> msg;
+ status_t err;
+ if ((err = mImpl->getTrackFormat(index, &msg)) != OK) {
+ return err;
+ }
+
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ return ConvertMessageToMap(env, msg, format);
+}
+
+status_t JMediaExtractor::selectTrack(size_t index) {
+ return mImpl->selectTrack(index);
+}
+
+status_t JMediaExtractor::seekTo(int64_t timeUs) {
+ return mImpl->seekTo(timeUs);
+}
+
+status_t JMediaExtractor::advance() {
+ return mImpl->advance();
+}
+
+status_t JMediaExtractor::readSampleData(
+ jobject byteBuf, size_t offset, size_t *sampleSize) {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ void *dst = env->GetDirectBufferAddress(byteBuf);
+
+ if (dst == NULL) {
+ // XXX if dst is NULL also fall back to "array()"
+ return INVALID_OPERATION;
+ }
+
+ jlong dstSize = env->GetDirectBufferCapacity(byteBuf);
+
+ if (dstSize < offset) {
+ return -ERANGE;
+ }
+
+ sp<ABuffer> buffer = new ABuffer((char *)dst + offset, dstSize - offset);
+
+ status_t err = mImpl->readSampleData(buffer);
+
+ if (err != OK) {
+ return err;
+ }
+
+ *sampleSize = buffer->size();
+
+ return OK;
+}
+
+status_t JMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
+ return mImpl->getSampleTrackIndex(trackIndex);
+}
+
+status_t JMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
+ return mImpl->getSampleTime(sampleTimeUs);
+}
+
+} // namespace android
+
+////////////////////////////////////////////////////////////////////////////////
+
+using namespace android;
+
+static sp<JMediaExtractor> setMediaExtractor(
+ JNIEnv *env, jobject thiz, const sp<JMediaExtractor> &extractor) {
+ sp<JMediaExtractor> old =
+ (JMediaExtractor *)env->GetIntField(thiz, gFields.context);
+
+ if (extractor != NULL) {
+ extractor->incStrong(thiz);
+ }
+ if (old != NULL) {
+ old->decStrong(thiz);
+ }
+ env->SetIntField(thiz, gFields.context, (int)extractor.get());
+
+ return old;
+}
+
+static sp<JMediaExtractor> getMediaExtractor(JNIEnv *env, jobject thiz) {
+ return (JMediaExtractor *)env->GetIntField(thiz, gFields.context);
+}
+
+static void android_media_MediaExtractor_release(JNIEnv *env, jobject thiz) {
+ setMediaExtractor(env, thiz, NULL);
+}
+
+static jint android_media_MediaExtractor_countTracks(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+
+ return extractor->countTracks();
+}
+
+static jobject android_media_MediaExtractor_getTrackFormat(
+ JNIEnv *env, jobject thiz, jint index) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+
+ jobject format;
+ status_t err = extractor->getTrackFormat(index, &format);
+
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return NULL;
+ }
+
+ return format;
+}
+
+static void android_media_MediaExtractor_selectTrack(
+ JNIEnv *env, jobject thiz, jint index) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = extractor->selectTrack(index);
+
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+}
+
+static void android_media_MediaExtractor_seekTo(
+ JNIEnv *env, jobject thiz, jlong timeUs) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return;
+ }
+
+ status_t err = extractor->seekTo(timeUs);
+
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+}
+
+static jboolean android_media_MediaExtractor_advance(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return false;
+ }
+
+ status_t err = extractor->advance();
+
+ if (err == ERROR_END_OF_STREAM) {
+ return false;
+ } else if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return false;
+ }
+
+ return true;
+}
+
+static jint android_media_MediaExtractor_readSampleData(
+ JNIEnv *env, jobject thiz, jobject byteBuf, jint offset) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1;
+ }
+
+ size_t sampleSize;
+ status_t err = extractor->readSampleData(byteBuf, offset, &sampleSize);
+
+ if (err == ERROR_END_OF_STREAM) {
+ return -1;
+ } else if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return false;
+ }
+
+ return sampleSize;
+}
+
+static jint android_media_MediaExtractor_getSampleTrackIndex(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1;
+ }
+
+ size_t trackIndex;
+ status_t err = extractor->getSampleTrackIndex(&trackIndex);
+
+ if (err == ERROR_END_OF_STREAM) {
+ return -1;
+ } else if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return false;
+ }
+
+ return trackIndex;
+}
+
+static jlong android_media_MediaExtractor_getSampleTime(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1ll;
+ }
+
+ int64_t sampleTimeUs;
+ status_t err = extractor->getSampleTime(&sampleTimeUs);
+
+ if (err == ERROR_END_OF_STREAM) {
+ return -1ll;
+ } else if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return false;
+ }
+
+ return sampleTimeUs;
+}
+
+static void android_media_MediaExtractor_native_init(JNIEnv *env) {
+ jclass clazz = env->FindClass("android/media/MediaExtractor");
+ CHECK(clazz != NULL);
+
+ gFields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+ CHECK(gFields.context != NULL);
+
+ DataSource::RegisterDefaultSniffers();
+}
+
+static void android_media_MediaExtractor_native_setup(
+ JNIEnv *env, jobject thiz, jstring path) {
+ sp<JMediaExtractor> extractor = new JMediaExtractor(env, thiz);
+
+ if (path == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ const char *tmp = env->GetStringUTFChars(path, NULL);
+
+ if (tmp == NULL) {
+ return;
+ }
+
+ status_t err = extractor->setDataSource(tmp);
+
+ env->ReleaseStringUTFChars(path, tmp);
+ tmp = NULL;
+
+ if (err != OK) {
+ jniThrowException(
+ env,
+ "java/io/IOException",
+ "Failed to instantiate extractor.");
+ return;
+ }
+
+ setMediaExtractor(env,thiz, extractor);
+}
+
+static void android_media_MediaExtractor_native_finalize(
+ JNIEnv *env, jobject thiz) {
+ android_media_MediaExtractor_release(env, thiz);
+}
+
+static JNINativeMethod gMethods[] = {
+ { "release", "()V", (void *)android_media_MediaExtractor_release },
+
+ { "countTracks", "()I", (void *)android_media_MediaExtractor_countTracks },
+
+ { "getTrackFormat", "(I)Ljava/util/Map;",
+ (void *)android_media_MediaExtractor_getTrackFormat },
+
+ { "selectTrack", "(I)V", (void *)android_media_MediaExtractor_selectTrack },
+
+ { "seekTo", "(J)V", (void *)android_media_MediaExtractor_seekTo },
+
+ { "advance", "()Z", (void *)android_media_MediaExtractor_advance },
+
+ { "readSampleData", "(Ljava/nio/ByteBuffer;I)I",
+ (void *)android_media_MediaExtractor_readSampleData },
+
+ { "getSampleTrackIndex", "()I",
+ (void *)android_media_MediaExtractor_getSampleTrackIndex },
+
+ { "getSampleTime", "()J",
+ (void *)android_media_MediaExtractor_getSampleTime },
+
+ { "native_init", "()V", (void *)android_media_MediaExtractor_native_init },
+
+ { "native_setup", "(Ljava/lang/String;)V",
+ (void *)android_media_MediaExtractor_native_setup },
+
+ { "native_finalize", "()V",
+ (void *)android_media_MediaExtractor_native_finalize },
+};
+
+int register_android_media_MediaExtractor(JNIEnv *env) {
+ return AndroidRuntime::registerNativeMethods(env,
+ "android/media/MediaExtractor", gMethods, NELEM(gMethods));
+}
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
new file mode 100644
index 000000000000..70e58c6c1a26
--- /dev/null
+++ b/media/jni/android_media_MediaExtractor.h
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIAEXTRACTOR_H_
+#define _ANDROID_MEDIA_MEDIAEXTRACTOR_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include "jni.h"
+
+namespace android {
+
+struct NuMediaExtractor;
+
+struct JMediaExtractor : public RefBase {
+ JMediaExtractor(JNIEnv *env, jobject thiz);
+
+ status_t setDataSource(const char *path);
+
+ size_t countTracks() const;
+ status_t getTrackFormat(size_t index, jobject *format) const;
+
+ status_t selectTrack(size_t index);
+
+ status_t seekTo(int64_t timeUs);
+
+ status_t advance();
+ status_t readSampleData(jobject byteBuf, size_t offset, size_t *sampleSize);
+ status_t getSampleTrackIndex(size_t *trackIndex);
+ status_t getSampleTime(int64_t *sampleTimeUs);
+
+protected:
+ virtual ~JMediaExtractor();
+
+private:
+ jclass mClass;
+ jweak mObject;
+ sp<NuMediaExtractor> mImpl;
+
+ DISALLOW_EVIL_CONSTRUCTORS(JMediaExtractor);
+};
+
+} // namespace android
+
+#endif // _ANDROID_MEDIA_MEDIAEXTRACTOR_H_
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 8ff9dd3fdc02..f3a56686d667 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -39,7 +39,7 @@
#include "android_util_Binder.h"
#include <binder/Parcel.h>
#include <gui/ISurfaceTexture.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -810,6 +810,8 @@ static int register_android_media_MediaPlayer(JNIEnv *env)
"android/media/MediaPlayer", gMethods, NELEM(gMethods));
}
+extern int register_android_media_MediaCodec(JNIEnv *env);
+extern int register_android_media_MediaExtractor(JNIEnv *env);
extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
extern int register_android_media_MediaRecorder(JNIEnv *env);
extern int register_android_media_MediaScanner(JNIEnv *env);
@@ -881,6 +883,16 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
goto bail;
}
+ if (register_android_media_MediaCodec(env) < 0) {
+ ALOGE("ERROR: MediaCodec native registration failed");
+ goto bail;
+ }
+
+ if (register_android_media_MediaExtractor(env) < 0) {
+ ALOGE("ERROR: MediaCodec native registration failed");
+ goto bail;
+ }
+
/* success -- return valid version number */
result = JNI_VERSION_1_4;
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index acc65f1b1837..b6e6ceb19806 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "MediaRecorderJNI"
#include <utils/Log.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/Surface.h>
#include <camera/ICameraService.h>
#include <camera/Camera.h>
#include <media/mediarecorder.h>
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index 47963b101b7d..8b2321c31288 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -20,6 +20,10 @@
#include <utils/Log.h>
#include "android_media_Utils.h"
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AMessage.h>
+
namespace android {
bool ConvertKeyValueArraysToKeyedVector(
@@ -71,5 +75,263 @@ bool ConvertKeyValueArraysToKeyedVector(
return true;
}
+static jobject makeIntegerObject(JNIEnv *env, int32_t value) {
+ jclass clazz = env->FindClass("java/lang/Integer");
+ CHECK(clazz != NULL);
+
+ jmethodID integerConstructID = env->GetMethodID(clazz, "<init>", "(I)V");
+ CHECK(integerConstructID != NULL);
+
+ return env->NewObject(clazz, integerConstructID, value);
+}
+
+static jobject makeFloatObject(JNIEnv *env, float value) {
+ jclass clazz = env->FindClass("java/lang/Float");
+ CHECK(clazz != NULL);
+
+ jmethodID floatConstructID = env->GetMethodID(clazz, "<init>", "(F)V");
+ CHECK(floatConstructID != NULL);
+
+ return env->NewObject(clazz, floatConstructID, value);
+}
+
+static jobject makeByteBufferObject(
+ JNIEnv *env, const void *data, size_t size) {
+ jbyteArray byteArrayObj = env->NewByteArray(size);
+ env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data);
+
+ jclass clazz = env->FindClass("java/nio/ByteBuffer");
+ CHECK(clazz != NULL);
+
+ jmethodID byteBufWrapID =
+ env->GetStaticMethodID(clazz, "wrap", "([B)Ljava/nio/ByteBuffer;");
+ CHECK(byteBufWrapID != NULL);
+
+ jobject byteBufObj = env->CallStaticObjectMethod(
+ clazz, byteBufWrapID, byteArrayObj);
+
+ env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL;
+
+ return byteBufObj;
+}
+
+status_t ConvertMessageToMap(
+ JNIEnv *env, const sp<AMessage> &msg, jobject *map) {
+ jclass hashMapClazz = env->FindClass("java/util/HashMap");
+
+ if (hashMapClazz == NULL) {
+ return -EINVAL;
+ }
+
+ jmethodID hashMapConstructID =
+ env->GetMethodID(hashMapClazz, "<init>", "()V");
+
+ if (hashMapConstructID == NULL) {
+ return -EINVAL;
+ }
+
+ jmethodID hashMapPutID =
+ env->GetMethodID(
+ hashMapClazz,
+ "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
+ if (hashMapPutID == NULL) {
+ return -EINVAL;
+ }
+
+ jobject hashMap = env->NewObject(hashMapClazz, hashMapConstructID);
+
+ for (size_t i = 0; i < msg->countEntries(); ++i) {
+ AMessage::Type valueType;
+ const char *key = msg->getEntryNameAt(i, &valueType);
+
+ jobject valueObj = NULL;
+
+ switch (valueType) {
+ case AMessage::kTypeInt32:
+ {
+ int32_t val;
+ CHECK(msg->findInt32(key, &val));
+
+ valueObj = makeIntegerObject(env, val);
+ break;
+ }
+
+ case AMessage::kTypeFloat:
+ {
+ float val;
+ CHECK(msg->findFloat(key, &val));
+
+ valueObj = makeFloatObject(env, val);
+ break;
+ }
+
+ case AMessage::kTypeString:
+ {
+ AString val;
+ CHECK(msg->findString(key, &val));
+
+ valueObj = env->NewStringUTF(val.c_str());
+ break;
+ }
+
+ case AMessage::kTypeBuffer:
+ {
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer(key, &buffer));
+
+ valueObj = makeByteBufferObject(
+ env, buffer->data(), buffer->size());
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (valueObj != NULL) {
+ jstring keyObj = env->NewStringUTF(key);
+
+ jobject res = env->CallObjectMethod(
+ hashMap, hashMapPutID, keyObj, valueObj);
+
+ env->DeleteLocalRef(keyObj); keyObj = NULL;
+ env->DeleteLocalRef(valueObj); valueObj = NULL;
+ }
+ }
+
+ *map = hashMap;
+
+ return OK;
+}
+
+status_t ConvertKeyValueArraysToMessage(
+ JNIEnv *env, jobjectArray keys, jobjectArray values,
+ sp<AMessage> *out) {
+ jclass stringClass = env->FindClass("java/lang/String");
+ CHECK(stringClass != NULL);
+
+ jclass integerClass = env->FindClass("java/lang/Integer");
+ CHECK(integerClass != NULL);
+
+ jclass floatClass = env->FindClass("java/lang/Float");
+ CHECK(floatClass != NULL);
+
+ jclass byteBufClass = env->FindClass("java/nio/ByteBuffer");
+ CHECK(byteBufClass != NULL);
+
+ sp<AMessage> msg = new AMessage;
+
+ jsize numEntries = 0;
+
+ if (keys != NULL) {
+ if (values == NULL) {
+ return -EINVAL;
+ }
+
+ numEntries = env->GetArrayLength(keys);
+
+ if (numEntries != env->GetArrayLength(values)) {
+ return -EINVAL;
+ }
+ } else if (values != NULL) {
+ return -EINVAL;
+ }
+
+ for (jsize i = 0; i < numEntries; ++i) {
+ jobject keyObj = env->GetObjectArrayElement(keys, i);
+
+ if (!env->IsInstanceOf(keyObj, stringClass)) {
+ return -EINVAL;
+ }
+
+ const char *tmp = env->GetStringUTFChars((jstring)keyObj, NULL);
+
+ if (tmp == NULL) {
+ return -ENOMEM;
+ }
+
+ AString key = tmp;
+
+ env->ReleaseStringUTFChars((jstring)keyObj, tmp);
+ tmp = NULL;
+
+ jobject valueObj = env->GetObjectArrayElement(values, i);
+
+ if (env->IsInstanceOf(valueObj, stringClass)) {
+ const char *value = env->GetStringUTFChars((jstring)valueObj, NULL);
+
+ if (value == NULL) {
+ return -ENOMEM;
+ }
+
+ msg->setString(key.c_str(), value);
+
+ env->ReleaseStringUTFChars((jstring)valueObj, value);
+ value = NULL;
+ } else if (env->IsInstanceOf(valueObj, integerClass)) {
+ jmethodID intValueID =
+ env->GetMethodID(integerClass, "intValue", "()I");
+ CHECK(intValueID != NULL);
+
+ jint value = env->CallIntMethod(valueObj, intValueID);
+
+ msg->setInt32(key.c_str(), value);
+ } else if (env->IsInstanceOf(valueObj, floatClass)) {
+ jmethodID floatValueID =
+ env->GetMethodID(floatClass, "floatValue", "()F");
+ CHECK(floatValueID != NULL);
+
+ jfloat value = env->CallFloatMethod(valueObj, floatValueID);
+
+ msg->setFloat(key.c_str(), value);
+ } else if (env->IsInstanceOf(valueObj, byteBufClass)) {
+ jmethodID positionID =
+ env->GetMethodID(byteBufClass, "position", "()I");
+ CHECK(positionID != NULL);
+
+ jmethodID limitID =
+ env->GetMethodID(byteBufClass, "limit", "()I");
+ CHECK(limitID != NULL);
+
+ jint position = env->CallIntMethod(valueObj, positionID);
+ jint limit = env->CallIntMethod(valueObj, limitID);
+
+ sp<ABuffer> buffer = new ABuffer(limit - position);
+
+ void *data = env->GetDirectBufferAddress(valueObj);
+
+ if (data != NULL) {
+ memcpy(buffer->data(),
+ (const uint8_t *)data + position,
+ buffer->size());
+ } else {
+ jmethodID arrayID =
+ env->GetMethodID(byteBufClass, "array", "()[B");
+ CHECK(arrayID != NULL);
+
+ jbyteArray byteArray =
+ (jbyteArray)env->CallObjectMethod(valueObj, arrayID);
+ CHECK(byteArray != NULL);
+
+ env->GetByteArrayRegion(
+ byteArray,
+ position,
+ buffer->size(),
+ (jbyte *)buffer->data());
+
+ env->DeleteLocalRef(byteArray); byteArray = NULL;
+ }
+
+ msg->setObject(key.c_str(), buffer);
+ }
+ }
+
+ *out = msg;
+
+ return OK;
+}
+
} // namespace android
diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h
index a2c155adfc7a..635bceb2fddf 100644
--- a/media/jni/android_media_Utils.h
+++ b/media/jni/android_media_Utils.h
@@ -33,6 +33,14 @@ bool ConvertKeyValueArraysToKeyedVector(
JNIEnv *env, jobjectArray keys, jobjectArray values,
KeyedVector<String8, String8>* vector);
+struct AMessage;
+status_t ConvertMessageToMap(
+ JNIEnv *env, const sp<AMessage> &msg, jobject *map);
+
+status_t ConvertKeyValueArraysToMessage(
+ JNIEnv *env, jobjectArray keys, jobjectArray values,
+ sp<AMessage> *msg);
+
}; // namespace android
#endif // _ANDROID_MEDIA_UTILS_H_
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index c84a88394d56..b0c1c35d905a 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -29,8 +29,7 @@
#include <VideoEditorThumbnailMain.h>
#include <M4OSA_Debug.h>
#include <M4xVSS_Internal.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
+#include <gui/Surface.h>
#include "VideoEditorPreviewController.h"
#include "VideoEditorMain.h"
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 098a1a29242d..dc27d38246ed 100755
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -845,6 +845,17 @@ int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
config->inputCfg.samplingRate, config->inputCfg.channels);
int status;
+ // if at least one process is enabled, do not accept configuration changes
+ if (session->enabledMsk) {
+ if (session->samplingRate != config->inputCfg.samplingRate ||
+ session->inChannelCount != inCnl ||
+ session->outChannelCount != outCnl) {
+ return -ENOSYS;
+ } else {
+ return 0;
+ }
+ }
+
// AEC implementation is limited to 16kHz
if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
session->apmSamplingRate = 32000;
@@ -1287,7 +1298,9 @@ int PreProcessingFx_Command(effect_handle_t self,
if (*(int *)pReplyData != 0) {
break;
}
- *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+ if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
+ *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+ }
break;
case EFFECT_CMD_GET_CONFIG:
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 64cc91972357..86d65db5ddc1 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -23,8 +23,6 @@
#include <media/IMediaPlayer.h>
#include <media/IStreamSource.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/Surface.h>
#include <gui/ISurfaceTexture.h>
#include <utils/String8.h>
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 42f55c234217..2f4e31aa91e5 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -19,10 +19,10 @@
#define LOG_TAG "IMediaRecorder"
#include <utils/Log.h>
#include <binder/Parcel.h>
-#include <surfaceflinger/Surface.h>
#include <camera/ICamera.h>
#include <media/IMediaRecorderClient.h>
#include <media/IMediaRecorder.h>
+#include <gui/Surface.h>
#include <gui/ISurfaceTexture.h>
#include <unistd.h>
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 27c7e03b0cd1..48e427abe9b3 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -22,8 +22,6 @@
#include <binder/Parcel.h>
#include <media/IOMX.h>
#include <media/stagefright/foundation/ADebug.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/Surface.h>
namespace android {
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 250425b5d5b0..9d459071f3f9 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -32,8 +32,6 @@
#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
-#include <surfaceflinger/Surface.h>
-
#include <binder/MemoryBase.h>
#include <utils/KeyedVector.h>
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 8d947d862549..cc730145bb06 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -18,7 +18,6 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaRecorder"
#include <utils/Log.h>
-#include <surfaceflinger/Surface.h>
#include <media/mediarecorder.h>
#include <binder/IServiceManager.h>
#include <utils/String8.h>
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index c5f4f86d38de..ca796572c86d 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -40,7 +40,7 @@
#include <media/MediaProfiles.h>
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
#include <utils/Errors.h>
#include <sys/types.h>
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index b731d0f3cd58..e618f6700195 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -38,7 +38,6 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
-#include <surfaceflinger/Surface.h>
#include <gui/ISurfaceTexture.h>
#include "avc_utils.h"
@@ -387,10 +386,10 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
audio ? "audio" : "video");
mRenderer->queueEOS(audio, UNKNOWN_ERROR);
- } else {
- CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
-
+ } else if (what == ACodec::kWhatDrainThisBuffer) {
renderBuffer(audio, codecRequest);
+ } else {
+ ALOGV("Unhandled codec notification %d.", what);
}
break;
@@ -768,7 +767,7 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
mediaTimeUs / 1E6);
#endif
- reply->setObject("buffer", accessUnit);
+ reply->setBuffer("buffer", accessUnit);
reply->post();
return OK;
@@ -793,10 +792,8 @@ void NuPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
return;
}
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
-
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
int64_t &skipUntilMediaTimeUs =
audio
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index ffc710ee05c1..6be14be6c8d7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -21,8 +21,6 @@
#include <media/MediaPlayerInterface.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/NativeWindowWrapper.h>
-#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/Surface.h>
namespace android {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 56c2773fa56b..460fc9839314 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -29,8 +29,6 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
-#include <surfaceflinger/Surface.h>
-#include <gui/ISurfaceTexture.h>
namespace android {
@@ -214,8 +212,6 @@ sp<AMessage> NuPlayer::Decoder::makeFormat(const sp<MetaData> &meta) {
buffer->meta()->setInt32("csd", true);
mCSD.push(buffer);
-
- msg->setObject("csd", buffer);
} else if (meta->findData(kKeyESDS, &type, &data, &size)) {
ESDS esds((const char *)data, size);
CHECK_EQ(esds.InitCheck(), (status_t)OK);
@@ -242,9 +238,8 @@ void NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) {
CHECK(msg->findMessage("reply", &reply));
#if 0
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
- sp<ABuffer> outBuffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> outBuffer;
+ CHECK(msg->findBuffer("buffer", &outBuffer));
#else
sp<ABuffer> outBuffer;
#endif
@@ -253,7 +248,7 @@ void NuPlayer::Decoder::onFillThisBuffer(const sp<AMessage> &msg) {
outBuffer = mCSD.editItemAt(mCSDIndex++);
outBuffer->meta()->setInt64("timeUs", 0);
- reply->setObject("buffer", outBuffer);
+ reply->setBuffer("buffer", outBuffer);
reply->post();
return;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 15259cb5c370..5738ecb60b52 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -60,7 +60,7 @@ void NuPlayer::Renderer::queueBuffer(
const sp<AMessage> &notifyConsumed) {
sp<AMessage> msg = new AMessage(kWhatQueueBuffer, id());
msg->setInt32("audio", static_cast<int32_t>(audio));
- msg->setObject("buffer", buffer);
+ msg->setBuffer("buffer", buffer);
msg->setMessage("notifyConsumed", notifyConsumed);
msg->post();
}
@@ -411,9 +411,8 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
return;
}
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
sp<AMessage> notifyConsumed;
CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 6eb0d077aac2..4c65b6564df5 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -218,10 +218,8 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
CHECK(msg->findSize("trackIndex", &trackIndex));
CHECK_LT(trackIndex, mTracks.size());
- sp<RefBase> obj;
- CHECK(msg->findObject("accessUnit", &obj));
-
- sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> accessUnit;
+ CHECK(msg->findBuffer("accessUnit", &accessUnit));
int32_t damaged;
if (accessUnit->meta()->findInt32("damaged", &damaged)
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index ca44ea364024..85bd7ba3a1eb 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -31,9 +31,6 @@
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
-#include <surfaceflinger/Surface.h>
-#include <gui/SurfaceTextureClient.h>
-
#include <OMX_Component.h>
namespace android {
@@ -171,6 +168,9 @@ protected:
private:
void onSetup(const sp<AMessage> &msg);
+ void onAllocateComponent(const sp<AMessage> &msg);
+ void onConfigureComponent(const sp<AMessage> &msg);
+ void onStart();
DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
};
@@ -265,6 +265,8 @@ protected:
private:
void changeStateIfWeOwnAllBuffers();
+ bool mComponentNowIdle;
+
DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
};
@@ -309,7 +311,8 @@ private:
ACodec::ACodec()
: mNode(NULL),
- mSentFormat(false) {
+ mSentFormat(false),
+ mIsEncoder(false) {
mUninitializedState = new UninitializedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
mIdleToExecutingState = new IdleToExecutingState(this);
@@ -341,6 +344,22 @@ void ACodec::initiateSetup(const sp<AMessage> &msg) {
msg->post();
}
+void ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
+ msg->setWhat(kWhatAllocateComponent);
+ msg->setTarget(id());
+ msg->post();
+}
+
+void ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
+ msg->setWhat(kWhatConfigureComponent);
+ msg->setTarget(id());
+ msg->post();
+}
+
+void ACodec::initiateStart() {
+ (new AMessage(kWhatStart, id()))->post();
+}
+
void ACodec::signalFlush() {
ALOGV("[%s] signalFlush", mComponentName.c_str());
(new AMessage(kWhatFlush, id()))->post();
@@ -360,62 +379,75 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(mDealer[portIndex] == NULL);
CHECK(mBuffers[portIndex].isEmpty());
+ status_t err;
if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
- return allocateOutputBuffersFromNativeWindow();
- }
+ err = allocateOutputBuffersFromNativeWindow();
+ } else {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = portIndex;
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = portIndex;
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+ if (err == OK) {
+ ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
+ mComponentName.c_str(),
+ def.nBufferCountActual, def.nBufferSize,
+ portIndex == kPortIndexInput ? "input" : "output");
- if (err != OK) {
- return err;
- }
+ size_t totalSize = def.nBufferCountActual * def.nBufferSize;
+ mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
- ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
- mComponentName.c_str(),
- def.nBufferCountActual, def.nBufferSize,
- portIndex == kPortIndexInput ? "input" : "output");
+ for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
+ sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
+ CHECK(mem.get() != NULL);
- size_t totalSize = def.nBufferCountActual * def.nBufferSize;
- mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
+ IOMX::buffer_id buffer;
- for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
- sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
- CHECK(mem.get() != NULL);
+ if (!strncasecmp(
+ mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.", 21)) {
+ if (portIndex == kPortIndexInput && i == 0) {
+ // Only log this warning once per allocation round.
- IOMX::buffer_id buffer;
+ ALOGW("OMX.TI.DUCATI1.VIDEO.* require the use of "
+ "OMX_AllocateBuffer instead of the preferred "
+ "OMX_UseBuffer. Vendor must fix this.");
+ }
- if (!strcasecmp(
- mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.DECODER")) {
- if (portIndex == kPortIndexInput && i == 0) {
- // Only log this warning once per allocation round.
+ err = mOMX->allocateBufferWithBackup(
+ mNode, portIndex, mem, &buffer);
+ } else {
+ err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
+ }
- ALOGW("OMX.TI.DUCATI1.VIDEO.DECODER requires the use of "
- "OMX_AllocateBuffer instead of the preferred "
- "OMX_UseBuffer. Vendor must fix this.");
+ BufferInfo info;
+ info.mBufferID = buffer;
+ info.mStatus = BufferInfo::OWNED_BY_US;
+ info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
+ mBuffers[portIndex].push(info);
}
-
- err = mOMX->allocateBufferWithBackup(
- mNode, portIndex, mem, &buffer);
- } else {
- err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
}
+ }
- if (err != OK) {
- return err;
- }
+ if (err != OK) {
+ return err;
+ }
- BufferInfo info;
- info.mBufferID = buffer;
- info.mStatus = BufferInfo::OWNED_BY_US;
- info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
- mBuffers[portIndex].push(info);
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", ACodec::kWhatBuffersAllocated);
+
+ notify->setInt32("portIndex", portIndex);
+ for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
+ AString name = StringPrintf("buffer-id_%d", i);
+ notify->setPointer(name.c_str(), mBuffers[portIndex][i].mBufferID);
+
+ name = StringPrintf("data_%d", i);
+ notify->setBuffer(name.c_str(), mBuffers[portIndex][i].mData);
}
+ notify->post();
+
return OK;
}
@@ -671,7 +703,7 @@ ACodec::BufferInfo *ACodec::findBufferByID(
return NULL;
}
-void ACodec::setComponentRole(
+status_t ACodec::setComponentRole(
bool isEncoder, const char *mime) {
struct MimeToRole {
const char *mime;
@@ -700,6 +732,8 @@ void ACodec::setComponentRole(
"video_decoder.mpeg4", "video_encoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_H263,
"video_decoder.h263", "video_encoder.h263" },
+ { MEDIA_MIMETYPE_VIDEO_VPX,
+ "video_decoder.vpx", "video_encoder.vpx" },
};
static const size_t kNumMimeToRole =
@@ -713,7 +747,7 @@ void ACodec::setComponentRole(
}
if (i == kNumMimeToRole) {
- return;
+ return ERROR_UNSUPPORTED;
}
const char *role =
@@ -736,50 +770,83 @@ void ACodec::setComponentRole(
if (err != OK) {
ALOGW("[%s] Failed to set standard component role '%s'.",
mComponentName.c_str(), role);
+
+ return err;
}
}
+
+ return OK;
}
-void ACodec::configureCodec(
+status_t ACodec::configureCodec(
const char *mime, const sp<AMessage> &msg) {
- setComponentRole(false /* isEncoder */, mime);
+ int32_t encoder;
+ if (!msg->findInt32("encoder", &encoder)) {
+ encoder = false;
+ }
- if (!strncasecmp(mime, "video/", 6)) {
- int32_t width, height;
- CHECK(msg->findInt32("width", &width));
- CHECK(msg->findInt32("height", &height));
+ mIsEncoder = encoder;
- CHECK_EQ(setupVideoDecoder(mime, width, height),
- (status_t)OK);
+ status_t err = setComponentRole(encoder /* isEncoder */, mime);
+
+ if (err != OK) {
+ return err;
+ }
+
+ int32_t bitRate = 0;
+ if (encoder && !msg->findInt32("bitrate", &bitRate)) {
+ return INVALID_OPERATION;
+ }
+
+ if (!strncasecmp(mime, "video/", 6)) {
+ if (encoder) {
+ err = setupVideoEncoder(mime, msg);
+ } else {
+ int32_t width, height;
+ if (!msg->findInt32("width", &width)
+ || !msg->findInt32("height", &height)) {
+ err = INVALID_OPERATION;
+ } else {
+ err = setupVideoDecoder(mime, width, height);
+ }
+ }
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
int32_t numChannels, sampleRate;
- CHECK(msg->findInt32("channel-count", &numChannels));
- CHECK(msg->findInt32("sample-rate", &sampleRate));
-
- CHECK_EQ(setupAACDecoder(numChannels, sampleRate), (status_t)OK);
+ if (!msg->findInt32("channel-count", &numChannels)
+ || !msg->findInt32("sample-rate", &sampleRate)) {
+ err = INVALID_OPERATION;
+ } else {
+ err = setupAACCodec(encoder, numChannels, sampleRate, bitRate);
+ }
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
- CHECK_EQ(setupAMRDecoder(false /* isWAMR */), (status_t)OK);
+ err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
- CHECK_EQ(setupAMRDecoder(true /* isWAMR */), (status_t)OK);
+ err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
|| !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
// These are PCM-like formats with a fixed sample rate but
// a variable number of channels.
int32_t numChannels;
- CHECK(msg->findInt32("channel-count", &numChannels));
+ if (!msg->findInt32("channel-count", &numChannels)) {
+ err = INVALID_OPERATION;
+ } else {
+ err = setupG711Codec(encoder, numChannels);
+ }
+ }
- CHECK_EQ(setupG711Decoder(numChannels), (status_t)OK);
+ if (err != OK) {
+ return err;
}
int32_t maxInputSize;
if (msg->findInt32("max-input-size", &maxInputSize)) {
- CHECK_EQ(setMinBufferSize(kPortIndexInput, (size_t)maxInputSize),
- (status_t)OK);
+ err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
} else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
- CHECK_EQ(setMinBufferSize(kPortIndexInput, 8192), // XXX
- (status_t)OK);
+ err = setMinBufferSize(kPortIndexInput, 8192); // XXX
}
+
+ return err;
}
status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
@@ -819,12 +886,113 @@ status_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
return OK;
}
-status_t ACodec::setupAACDecoder(int32_t numChannels, int32_t sampleRate) {
+status_t ACodec::selectAudioPortFormat(
+ OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE format;
+ InitOMXParams(&format);
+
+ format.nPortIndex = portIndex;
+ for (OMX_U32 index = 0;; ++index) {
+ format.nIndex = index;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamAudioPortFormat,
+ &format, sizeof(format));
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (format.eEncoding == desiredFormat) {
+ break;
+ }
+ }
+
+ return mOMX->setParameter(
+ mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
+}
+
+status_t ACodec::setupAACCodec(
+ bool encoder,
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
+ status_t err = setupRawAudioFormat(
+ encoder ? kPortIndexInput : kPortIndexOutput,
+ sampleRate,
+ numChannels);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (encoder) {
+ err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
+
+ if (err != OK) {
+ return err;
+ }
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexOutput;
+
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ def.format.audio.bFlagErrorConcealment = OMX_TRUE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ OMX_AUDIO_PARAM_AACPROFILETYPE profile;
+ InitOMXParams(&profile);
+ profile.nPortIndex = kPortIndexOutput;
+
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+
+ if (err != OK) {
+ return err;
+ }
+
+ profile.nChannels = numChannels;
+
+ profile.eChannelMode =
+ (numChannels == 1)
+ ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
+
+ profile.nSampleRate = sampleRate;
+ profile.nBitRate = bitRate;
+ profile.nAudioBandWidth = 0;
+ profile.nFrameLength = 0;
+ profile.nAACtools = OMX_AUDIO_AACToolAll;
+ profile.nAACERtools = OMX_AUDIO_AACERNone;
+ profile.eAACProfile = OMX_AUDIO_AACObjectLC;
+ profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+
+ if (err != OK) {
+ return err;
+ }
+
+ return err;
+ }
+
OMX_AUDIO_PARAM_AACPROFILETYPE profile;
InitOMXParams(&profile);
profile.nPortIndex = kPortIndexInput;
- status_t err = mOMX->getParameter(
+ err = mOMX->getParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
if (err != OK) {
@@ -835,16 +1003,59 @@ status_t ACodec::setupAACDecoder(int32_t numChannels, int32_t sampleRate) {
profile.nSampleRate = sampleRate;
profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
- err = mOMX->setParameter(
+ return mOMX->setParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+}
- return err;
+static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
+ bool isAMRWB, int32_t bps) {
+ if (isAMRWB) {
+ if (bps <= 6600) {
+ return OMX_AUDIO_AMRBandModeWB0;
+ } else if (bps <= 8850) {
+ return OMX_AUDIO_AMRBandModeWB1;
+ } else if (bps <= 12650) {
+ return OMX_AUDIO_AMRBandModeWB2;
+ } else if (bps <= 14250) {
+ return OMX_AUDIO_AMRBandModeWB3;
+ } else if (bps <= 15850) {
+ return OMX_AUDIO_AMRBandModeWB4;
+ } else if (bps <= 18250) {
+ return OMX_AUDIO_AMRBandModeWB5;
+ } else if (bps <= 19850) {
+ return OMX_AUDIO_AMRBandModeWB6;
+ } else if (bps <= 23050) {
+ return OMX_AUDIO_AMRBandModeWB7;
+ }
+
+ // 23850 bps
+ return OMX_AUDIO_AMRBandModeWB8;
+ } else { // AMRNB
+ if (bps <= 4750) {
+ return OMX_AUDIO_AMRBandModeNB0;
+ } else if (bps <= 5150) {
+ return OMX_AUDIO_AMRBandModeNB1;
+ } else if (bps <= 5900) {
+ return OMX_AUDIO_AMRBandModeNB2;
+ } else if (bps <= 6700) {
+ return OMX_AUDIO_AMRBandModeNB3;
+ } else if (bps <= 7400) {
+ return OMX_AUDIO_AMRBandModeNB4;
+ } else if (bps <= 7950) {
+ return OMX_AUDIO_AMRBandModeNB5;
+ } else if (bps <= 10200) {
+ return OMX_AUDIO_AMRBandModeNB6;
+ }
+
+ // 12200 bps
+ return OMX_AUDIO_AMRBandModeNB7;
+ }
}
-status_t ACodec::setupAMRDecoder(bool isWAMR) {
+status_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
OMX_AUDIO_PARAM_AMRTYPE def;
InitOMXParams(&def);
- def.nPortIndex = kPortIndexInput;
+ def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
status_t err =
mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
@@ -854,14 +1065,24 @@ status_t ACodec::setupAMRDecoder(bool isWAMR) {
}
def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+ def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
- def.eAMRBandMode =
- isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
+ if (err != OK) {
+ return err;
+ }
- return mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+ return setupRawAudioFormat(
+ encoder ? kPortIndexInput : kPortIndexOutput,
+ isWAMR ? 16000 : 8000 /* sampleRate */,
+ 1 /* numChannels */);
}
-status_t ACodec::setupG711Decoder(int32_t numChannels) {
+status_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
+ CHECK(!encoder); // XXX TODO
+
return setupRawAudioFormat(
kPortIndexInput, 8000 /* sampleRate */, numChannels);
}
@@ -1001,22 +1222,36 @@ status_t ACodec::setSupportedOutputFormat() {
&format, sizeof(format));
}
-status_t ACodec::setupVideoDecoder(
- const char *mime, int32_t width, int32_t height) {
- OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
+static status_t GetVideoCodingTypeFromMime(
+ const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
- compressionFormat = OMX_VIDEO_CodingAVC;
+ *codingType = OMX_VIDEO_CodingAVC;
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
- compressionFormat = OMX_VIDEO_CodingMPEG4;
+ *codingType = OMX_VIDEO_CodingMPEG4;
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
- compressionFormat = OMX_VIDEO_CodingH263;
+ *codingType = OMX_VIDEO_CodingH263;
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
- compressionFormat = OMX_VIDEO_CodingMPEG2;
+ *codingType = OMX_VIDEO_CodingMPEG2;
+ } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
+ *codingType = OMX_VIDEO_CodingVPX;
} else {
- TRESPASS();
+ *codingType = OMX_VIDEO_CodingUnused;
+ return ERROR_UNSUPPORTED;
}
- status_t err = setVideoPortFormatType(
+ return OK;
+}
+
+status_t ACodec::setupVideoDecoder(
+ const char *mime, int32_t width, int32_t height) {
+ OMX_VIDEO_CODINGTYPE compressionFormat;
+ status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
+
+ if (err != OK) {
+ return err;
+ }
+
+ err = setVideoPortFormatType(
kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
if (err != OK) {
@@ -1046,6 +1281,489 @@ status_t ACodec::setupVideoDecoder(
return OK;
}
+status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
+ int32_t tmp;
+ if (!msg->findInt32("color-format", &tmp)) {
+ return INVALID_OPERATION;
+ }
+
+ OMX_COLOR_FORMATTYPE colorFormat =
+ static_cast<OMX_COLOR_FORMATTYPE>(tmp);
+
+ status_t err = setVideoPortFormatType(
+ kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
+
+ if (err != OK) {
+ ALOGE("[%s] does not support color format %d",
+ mComponentName.c_str(), colorFormat);
+
+ return err;
+ }
+
+ /* Input port configuration */
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
+
+ def.nPortIndex = kPortIndexInput;
+
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ int32_t width, height, bitrate;
+ if (!msg->findInt32("width", &width)
+ || !msg->findInt32("height", &height)
+ || !msg->findInt32("bitrate", &bitrate)) {
+ return INVALID_OPERATION;
+ }
+
+ video_def->nFrameWidth = width;
+ video_def->nFrameHeight = height;
+
+ int32_t stride;
+ if (!msg->findInt32("stride", &stride)) {
+ stride = width;
+ }
+
+ video_def->nStride = stride;
+
+ int32_t sliceHeight;
+ if (!msg->findInt32("slice-height", &sliceHeight)) {
+ sliceHeight = height;
+ }
+
+ video_def->nSliceHeight = sliceHeight;
+
+ def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
+
+ float frameRate;
+ if (!msg->findFloat("frame-rate", &frameRate)) {
+ int32_t tmp;
+ if (!msg->findInt32("frame-rate", &tmp)) {
+ return INVALID_OPERATION;
+ }
+ frameRate = (float)tmp;
+ }
+
+ video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
+ video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ video_def->eColorFormat = colorFormat;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ if (err != OK) {
+ ALOGE("[%s] failed to set input port definition parameters.",
+ mComponentName.c_str());
+
+ return err;
+ }
+
+ /* Output port configuration */
+
+ OMX_VIDEO_CODINGTYPE compressionFormat;
+ err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
+
+ if (err != OK) {
+ return err;
+ }
+
+ err = setVideoPortFormatType(
+ kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
+
+ if (err != OK) {
+ ALOGE("[%s] does not support compression format %d",
+ mComponentName.c_str(), compressionFormat);
+
+ return err;
+ }
+
+ def.nPortIndex = kPortIndexOutput;
+
+ err = mOMX->getParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ if (err != OK) {
+ return err;
+ }
+
+ video_def->nFrameWidth = width;
+ video_def->nFrameHeight = height;
+ video_def->xFramerate = 0;
+ video_def->nBitrate = bitrate;
+ video_def->eCompressionFormat = compressionFormat;
+ video_def->eColorFormat = OMX_COLOR_FormatUnused;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ if (err != OK) {
+ ALOGE("[%s] failed to set output port definition parameters.",
+ mComponentName.c_str());
+
+ return err;
+ }
+
+ switch (compressionFormat) {
+ case OMX_VIDEO_CodingMPEG4:
+ err = setupMPEG4EncoderParameters(msg);
+ break;
+
+ case OMX_VIDEO_CodingH263:
+ err = setupH263EncoderParameters(msg);
+ break;
+
+ case OMX_VIDEO_CodingAVC:
+ err = setupAVCEncoderParameters(msg);
+ break;
+
+ default:
+ break;
+ }
+
+ ALOGI("setupVideoEncoder succeeded");
+
+ return err;
+}
+
+static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
+ if (iFramesInterval < 0) {
+ return 0xFFFFFFFF;
+ } else if (iFramesInterval == 0) {
+ return 0;
+ }
+ OMX_U32 ret = frameRate * iFramesInterval;
+ CHECK(ret > 1);
+ return ret;
+}
+
+status_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
+ int32_t bitrate, iFrameInterval;
+ if (!msg->findInt32("bitrate", &bitrate)
+ || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
+ return INVALID_OPERATION;
+ }
+
+ float frameRate;
+ if (!msg->findFloat("frame-rate", &frameRate)) {
+ int32_t tmp;
+ if (!msg->findInt32("frame-rate", &tmp)) {
+ return INVALID_OPERATION;
+ }
+ frameRate = (float)tmp;
+ }
+
+ OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
+ InitOMXParams(&mpeg4type);
+ mpeg4type.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
+
+ if (err != OK) {
+ return err;
+ }
+
+ mpeg4type.nSliceHeaderSpacing = 0;
+ mpeg4type.bSVH = OMX_FALSE;
+ mpeg4type.bGov = OMX_FALSE;
+
+ mpeg4type.nAllowedPictureTypes =
+ OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
+
+ mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
+ if (mpeg4type.nPFrames == 0) {
+ mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
+ }
+ mpeg4type.nBFrames = 0;
+ mpeg4type.nIDCVLCThreshold = 0;
+ mpeg4type.bACPred = OMX_TRUE;
+ mpeg4type.nMaxPacketSize = 256;
+ mpeg4type.nTimeIncRes = 1000;
+ mpeg4type.nHeaderExtension = 0;
+ mpeg4type.bReversibleVLC = OMX_FALSE;
+
+ int32_t profile;
+ if (msg->findInt32("profile", &profile)) {
+ int32_t level;
+ if (!msg->findInt32("level", &level)) {
+ return INVALID_OPERATION;
+ }
+
+ err = verifySupportForProfileAndLevel(profile, level);
+
+ if (err != OK) {
+ return err;
+ }
+
+ mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
+ mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
+ }
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
+
+ if (err != OK) {
+ return err;
+ }
+
+ err = configureBitrate(bitrate);
+
+ if (err != OK) {
+ return err;
+ }
+
+ return setupErrorCorrectionParameters();
+}
+
+status_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
+ int32_t bitrate, iFrameInterval;
+ if (!msg->findInt32("bitrate", &bitrate)
+ || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
+ return INVALID_OPERATION;
+ }
+
+ float frameRate;
+ if (!msg->findFloat("frame-rate", &frameRate)) {
+ int32_t tmp;
+ if (!msg->findInt32("frame-rate", &tmp)) {
+ return INVALID_OPERATION;
+ }
+ frameRate = (float)tmp;
+ }
+
+ OMX_VIDEO_PARAM_H263TYPE h263type;
+ InitOMXParams(&h263type);
+ h263type.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
+
+ if (err != OK) {
+ return err;
+ }
+
+ h263type.nAllowedPictureTypes =
+ OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
+
+ h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
+ if (h263type.nPFrames == 0) {
+ h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
+ }
+ h263type.nBFrames = 0;
+
+ int32_t profile;
+ if (msg->findInt32("profile", &profile)) {
+ int32_t level;
+ if (!msg->findInt32("level", &level)) {
+ return INVALID_OPERATION;
+ }
+
+ err = verifySupportForProfileAndLevel(profile, level);
+
+ if (err != OK) {
+ return err;
+ }
+
+ h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
+ h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
+ }
+
+ h263type.bPLUSPTYPEAllowed = OMX_FALSE;
+ h263type.bForceRoundingTypeToZero = OMX_FALSE;
+ h263type.nPictureHeaderRepetition = 0;
+ h263type.nGOBHeaderInterval = 0;
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
+
+ if (err != OK) {
+ return err;
+ }
+
+ err = configureBitrate(bitrate);
+
+ if (err != OK) {
+ return err;
+ }
+
+ return setupErrorCorrectionParameters();
+}
+
+status_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
+ int32_t bitrate, iFrameInterval;
+ if (!msg->findInt32("bitrate", &bitrate)
+ || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
+ return INVALID_OPERATION;
+ }
+
+ float frameRate;
+ if (!msg->findFloat("frame-rate", &frameRate)) {
+ int32_t tmp;
+ if (!msg->findInt32("frame-rate", &tmp)) {
+ return INVALID_OPERATION;
+ }
+ frameRate = (float)tmp;
+ }
+
+ OMX_VIDEO_PARAM_AVCTYPE h264type;
+ InitOMXParams(&h264type);
+ h264type.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
+
+ if (err != OK) {
+ return err;
+ }
+
+ h264type.nAllowedPictureTypes =
+ OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
+
+ int32_t profile;
+ if (msg->findInt32("profile", &profile)) {
+ int32_t level;
+ if (!msg->findInt32("level", &level)) {
+ return INVALID_OPERATION;
+ }
+
+ err = verifySupportForProfileAndLevel(profile, level);
+
+ if (err != OK) {
+ return err;
+ }
+
+ h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
+ h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
+ }
+
+ // XXX
+ if (!strncmp(mComponentName.c_str(), "OMX.TI.DUCATI1", 14)) {
+ h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
+ }
+
+ if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
+ h264type.nSliceHeaderSpacing = 0;
+ h264type.bUseHadamard = OMX_TRUE;
+ h264type.nRefFrames = 1;
+ h264type.nBFrames = 0;
+ h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
+ if (h264type.nPFrames == 0) {
+ h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
+ }
+ h264type.nRefIdx10ActiveMinus1 = 0;
+ h264type.nRefIdx11ActiveMinus1 = 0;
+ h264type.bEntropyCodingCABAC = OMX_FALSE;
+ h264type.bWeightedPPrediction = OMX_FALSE;
+ h264type.bconstIpred = OMX_FALSE;
+ h264type.bDirect8x8Inference = OMX_FALSE;
+ h264type.bDirectSpatialTemporal = OMX_FALSE;
+ h264type.nCabacInitIdc = 0;
+ }
+
+ if (h264type.nBFrames != 0) {
+ h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
+ }
+
+ h264type.bEnableUEP = OMX_FALSE;
+ h264type.bEnableFMO = OMX_FALSE;
+ h264type.bEnableASO = OMX_FALSE;
+ h264type.bEnableRS = OMX_FALSE;
+ h264type.bFrameMBsOnly = OMX_TRUE;
+ h264type.bMBAFF = OMX_FALSE;
+ h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
+
+ if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName.c_str())) {
+ h264type.eLevel = OMX_VIDEO_AVCLevelMax;
+ }
+
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
+
+ if (err != OK) {
+ return err;
+ }
+
+ return configureBitrate(bitrate);
+}
+
+status_t ACodec::verifySupportForProfileAndLevel(
+ int32_t profile, int32_t level) {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
+ InitOMXParams(&params);
+ params.nPortIndex = kPortIndexOutput;
+
+ for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
+ status_t err = mOMX->getParameter(
+ mNode,
+ OMX_IndexParamVideoProfileLevelQuerySupported,
+ &params,
+ sizeof(params));
+
+ if (err != OK) {
+ return err;
+ }
+
+ int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
+ int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
+
+ if (profile == supportedProfile && level <= supportedLevel) {
+ return OK;
+ }
+ }
+}
+
+status_t ACodec::configureBitrate(int32_t bitrate) {
+ OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
+ InitOMXParams(&bitrateType);
+ bitrateType.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoBitrate,
+ &bitrateType, sizeof(bitrateType));
+
+ if (err != OK) {
+ return err;
+ }
+
+ bitrateType.eControlRate = OMX_Video_ControlRateVariable;
+ bitrateType.nTargetBitrate = bitrate;
+
+ return mOMX->setParameter(
+ mNode, OMX_IndexParamVideoBitrate,
+ &bitrateType, sizeof(bitrateType));
+}
+
+status_t ACodec::setupErrorCorrectionParameters() {
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
+ InitOMXParams(&errorCorrectionType);
+ errorCorrectionType.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->getParameter(
+ mNode, OMX_IndexParamVideoErrorCorrection,
+ &errorCorrectionType, sizeof(errorCorrectionType));
+
+ if (err != OK) {
+ return OK; // Optional feature. Ignore this failure
+ }
+
+ errorCorrectionType.bEnableHEC = OMX_FALSE;
+ errorCorrectionType.bEnableResync = OMX_TRUE;
+ errorCorrectionType.nResynchMarkerSpacing = 256;
+ errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
+ errorCorrectionType.bEnableRVLC = OMX_FALSE;
+
+ return mOMX->setParameter(
+ mNode, OMX_IndexParamVideoErrorCorrection,
+ &errorCorrectionType, sizeof(errorCorrectionType));
+}
+
status_t ACodec::setVideoFormatOnPort(
OMX_U32 portIndex,
int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
@@ -1166,6 +1884,9 @@ void ACodec::sendFormatChange() {
notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
notify->setInt32("width", videoDef->nFrameWidth);
notify->setInt32("height", videoDef->nFrameHeight);
+ notify->setInt32("stride", videoDef->nStride);
+ notify->setInt32("slice-height", videoDef->nSliceHeight);
+ notify->setInt32("color-format", videoDef->eColorFormat);
OMX_CONFIG_RECTTYPE rect;
InitOMXParams(&rect);
@@ -1241,10 +1962,11 @@ void ACodec::sendFormatChange() {
mSentFormat = true;
}
-void ACodec::signalError(OMX_ERRORTYPE error) {
+void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", ACodec::kWhatError);
notify->setInt32("omx-error", error);
+ notify->setInt32("err", internalError);
notify->post();
}
@@ -1417,7 +2139,7 @@ void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
notify->setPointer("buffer-id", info->mBufferID);
info->mData->meta()->clear();
- notify->setObject("buffer", info->mData);
+ notify->setBuffer("buffer", info->mData);
sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
reply->setPointer("buffer-id", info->mBufferID);
@@ -1433,18 +2155,26 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
IOMX::buffer_id bufferID;
CHECK(msg->findPointer("buffer-id", &bufferID));
- sp<RefBase> obj;
+ sp<ABuffer> buffer;
int32_t err = OK;
- if (!msg->findObject("buffer", &obj)) {
+ bool eos = false;
+
+ if (!msg->findBuffer("buffer", &buffer)) {
CHECK(msg->findInt32("err", &err));
ALOGV("[%s] saw error %d instead of an input buffer",
mCodec->mComponentName.c_str(), err);
- obj.clear();
+ buffer.clear();
+
+ eos = true;
}
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+ int32_t tmp;
+ if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
+ eos = true;
+ err = ERROR_END_OF_STREAM;
+ }
BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
@@ -1456,7 +2186,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
switch (mode) {
case KEEP_BUFFERS:
{
- if (buffer == NULL) {
+ if (eos) {
if (!mCodec->mPortEOS[kPortIndexInput]) {
mCodec->mPortEOS[kPortIndexInput] = true;
mCodec->mInputEOSResult = err;
@@ -1467,9 +2197,7 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
case RESUBMIT_BUFFERS:
{
- if (buffer != NULL) {
- CHECK(!mCodec->mPortEOS[kPortIndexInput]);
-
+ if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
int64_t timeUs;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
@@ -1480,6 +2208,10 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
flags |= OMX_BUFFERFLAG_CODECCONFIG;
}
+ if (eos) {
+ flags |= OMX_BUFFERFLAG_EOS;
+ }
+
if (buffer != info->mData) {
if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
ALOGV("[%s] Needs to copy input data.",
@@ -1493,6 +2225,9 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
mCodec->mComponentName.c_str(), bufferID);
+ } else if (flags & OMX_BUFFERFLAG_EOS) {
+ ALOGV("[%s] calling emptyBuffer %p w/ EOS",
+ mCodec->mComponentName.c_str(), bufferID);
} else {
ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
mCodec->mComponentName.c_str(), bufferID, timeUs);
@@ -1509,7 +2244,15 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- getMoreInputDataIfPossible();
+ if (!eos) {
+ getMoreInputDataIfPossible();
+ } else {
+ ALOGV("[%s] Signalled EOS on the input port",
+ mCodec->mComponentName.c_str());
+
+ mCodec->mPortEOS[kPortIndexInput] = true;
+ mCodec->mInputEOSResult = err;
+ }
} else if (!mCodec->mPortEOS[kPortIndexInput]) {
if (err != ERROR_END_OF_STREAM) {
ALOGV("[%s] Signalling EOS on the input port "
@@ -1582,8 +2325,8 @@ bool ACodec::BaseState::onOMXFillBufferDone(
int64_t timeUs,
void *platformPrivate,
void *dataPtr) {
- ALOGV("[%s] onOMXFillBufferDone %p time %lld us",
- mCodec->mComponentName.c_str(), bufferID, timeUs);
+ ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
+ mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
ssize_t index;
BufferInfo *info =
@@ -1601,46 +2344,48 @@ bool ACodec::BaseState::onOMXFillBufferDone(
case RESUBMIT_BUFFERS:
{
- if (rangeLength == 0) {
- if (!(flags & OMX_BUFFERFLAG_EOS)) {
- ALOGV("[%s] calling fillBuffer %p",
- mCodec->mComponentName.c_str(), info->mBufferID);
+ if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
+ ALOGV("[%s] calling fillBuffer %p",
+ mCodec->mComponentName.c_str(), info->mBufferID);
- CHECK_EQ(mCodec->mOMX->fillBuffer(
- mCodec->mNode, info->mBufferID),
- (status_t)OK);
+ CHECK_EQ(mCodec->mOMX->fillBuffer(
+ mCodec->mNode, info->mBufferID),
+ (status_t)OK);
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- }
- } else {
- if (!mCodec->mSentFormat) {
- mCodec->sendFormatChange();
- }
+ info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
+ break;
+ }
- if (mCodec->mNativeWindow == NULL) {
- info->mData->setRange(rangeOffset, rangeLength);
- }
+ if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
+ mCodec->sendFormatChange();
+ }
- info->mData->meta()->setInt64("timeUs", timeUs);
+ if (mCodec->mNativeWindow == NULL) {
+ info->mData->setRange(rangeOffset, rangeLength);
+ }
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
- notify->setPointer("buffer-id", info->mBufferID);
- notify->setObject("buffer", info->mData);
+ info->mData->meta()->setInt64("timeUs", timeUs);
- sp<AMessage> reply =
- new AMessage(kWhatOutputBufferDrained, mCodec->id());
+ sp<AMessage> notify = mCodec->mNotify->dup();
+ notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
+ notify->setPointer("buffer-id", info->mBufferID);
+ notify->setBuffer("buffer", info->mData);
+ notify->setInt32("flags", flags);
- reply->setPointer("buffer-id", info->mBufferID);
+ sp<AMessage> reply =
+ new AMessage(kWhatOutputBufferDrained, mCodec->id());
- notify->setMessage("reply", reply);
+ reply->setPointer("buffer-id", info->mBufferID);
- notify->post();
+ notify->setMessage("reply", reply);
- info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
- }
+ notify->post();
+
+ info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
if (flags & OMX_BUFFERFLAG_EOS) {
+ ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
+
sp<AMessage> notify = mCodec->mNotify->dup();
notify->setInt32("what", ACodec::kWhatEOS);
notify->setInt32("err", mCodec->mInputEOSResult);
@@ -1678,12 +2423,13 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
&& msg->findInt32("render", &render) && render != 0) {
// The client wants this buffer to be rendered.
- if (mCodec->mNativeWindow->queueBuffer(
+ status_t err;
+ if ((err = mCodec->mNativeWindow->queueBuffer(
mCodec->mNativeWindow.get(),
- info->mGraphicBuffer.get()) == OK) {
+ info->mGraphicBuffer.get())) == OK) {
info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
} else {
- mCodec->signalError();
+ mCodec->signalError(OMX_ErrorUndefined, err);
info->mStatus = BufferInfo::OWNED_BY_US;
}
} else {
@@ -1758,6 +2504,27 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case ACodec::kWhatAllocateComponent:
+ {
+ onAllocateComponent(msg);
+ handled = true;
+ break;
+ }
+
+ case ACodec::kWhatConfigureComponent:
+ {
+ onConfigureComponent(msg);
+ handled = true;
+ break;
+ }
+
+ case ACodec::kWhatStart:
+ {
+ onStart();
+ handled = true;
+ break;
+ }
+
case ACodec::kWhatShutdown:
{
sp<AMessage> notify = mCodec->mNotify->dup();
@@ -1787,27 +2554,54 @@ bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
void ACodec::UninitializedState::onSetup(
const sp<AMessage> &msg) {
+ onAllocateComponent(msg);
+ onConfigureComponent(msg);
+ onStart();
+}
+
+void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
+ ALOGV("onAllocateComponent");
+
+ if (mCodec->mNode != NULL) {
+ CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
+
+ mCodec->mNativeWindow.clear();
+ mCodec->mNode = NULL;
+ mCodec->mOMX.clear();
+ mCodec->mComponentName.clear();
+ }
+
OMXClient client;
CHECK_EQ(client.connect(), (status_t)OK);
sp<IOMX> omx = client.interface();
+ Vector<String8> matchingCodecs;
+
AString mime;
- CHECK(msg->findString("mime", &mime));
- Vector<String8> matchingCodecs;
- OMXCodec::findMatchingCodecs(
- mime.c_str(),
- false, // createEncoder
- NULL, // matchComponentName
- 0, // flags
- &matchingCodecs);
+ AString componentName;
+ if (msg->findString("componentName", &componentName)) {
+ matchingCodecs.push_back(String8(componentName.c_str()));
+ } else {
+ CHECK(msg->findString("mime", &mime));
+
+ int32_t encoder;
+ if (!msg->findInt32("encoder", &encoder)) {
+ encoder = false;
+ }
+
+ OMXCodec::findMatchingCodecs(
+ mime.c_str(),
+ encoder, // createEncoder
+ NULL, // matchComponentName
+ 0, // flags
+ &matchingCodecs);
+ }
sp<CodecObserver> observer = new CodecObserver;
IOMX::node_id node = NULL;
- AString componentName;
-
for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
++matchIndex) {
componentName = matchingCodecs.itemAt(matchIndex).string();
@@ -1826,7 +2620,12 @@ void ACodec::UninitializedState::onSetup(
}
if (node == NULL) {
- ALOGE("Unable to instantiate a decoder for type '%s'.", mime.c_str());
+ if (!mime.empty()) {
+ ALOGE("Unable to instantiate a decoder for type '%s'.",
+ mime.c_str());
+ } else {
+ ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
+ }
mCodec->signalError(OMX_ErrorComponentNotFound);
return;
@@ -1844,20 +2643,52 @@ void ACodec::UninitializedState::onSetup(
mCodec->mInputEOSResult = OK;
- mCodec->configureCodec(mime.c_str(), msg);
+ {
+ sp<AMessage> notify = mCodec->mNotify->dup();
+ notify->setInt32("what", ACodec::kWhatComponentAllocated);
+ notify->setString("componentName", mCodec->mComponentName.c_str());
+ notify->post();
+ }
+}
+
+void ACodec::UninitializedState::onConfigureComponent(
+ const sp<AMessage> &msg) {
+ ALOGV("onConfigureComponent");
+
+ CHECK(mCodec->mNode != NULL);
+
+ AString mime;
+ CHECK(msg->findString("mime", &mime));
+
+ status_t err = mCodec->configureCodec(mime.c_str(), msg);
+
+ if (err != OK) {
+ mCodec->signalError(OMX_ErrorUndefined, err);
+ return;
+ }
sp<RefBase> obj;
if (msg->findObject("native-window", &obj)
- && strncmp("OMX.google.", componentName.c_str(), 11)) {
+ && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
sp<NativeWindowWrapper> nativeWindow(
static_cast<NativeWindowWrapper *>(obj.get()));
CHECK(nativeWindow != NULL);
mCodec->mNativeWindow = nativeWindow->getNativeWindow();
}
-
CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
- CHECK_EQ(omx->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle),
+ {
+ sp<AMessage> notify = mCodec->mNotify->dup();
+ notify->setInt32("what", ACodec::kWhatComponentConfigured);
+ notify->post();
+ }
+}
+
+void ACodec::UninitializedState::onStart() {
+ ALOGV("onStart");
+
+ CHECK_EQ(mCodec->mOMX->sendCommand(
+ mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
(status_t)OK);
mCodec->changeState(mCodec->mLoadedToIdleState);
@@ -1878,7 +2709,7 @@ void ACodec::LoadedToIdleState::stateEntered() {
"(error 0x%08x)",
err);
- mCodec->signalError();
+ mCodec->signalError(OMX_ErrorUndefined, err);
}
}
@@ -2202,7 +3033,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
"port reconfiguration (error 0x%08x)",
err);
- mCodec->signalError();
+ mCodec->signalError(OMX_ErrorUndefined, err);
// This is technically not correct, since we were unable
// to allocate output buffers and therefore the output port
@@ -2240,7 +3071,8 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
////////////////////////////////////////////////////////////////////////////////
ACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
- : BaseState(codec) {
+ : BaseState(codec),
+ mComponentNowIdle(false) {
}
bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
@@ -2274,6 +3106,7 @@ bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
void ACodec::ExecutingToIdleState::stateEntered() {
ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
+ mComponentNowIdle = false;
mCodec->mSentFormat = false;
}
@@ -2285,6 +3118,8 @@ bool ACodec::ExecutingToIdleState::onOMXEvent(
CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
+ mComponentNowIdle = true;
+
changeStateIfWeOwnAllBuffers();
return true;
@@ -2303,7 +3138,7 @@ bool ACodec::ExecutingToIdleState::onOMXEvent(
}
void ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
- if (mCodec->allYourBuffersAreBelongToUs()) {
+ if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
CHECK_EQ(mCodec->mOMX->sendCommand(
mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
(status_t)OK);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 3f9ba47e1345..cfb1e29aa1bf 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -29,12 +29,14 @@ LOCAL_SRC_FILES:= \
MPEG4Writer.cpp \
MediaBuffer.cpp \
MediaBufferGroup.cpp \
+ MediaCodec.cpp \
MediaDefs.cpp \
MediaExtractor.cpp \
MediaSource.cpp \
MediaSourceSplitter.cpp \
MetaData.cpp \
NuCachedSource2.cpp \
+ NuMediaExtractor.cpp \
OMXClient.cpp \
OMXCodec.cpp \
OggExtractor.cpp \
@@ -61,20 +63,26 @@ LOCAL_C_INCLUDES:= \
$(TOP)/external/openssl/include \
LOCAL_SHARED_LIBRARIES := \
- libbinder \
- libmedia \
- libutils \
- libcutils \
- libui \
- libsonivox \
- libvorbisidec \
+ libbinder \
+ libmedia \
+ libutils \
+ libcutils \
+ libui \
+ libsonivox \
+ libvorbisidec \
libstagefright_yuv \
libcamera_client \
- libdrmframework \
- libcrypto \
- libssl \
- libgui \
+ libdrmframework \
+ libcrypto \
+ libssl \
+ libgui \
libstagefright_omx \
+ liblog \
+ libicuuc \
+ libicui18n \
+ libz \
+ libdl \
+ libchromium_net \
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
@@ -88,51 +96,14 @@ LOCAL_STATIC_LIBRARIES := \
libstagefright_httplive \
libstagefright_id3 \
libFLAC \
+ libstagefright_chromium_http \
-################################################################################
-
-# The following was shamelessly copied from external/webkit/Android.mk and
-# currently must follow the same logic to determine how webkit was built and
-# if it's safe to link against libchromium_net
-
-# See if the user has specified a stack they want to use
-HTTP_STACK = $(HTTP)
-# We default to the Chrome HTTP stack.
-DEFAULT_HTTP = chrome
-ALT_HTTP = android
-
-ifneq ($(HTTP_STACK),chrome)
- ifneq ($(HTTP_STACK),android)
- # No HTTP stack is specified, pickup the one we want as default.
- ifeq ($(USE_ALT_HTTP),true)
- HTTP_STACK = $(ALT_HTTP)
- else
- HTTP_STACK = $(DEFAULT_HTTP)
- endif
- endif
-endif
-
-ifeq ($(HTTP_STACK),chrome)
-
-LOCAL_SHARED_LIBRARIES += \
- liblog \
- libicuuc \
- libicui18n \
- libz \
- libdl \
-
-LOCAL_STATIC_LIBRARIES += \
- libstagefright_chromium_http
-
-LOCAL_SHARED_LIBRARIES += libstlport libchromium_net
+LOCAL_SHARED_LIBRARIES += libstlport
include external/stlport/libstlport.mk
+# TODO: Chromium is always available, so this flag can be removed.
LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
-endif # ifeq ($(HTTP_STACK),chrome)
-
-################################################################################
-
LOCAL_SHARED_LIBRARIES += \
libstagefright_enc_common \
libstagefright_avc_common \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 70945e33cdc7..8cfb8d3858a3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -47,10 +47,8 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXCodec.h>
-#include <surfaceflinger/Surface.h>
#include <gui/ISurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
#include <media/stagefright/foundation/AMessage.h>
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ed1d5f46ba94..2df55282f35f 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -27,7 +27,7 @@
#include <media/stagefright/MetaData.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
#include <utils/String8.h>
#include <cutils/properties.h>
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index 0b4ecbea4e6c..f70237628291 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -244,7 +244,7 @@ void MPEG2TSWriter::SourceInfo::extractCodecSpecificData() {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kNotifyBuffer);
- notify->setObject("buffer", out);
+ notify->setBuffer("buffer", out);
notify->setInt32("oob", true);
notify->post();
}
@@ -270,7 +270,7 @@ void MPEG2TSWriter::SourceInfo::postAVCFrame(MediaBuffer *buffer) {
copy->meta()->setInt32("isSync", true);
}
- notify->setObject("buffer", copy);
+ notify->setBuffer("buffer", copy);
notify->post();
}
@@ -351,7 +351,7 @@ bool MPEG2TSWriter::SourceInfo::flushAACFrames() {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kNotifyBuffer);
- notify->setObject("buffer", mAACBuffer);
+ notify->setBuffer("buffer", mAACBuffer);
notify->post();
mAACBuffer.clear();
@@ -614,10 +614,8 @@ void MPEG2TSWriter::onMessageReceived(const sp<AMessage> &msg) {
++mNumSourcesDone;
} else if (what == SourceInfo::kNotifyBuffer) {
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
-
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
int32_t oob;
if (msg->findInt32("oob", &oob) && oob) {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
new file mode 100644
index 000000000000..e14b1c406dc7
--- /dev/null
+++ b/media/libstagefright/MediaCodec.cpp
@@ -0,0 +1,1179 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaCodec"
+#include <utils/Log.h>
+
+#include <media/stagefright/MediaCodec.h>
+
+#include "include/SoftwareRenderer.h"
+
+#include <gui/SurfaceTextureClient.h>
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/ACodec.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/NativeWindowWrapper.h>
+
+namespace android {
+
+// static
+sp<MediaCodec> MediaCodec::CreateByType(
+ const sp<ALooper> &looper, const char *mime, bool encoder) {
+ sp<MediaCodec> codec = new MediaCodec(looper);
+ if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
+ return NULL;
+ }
+
+ return codec;
+}
+
+// static
+sp<MediaCodec> MediaCodec::CreateByComponentName(
+ const sp<ALooper> &looper, const char *name) {
+ sp<MediaCodec> codec = new MediaCodec(looper);
+ if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
+ return NULL;
+ }
+
+ return codec;
+}
+
+MediaCodec::MediaCodec(const sp<ALooper> &looper)
+ : mState(UNINITIALIZED),
+ mLooper(looper),
+ mCodec(new ACodec),
+ mFlags(0),
+ mSoftRenderer(NULL),
+ mDequeueInputTimeoutGeneration(0),
+ mDequeueInputReplyID(0),
+ mDequeueOutputTimeoutGeneration(0),
+ mDequeueOutputReplyID(0) {
+}
+
+MediaCodec::~MediaCodec() {
+ CHECK_EQ(mState, UNINITIALIZED);
+}
+
+// static
+status_t MediaCodec::PostAndAwaitResponse(
+ const sp<AMessage> &msg, sp<AMessage> *response) {
+ status_t err = msg->postAndAwaitResponse(response);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (!(*response)->findInt32("err", &err)) {
+ err = OK;
+ }
+
+ return err;
+}
+
+status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
+ // Current video decoders do not return from OMX_FillThisBuffer
+ // quickly, violating the OpenMAX specs, until that is remedied
+ // we need to invest in an extra looper to free the main event
+ // queue.
+ bool needDedicatedLooper = false;
+ if (nameIsType && !strncasecmp(name, "video/", 6)) {
+ needDedicatedLooper = true;
+ } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) {
+ needDedicatedLooper = true;
+ }
+
+ if (needDedicatedLooper) {
+ if (mCodecLooper == NULL) {
+ mCodecLooper = new ALooper;
+ mCodecLooper->setName("CodecLooper");
+ mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
+ }
+
+ mCodecLooper->registerHandler(mCodec);
+ } else {
+ mLooper->registerHandler(mCodec);
+ }
+
+ mLooper->registerHandler(this);
+
+ mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
+
+ sp<AMessage> msg = new AMessage(kWhatInit, id());
+ msg->setString("name", name);
+ msg->setInt32("nameIsType", nameIsType);
+
+ if (nameIsType) {
+ msg->setInt32("encoder", encoder);
+ }
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::configure(
+ const sp<AMessage> &format,
+ const sp<SurfaceTextureClient> &nativeWindow,
+ uint32_t flags) {
+ sp<AMessage> msg = new AMessage(kWhatConfigure, id());
+
+ msg->setMessage("format", format);
+ msg->setInt32("flags", flags);
+
+ if (nativeWindow != NULL) {
+ if (!(mFlags & kFlagIsSoftwareCodec)) {
+ msg->setObject(
+ "native-window",
+ new NativeWindowWrapper(nativeWindow));
+ } else {
+ mNativeWindow = nativeWindow;
+ }
+ }
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::start() {
+ sp<AMessage> msg = new AMessage(kWhatStart, id());
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::stop() {
+ sp<AMessage> msg = new AMessage(kWhatStop, id());
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::queueInputBuffer(
+ size_t index,
+ size_t offset,
+ size_t size,
+ int64_t presentationTimeUs,
+ uint32_t flags) {
+ sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
+ msg->setSize("index", index);
+ msg->setSize("offset", offset);
+ msg->setSize("size", size);
+ msg->setInt64("timeUs", presentationTimeUs);
+ msg->setInt32("flags", flags);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
+ sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
+ msg->setInt64("timeoutUs", timeoutUs);
+
+ sp<AMessage> response;
+ status_t err;
+ if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
+ return err;
+ }
+
+ CHECK(response->findSize("index", index));
+
+ return OK;
+}
+
+status_t MediaCodec::dequeueOutputBuffer(
+ size_t *index,
+ size_t *offset,
+ size_t *size,
+ int64_t *presentationTimeUs,
+ uint32_t *flags,
+ int64_t timeoutUs) {
+ sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
+ msg->setInt64("timeoutUs", timeoutUs);
+
+ sp<AMessage> response;
+ status_t err;
+ if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
+ return err;
+ }
+
+ CHECK(response->findSize("index", index));
+ CHECK(response->findSize("offset", offset));
+ CHECK(response->findSize("size", size));
+ CHECK(response->findInt64("timeUs", presentationTimeUs));
+ CHECK(response->findInt32("flags", (int32_t *)flags));
+
+ return OK;
+}
+
+status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
+ sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
+ msg->setSize("index", index);
+ msg->setInt32("render", true);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::releaseOutputBuffer(size_t index) {
+ sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
+ msg->setSize("index", index);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
+ sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
+
+ sp<AMessage> response;
+ status_t err;
+ if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
+ return err;
+ }
+
+ CHECK(response->findMessage("format", format));
+
+ return OK;
+}
+
+status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
+ sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
+ msg->setInt32("portIndex", kPortIndexInput);
+ msg->setPointer("buffers", buffers);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
+ sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
+ msg->setInt32("portIndex", kPortIndexOutput);
+ msg->setPointer("buffers", buffers);
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+status_t MediaCodec::flush() {
+ sp<AMessage> msg = new AMessage(kWhatFlush, id());
+
+ sp<AMessage> response;
+ return PostAndAwaitResponse(msg, &response);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void MediaCodec::cancelPendingDequeueOperations() {
+ if (mFlags & kFlagDequeueInputPending) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+ response->postReply(mDequeueInputReplyID);
+
+ ++mDequeueInputTimeoutGeneration;
+ mDequeueInputReplyID = 0;
+ mFlags &= ~kFlagDequeueInputPending;
+ }
+
+ if (mFlags & kFlagDequeueOutputPending) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+ response->postReply(mDequeueOutputReplyID);
+
+ ++mDequeueOutputTimeoutGeneration;
+ mDequeueOutputReplyID = 0;
+ mFlags &= ~kFlagDequeueOutputPending;
+ }
+}
+
+bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
+ if (mState != STARTED
+ || (mFlags & kFlagStickyError)
+ || (newRequest && (mFlags & kFlagDequeueInputPending))) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+
+ return true;
+ }
+
+ ssize_t index = dequeuePortBuffer(kPortIndexInput);
+
+ if (index < 0) {
+ CHECK_EQ(index, -EAGAIN);
+ return false;
+ }
+
+ sp<AMessage> response = new AMessage;
+ response->setSize("index", index);
+ response->postReply(replyID);
+
+ return true;
+}
+
+bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
+ sp<AMessage> response = new AMessage;
+
+ if (mState != STARTED
+ || (mFlags & kFlagStickyError)
+ || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
+ response->setInt32("err", INVALID_OPERATION);
+ } else if (mFlags & kFlagOutputBuffersChanged) {
+ response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
+ mFlags &= ~kFlagOutputBuffersChanged;
+ } else if (mFlags & kFlagOutputFormatChanged) {
+ response->setInt32("err", INFO_FORMAT_CHANGED);
+ mFlags &= ~kFlagOutputFormatChanged;
+ } else {
+ ssize_t index = dequeuePortBuffer(kPortIndexOutput);
+
+ if (index < 0) {
+ CHECK_EQ(index, -EAGAIN);
+ return false;
+ }
+
+ const sp<ABuffer> &buffer =
+ mPortBuffers[kPortIndexOutput].itemAt(index).mData;
+
+ response->setSize("index", index);
+ response->setSize("offset", buffer->offset());
+ response->setSize("size", buffer->size());
+
+ int64_t timeUs;
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+
+ response->setInt64("timeUs", timeUs);
+
+ int32_t omxFlags;
+ CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
+
+ uint32_t flags = 0;
+ if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
+ flags |= BUFFER_FLAG_SYNCFRAME;
+ }
+ if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ flags |= BUFFER_FLAG_CODECCONFIG;
+ }
+ if (omxFlags & OMX_BUFFERFLAG_EOS) {
+ flags |= BUFFER_FLAG_EOS;
+ }
+
+ response->setInt32("flags", flags);
+ }
+
+ response->postReply(replyID);
+
+ return true;
+}
+
+void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatCodecNotify:
+ {
+ int32_t what;
+ CHECK(msg->findInt32("what", &what));
+
+ switch (what) {
+ case ACodec::kWhatError:
+ {
+ int32_t omxError, internalError;
+ CHECK(msg->findInt32("omx-error", &omxError));
+ CHECK(msg->findInt32("err", &internalError));
+
+ ALOGE("Codec reported an error. "
+ "(omx error 0x%08x, internalError %d)",
+ omxError, internalError);
+
+ bool sendErrorReponse = true;
+
+ switch (mState) {
+ case INITIALIZING:
+ {
+ setState(UNINITIALIZED);
+ break;
+ }
+
+ case CONFIGURING:
+ {
+ setState(INITIALIZED);
+ break;
+ }
+
+ case STARTING:
+ {
+ setState(CONFIGURED);
+ break;
+ }
+
+ case STOPPING:
+ {
+ // Ignore the error, assuming we'll still get
+ // the shutdown complete notification.
+
+ sendErrorReponse = false;
+ break;
+ }
+
+ case FLUSHING:
+ {
+ setState(STARTED);
+ break;
+ }
+
+ case STARTED:
+ {
+ sendErrorReponse = false;
+
+ mFlags |= kFlagStickyError;
+
+ cancelPendingDequeueOperations();
+ break;
+ }
+
+ default:
+ {
+ sendErrorReponse = false;
+
+ mFlags |= kFlagStickyError;
+ break;
+ }
+ }
+
+ if (sendErrorReponse) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", UNKNOWN_ERROR);
+
+ response->postReply(mReplyID);
+ }
+ break;
+ }
+
+ case ACodec::kWhatComponentAllocated:
+ {
+ CHECK_EQ(mState, INITIALIZING);
+ setState(INITIALIZED);
+
+ AString componentName;
+ CHECK(msg->findString("componentName", &componentName));
+
+ if (componentName.startsWith("OMX.google.")) {
+ mFlags |= kFlagIsSoftwareCodec;
+ } else {
+ mFlags &= ~kFlagIsSoftwareCodec;
+ }
+
+ (new AMessage)->postReply(mReplyID);
+ break;
+ }
+
+ case ACodec::kWhatComponentConfigured:
+ {
+ CHECK_EQ(mState, CONFIGURING);
+ setState(CONFIGURED);
+
+ (new AMessage)->postReply(mReplyID);
+ break;
+ }
+
+ case ACodec::kWhatBuffersAllocated:
+ {
+ int32_t portIndex;
+ CHECK(msg->findInt32("portIndex", &portIndex));
+
+ ALOGV("%s buffers allocated",
+ portIndex == kPortIndexInput ? "input" : "output");
+
+ CHECK(portIndex == kPortIndexInput
+ || portIndex == kPortIndexOutput);
+
+ mPortBuffers[portIndex].clear();
+
+ Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
+ for (size_t i = 0;; ++i) {
+ AString name = StringPrintf("buffer-id_%d", i);
+
+ void *bufferID;
+ if (!msg->findPointer(name.c_str(), &bufferID)) {
+ break;
+ }
+
+ name = StringPrintf("data_%d", i);
+
+ BufferInfo info;
+ info.mBufferID = bufferID;
+ info.mOwnedByClient = false;
+ CHECK(msg->findBuffer(name.c_str(), &info.mData));
+
+ buffers->push_back(info);
+ }
+
+ if (portIndex == kPortIndexOutput) {
+ if (mState == STARTING) {
+ // We're always allocating output buffers after
+ // allocating input buffers, so this is a good
+ // indication that now all buffers are allocated.
+ setState(STARTED);
+ (new AMessage)->postReply(mReplyID);
+ } else {
+ mFlags |= kFlagOutputBuffersChanged;
+ }
+ }
+ break;
+ }
+
+ case ACodec::kWhatOutputFormatChanged:
+ {
+ ALOGV("codec output format changed");
+
+ if ((mFlags & kFlagIsSoftwareCodec)
+ && mNativeWindow != NULL) {
+ AString mime;
+ CHECK(msg->findString("mime", &mime));
+
+ if (!strncasecmp("video/", mime.c_str(), 6)) {
+ delete mSoftRenderer;
+ mSoftRenderer = NULL;
+
+ int32_t width, height;
+ CHECK(msg->findInt32("width", &width));
+ CHECK(msg->findInt32("height", &height));
+
+ int32_t colorFormat;
+ CHECK(msg->findInt32(
+ "color-format", &colorFormat));
+
+ sp<MetaData> meta = new MetaData;
+ meta->setInt32(kKeyWidth, width);
+ meta->setInt32(kKeyHeight, height);
+ meta->setInt32(kKeyColorFormat, colorFormat);
+
+ mSoftRenderer =
+ new SoftwareRenderer(mNativeWindow, meta);
+ }
+ }
+
+ mOutputFormat = msg;
+ mFlags |= kFlagOutputFormatChanged;
+ break;
+ }
+
+ case ACodec::kWhatFillThisBuffer:
+ {
+ /* size_t index = */updateBuffers(kPortIndexInput, msg);
+
+ if (mState == FLUSHING || mState == STOPPING) {
+ returnBuffersToCodecOnPort(kPortIndexInput);
+ break;
+ }
+
+ if (mFlags & kFlagDequeueInputPending) {
+ CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
+
+ ++mDequeueInputTimeoutGeneration;
+ mFlags &= ~kFlagDequeueInputPending;
+ mDequeueInputReplyID = 0;
+ }
+ break;
+ }
+
+ case ACodec::kWhatDrainThisBuffer:
+ {
+ /* size_t index = */updateBuffers(kPortIndexOutput, msg);
+
+ if (mState == FLUSHING || mState == STOPPING) {
+ returnBuffersToCodecOnPort(kPortIndexOutput);
+ break;
+ }
+
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
+
+ int32_t omxFlags;
+ CHECK(msg->findInt32("flags", &omxFlags));
+
+ buffer->meta()->setInt32("omxFlags", omxFlags);
+
+ if (mFlags & kFlagDequeueOutputPending) {
+ CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
+
+ ++mDequeueOutputTimeoutGeneration;
+ mFlags &= ~kFlagDequeueOutputPending;
+ mDequeueOutputReplyID = 0;
+ }
+ break;
+ }
+
+ case ACodec::kWhatEOS:
+ {
+ // We already notify the client of this by using the
+ // corresponding flag in "onOutputBufferReady".
+ break;
+ }
+
+ case ACodec::kWhatShutdownCompleted:
+ {
+ CHECK_EQ(mState, STOPPING);
+ setState(UNINITIALIZED);
+
+ (new AMessage)->postReply(mReplyID);
+ break;
+ }
+
+ case ACodec::kWhatFlushCompleted:
+ {
+ CHECK_EQ(mState, FLUSHING);
+ setState(STARTED);
+
+ mCodec->signalResume();
+
+ (new AMessage)->postReply(mReplyID);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+ break;
+ }
+
+ case kWhatInit:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != UNINITIALIZED) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ setState(INITIALIZING);
+
+ AString name;
+ CHECK(msg->findString("name", &name));
+
+ int32_t nameIsType;
+ int32_t encoder = false;
+ CHECK(msg->findInt32("nameIsType", &nameIsType));
+ if (nameIsType) {
+ CHECK(msg->findInt32("encoder", &encoder));
+ }
+
+ sp<AMessage> format = new AMessage;
+
+ if (nameIsType) {
+ format->setString("mime", name.c_str());
+ format->setInt32("encoder", encoder);
+ } else {
+ format->setString("componentName", name.c_str());
+ }
+
+ mCodec->initiateAllocateComponent(format);
+ break;
+ }
+
+ case kWhatConfigure:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != INITIALIZED) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ setState(CONFIGURING);
+
+ sp<RefBase> obj;
+ if (!msg->findObject("native-window", &obj)) {
+ obj.clear();
+ }
+
+ sp<AMessage> format;
+ CHECK(msg->findMessage("format", &format));
+
+ if (obj != NULL) {
+ format->setObject("native-window", obj);
+ }
+
+ uint32_t flags;
+ CHECK(msg->findInt32("flags", (int32_t *)&flags));
+
+ if (flags & CONFIGURE_FLAG_ENCODE) {
+ format->setInt32("encoder", true);
+ }
+
+ mCodec->initiateConfigureComponent(format);
+ break;
+ }
+
+ case kWhatStart:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != CONFIGURED) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ setState(STARTING);
+
+ mCodec->initiateStart();
+ break;
+ }
+
+ case kWhatStop:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != INITIALIZED
+ && mState != CONFIGURED && mState != STARTED) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ setState(STOPPING);
+
+ mCodec->initiateShutdown();
+ returnBuffersToCodec();
+ break;
+ }
+
+ case kWhatDequeueInputBuffer:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (handleDequeueInputBuffer(replyID, true /* new request */)) {
+ break;
+ }
+
+ int64_t timeoutUs;
+ CHECK(msg->findInt64("timeoutUs", &timeoutUs));
+
+ if (timeoutUs == 0ll) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", -EAGAIN);
+ response->postReply(replyID);
+ break;
+ }
+
+ mFlags |= kFlagDequeueInputPending;
+ mDequeueInputReplyID = replyID;
+
+ if (timeoutUs > 0ll) {
+ sp<AMessage> timeoutMsg =
+ new AMessage(kWhatDequeueInputTimedOut, id());
+ timeoutMsg->setInt32(
+ "generation", ++mDequeueInputTimeoutGeneration);
+ timeoutMsg->post(timeoutUs);
+ }
+ break;
+ }
+
+ case kWhatDequeueInputTimedOut:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != mDequeueInputTimeoutGeneration) {
+ // Obsolete
+ break;
+ }
+
+ CHECK(mFlags & kFlagDequeueInputPending);
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", -EAGAIN);
+ response->postReply(mDequeueInputReplyID);
+
+ mFlags &= ~kFlagDequeueInputPending;
+ mDequeueInputReplyID = 0;
+ break;
+ }
+
+ case kWhatQueueInputBuffer:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != STARTED || (mFlags & kFlagStickyError)) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ status_t err = onQueueInputBuffer(msg);
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatDequeueOutputBuffer:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
+ break;
+ }
+
+ int64_t timeoutUs;
+ CHECK(msg->findInt64("timeoutUs", &timeoutUs));
+
+ if (timeoutUs == 0ll) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", -EAGAIN);
+ response->postReply(replyID);
+ break;
+ }
+
+ mFlags |= kFlagDequeueOutputPending;
+ mDequeueOutputReplyID = replyID;
+
+ if (timeoutUs > 0ll) {
+ sp<AMessage> timeoutMsg =
+ new AMessage(kWhatDequeueOutputTimedOut, id());
+ timeoutMsg->setInt32(
+ "generation", ++mDequeueOutputTimeoutGeneration);
+ timeoutMsg->post(timeoutUs);
+ }
+ break;
+ }
+
+ case kWhatDequeueOutputTimedOut:
+ {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+
+ if (generation != mDequeueOutputTimeoutGeneration) {
+ // Obsolete
+ break;
+ }
+
+ CHECK(mFlags & kFlagDequeueOutputPending);
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", -EAGAIN);
+ response->postReply(mDequeueOutputReplyID);
+
+ mFlags &= ~kFlagDequeueOutputPending;
+ mDequeueOutputReplyID = 0;
+ break;
+ }
+
+ case kWhatReleaseOutputBuffer:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != STARTED || (mFlags & kFlagStickyError)) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ status_t err = onReleaseOutputBuffer(msg);
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", err);
+ response->postReply(replyID);
+ break;
+ }
+
+ case kWhatGetBuffers:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != STARTED || (mFlags & kFlagStickyError)) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ int32_t portIndex;
+ CHECK(msg->findInt32("portIndex", &portIndex));
+
+ Vector<sp<ABuffer> > *dstBuffers;
+ CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
+
+ dstBuffers->clear();
+ const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
+
+ for (size_t i = 0; i < srcBuffers.size(); ++i) {
+ const BufferInfo &info = srcBuffers.itemAt(i);
+
+ dstBuffers->push_back(info.mData);
+ }
+
+ (new AMessage)->postReply(replyID);
+ break;
+ }
+
+ case kWhatFlush:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if (mState != STARTED || (mFlags & kFlagStickyError)) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ mReplyID = replyID;
+ setState(FLUSHING);
+
+ mCodec->signalFlush();
+ returnBuffersToCodec();
+ break;
+ }
+
+ case kWhatGetOutputFormat:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ if ((mState != STARTED && mState != FLUSHING)
+ || (mFlags & kFlagStickyError)) {
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", INVALID_OPERATION);
+
+ response->postReply(replyID);
+ break;
+ }
+
+ sp<AMessage> response = new AMessage;
+ response->setMessage("format", mOutputFormat);
+ response->postReply(replyID);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+}
+
+void MediaCodec::setState(State newState) {
+ if (newState == UNINITIALIZED) {
+ delete mSoftRenderer;
+ mSoftRenderer = NULL;
+
+ mNativeWindow.clear();
+
+ mOutputFormat.clear();
+ mFlags &= ~kFlagOutputFormatChanged;
+ mFlags &= ~kFlagOutputBuffersChanged;
+ mFlags &= ~kFlagStickyError;
+ }
+
+ mState = newState;
+
+ cancelPendingDequeueOperations();
+}
+
+void MediaCodec::returnBuffersToCodec() {
+ returnBuffersToCodecOnPort(kPortIndexInput);
+ returnBuffersToCodecOnPort(kPortIndexOutput);
+}
+
+void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
+ CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
+
+ Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
+
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ BufferInfo *info = &buffers->editItemAt(i);
+
+ if (info->mNotify != NULL) {
+ sp<AMessage> msg = info->mNotify;
+ info->mNotify = NULL;
+ info->mOwnedByClient = false;
+
+ if (portIndex == kPortIndexInput) {
+ msg->setInt32("err", ERROR_END_OF_STREAM);
+ }
+ msg->post();
+ }
+ }
+
+ mAvailPortBuffers[portIndex].clear();
+}
+
+size_t MediaCodec::updateBuffers(
+ int32_t portIndex, const sp<AMessage> &msg) {
+ CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
+
+ void *bufferID;
+ CHECK(msg->findPointer("buffer-id", &bufferID));
+
+ Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
+
+ for (size_t i = 0; i < buffers->size(); ++i) {
+ BufferInfo *info = &buffers->editItemAt(i);
+
+ if (info->mBufferID == bufferID) {
+ CHECK(info->mNotify == NULL);
+ CHECK(msg->findMessage("reply", &info->mNotify));
+
+ mAvailPortBuffers[portIndex].push_back(i);
+
+ return i;
+ }
+ }
+
+ TRESPASS();
+
+ return 0;
+}
+
+status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
+ size_t index;
+ size_t offset;
+ size_t size;
+ int64_t timeUs;
+ uint32_t flags;
+ CHECK(msg->findSize("index", &index));
+ CHECK(msg->findSize("offset", &offset));
+ CHECK(msg->findSize("size", &size));
+ CHECK(msg->findInt64("timeUs", &timeUs));
+ CHECK(msg->findInt32("flags", (int32_t *)&flags));
+
+ if (index >= mPortBuffers[kPortIndexInput].size()) {
+ return -ERANGE;
+ }
+
+ BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
+
+ if (info->mNotify == NULL || !info->mOwnedByClient) {
+ return -EACCES;
+ }
+
+ if (offset + size > info->mData->capacity()) {
+ return -EINVAL;
+ }
+
+ sp<AMessage> reply = info->mNotify;
+ info->mNotify = NULL;
+ info->mOwnedByClient = false;
+
+ info->mData->setRange(offset, size);
+ info->mData->meta()->setInt64("timeUs", timeUs);
+
+ if (flags & BUFFER_FLAG_EOS) {
+ info->mData->meta()->setInt32("eos", true);
+ }
+
+ if (flags & BUFFER_FLAG_CODECCONFIG) {
+ info->mData->meta()->setInt32("csd", true);
+ }
+
+ reply->setBuffer("buffer", info->mData);
+ reply->post();
+
+ return OK;
+}
+
+status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
+ size_t index;
+ CHECK(msg->findSize("index", &index));
+
+ int32_t render;
+ if (!msg->findInt32("render", &render)) {
+ render = 0;
+ }
+
+ if (mState != STARTED) {
+ return -EINVAL;
+ }
+
+ if (index >= mPortBuffers[kPortIndexOutput].size()) {
+ return -ERANGE;
+ }
+
+ BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
+
+ if (info->mNotify == NULL || !info->mOwnedByClient) {
+ return -EACCES;
+ }
+
+ if (render) {
+ info->mNotify->setInt32("render", true);
+
+ if (mSoftRenderer != NULL) {
+ mSoftRenderer->render(
+ info->mData->data(), info->mData->size(), NULL);
+ }
+ }
+
+ info->mNotify->post();
+ info->mNotify = NULL;
+ info->mOwnedByClient = false;
+
+ return OK;
+}
+
+ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
+ CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
+
+ List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
+
+ if (availBuffers->empty()) {
+ return -EAGAIN;
+ }
+
+ size_t index = *availBuffers->begin();
+ availBuffers->erase(availBuffers->begin());
+
+ BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
+ CHECK(!info->mOwnedByClient);
+ info->mOwnedByClient = true;
+
+ return index;
+}
+
+} // namespace android
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
new file mode 100644
index 000000000000..afd476356047
--- /dev/null
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -0,0 +1,433 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "NuMediaExtractor"
+#include <utils/Log.h>
+
+#include <media/stagefright/NuMediaExtractor.h>
+
+#include "include/ESDS.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
+
+namespace android {
+
+NuMediaExtractor::NuMediaExtractor() {
+}
+
+NuMediaExtractor::~NuMediaExtractor() {
+ releaseTrackSamples();
+
+ for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
+ TrackInfo *info = &mSelectedTracks.editItemAt(i);
+
+ CHECK_EQ((status_t)OK, info->mSource->stop());
+ }
+
+ mSelectedTracks.clear();
+}
+
+status_t NuMediaExtractor::setDataSource(const char *path) {
+ sp<DataSource> dataSource = DataSource::CreateFromURI(path);
+
+ if (dataSource == NULL) {
+ return -ENOENT;
+ }
+
+ mImpl = MediaExtractor::Create(dataSource);
+
+ if (mImpl == NULL) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ return OK;
+}
+
+size_t NuMediaExtractor::countTracks() const {
+ return mImpl == NULL ? 0 : mImpl->countTracks();
+}
+
+status_t NuMediaExtractor::getTrackFormat(
+ size_t index, sp<AMessage> *format) const {
+ *format = NULL;
+
+ if (mImpl == NULL) {
+ return -EINVAL;
+ }
+
+ if (index >= mImpl->countTracks()) {
+ return -ERANGE;
+ }
+
+ sp<MetaData> meta = mImpl->getTrackMetaData(index);
+
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ sp<AMessage> msg = new AMessage;
+ msg->setString("mime", mime);
+
+ if (!strncasecmp("video/", mime, 6)) {
+ int32_t width, height;
+ CHECK(meta->findInt32(kKeyWidth, &width));
+ CHECK(meta->findInt32(kKeyHeight, &height));
+
+ msg->setInt32("width", width);
+ msg->setInt32("height", height);
+ } else {
+ CHECK(!strncasecmp("audio/", mime, 6));
+
+ int32_t numChannels, sampleRate;
+ CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+ CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
+
+ msg->setInt32("channel-count", numChannels);
+ msg->setInt32("sample-rate", sampleRate);
+ }
+
+ int32_t maxInputSize;
+ if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
+ msg->setInt32("max-input-size", maxInputSize);
+ }
+
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (meta->findData(kKeyAVCC, &type, &data, &size)) {
+ // Parse the AVCDecoderConfigurationRecord
+
+ const uint8_t *ptr = (const uint8_t *)data;
+
+ CHECK(size >= 7);
+ CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1
+ uint8_t profile = ptr[1];
+ uint8_t level = ptr[3];
+
+ // There is decodable content out there that fails the following
+ // assertion, let's be lenient for now...
+ // CHECK((ptr[4] >> 2) == 0x3f); // reserved
+
+ size_t lengthSize = 1 + (ptr[4] & 3);
+
+ // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
+ // violates it...
+ // CHECK((ptr[5] >> 5) == 7); // reserved
+
+ size_t numSeqParameterSets = ptr[5] & 31;
+
+ ptr += 6;
+ size -= 6;
+
+ sp<ABuffer> buffer = new ABuffer(1024);
+ buffer->setRange(0, 0);
+
+ for (size_t i = 0; i < numSeqParameterSets; ++i) {
+ CHECK(size >= 2);
+ size_t length = U16_AT(ptr);
+
+ ptr += 2;
+ size -= 2;
+
+ CHECK(size >= length);
+
+ memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
+ memcpy(buffer->data() + buffer->size() + 4, ptr, length);
+ buffer->setRange(0, buffer->size() + 4 + length);
+
+ ptr += length;
+ size -= length;
+ }
+
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+
+ msg->setBuffer("csd-0", buffer);
+
+ buffer = new ABuffer(1024);
+ buffer->setRange(0, 0);
+
+ CHECK(size >= 1);
+ size_t numPictureParameterSets = *ptr;
+ ++ptr;
+ --size;
+
+ for (size_t i = 0; i < numPictureParameterSets; ++i) {
+ CHECK(size >= 2);
+ size_t length = U16_AT(ptr);
+
+ ptr += 2;
+ size -= 2;
+
+ CHECK(size >= length);
+
+ memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
+ memcpy(buffer->data() + buffer->size() + 4, ptr, length);
+ buffer->setRange(0, buffer->size() + 4 + length);
+
+ ptr += length;
+ size -= length;
+ }
+
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ msg->setBuffer("csd-1", buffer);
+ } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
+ ESDS esds((const char *)data, size);
+ CHECK_EQ(esds.InitCheck(), (status_t)OK);
+
+ const void *codec_specific_data;
+ size_t codec_specific_data_size;
+ esds.getCodecSpecificInfo(
+ &codec_specific_data, &codec_specific_data_size);
+
+ sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
+
+ memcpy(buffer->data(), codec_specific_data,
+ codec_specific_data_size);
+
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ msg->setBuffer("csd-0", buffer);
+ } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
+ sp<ABuffer> buffer = new ABuffer(size);
+ memcpy(buffer->data(), data, size);
+
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ msg->setBuffer("csd-0", buffer);
+
+ if (!meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
+ return -EINVAL;
+ }
+
+ buffer = new ABuffer(size);
+ memcpy(buffer->data(), data, size);
+
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ msg->setBuffer("csd-1", buffer);
+ }
+
+ *format = msg;
+
+ return OK;
+}
+
+status_t NuMediaExtractor::selectTrack(size_t index) {
+ if (mImpl == NULL) {
+ return -EINVAL;
+ }
+
+ if (index >= mImpl->countTracks()) {
+ return -ERANGE;
+ }
+
+ for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
+ TrackInfo *info = &mSelectedTracks.editItemAt(i);
+
+ if (info->mTrackIndex == index) {
+ // This track has already been selected.
+ return OK;
+ }
+ }
+
+ sp<MediaSource> source = mImpl->getTrack(index);
+
+ CHECK_EQ((status_t)OK, source->start());
+
+ mSelectedTracks.push();
+ TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);
+
+ info->mSource = source;
+ info->mTrackIndex = index;
+ info->mFinalResult = OK;
+ info->mSample = NULL;
+ info->mSampleTimeUs = -1ll;
+ info->mFlags = 0;
+
+ const char *mime;
+ CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
+
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
+ info->mFlags |= kIsVorbis;
+ }
+
+ return OK;
+}
+
+void NuMediaExtractor::releaseTrackSamples() {
+ for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
+ TrackInfo *info = &mSelectedTracks.editItemAt(i);
+
+ if (info->mSample != NULL) {
+ info->mSample->release();
+ info->mSample = NULL;
+
+ info->mSampleTimeUs = -1ll;
+ }
+ }
+}
+
+ssize_t NuMediaExtractor::fetchTrackSamples(int64_t seekTimeUs) {
+ TrackInfo *minInfo = NULL;
+ ssize_t minIndex = -1;
+
+ for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
+ TrackInfo *info = &mSelectedTracks.editItemAt(i);
+
+ if (seekTimeUs >= 0ll) {
+ info->mFinalResult = OK;
+
+ if (info->mSample != NULL) {
+ info->mSample->release();
+ info->mSample = NULL;
+ info->mSampleTimeUs = -1ll;
+ }
+ } else if (info->mFinalResult != OK) {
+ continue;
+ }
+
+ if (info->mSample == NULL) {
+ MediaSource::ReadOptions options;
+ if (seekTimeUs >= 0ll) {
+ options.setSeekTo(seekTimeUs);
+ }
+ status_t err = info->mSource->read(&info->mSample, &options);
+
+ if (err != OK) {
+ CHECK(info->mSample == NULL);
+
+ info->mFinalResult = err;
+ info->mSampleTimeUs = -1ll;
+ continue;
+ } else {
+ CHECK(info->mSample != NULL);
+ CHECK(info->mSample->meta_data()->findInt64(
+ kKeyTime, &info->mSampleTimeUs));
+ }
+ }
+
+ if (minInfo == NULL || info->mSampleTimeUs < minInfo->mSampleTimeUs) {
+ minInfo = info;
+ minIndex = i;
+ }
+ }
+
+ return minIndex;
+}
+
+status_t NuMediaExtractor::seekTo(int64_t timeUs) {
+ return fetchTrackSamples(timeUs);
+}
+
+status_t NuMediaExtractor::advance() {
+ ssize_t minIndex = fetchTrackSamples();
+
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
+
+ info->mSample->release();
+ info->mSample = NULL;
+ info->mSampleTimeUs = -1ll;
+
+ return OK;
+}
+
+status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
+ ssize_t minIndex = fetchTrackSamples();
+
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
+
+ size_t sampleSize = info->mSample->range_length();
+
+ if (info->mFlags & kIsVorbis) {
+ // Each sample's data is suffixed by the number of page samples
+ // or -1 if not available.
+ sampleSize += sizeof(int32_t);
+ }
+
+ if (buffer->capacity() < sampleSize) {
+ return -ENOMEM;
+ }
+
+ const uint8_t *src =
+ (const uint8_t *)info->mSample->data()
+ + info->mSample->range_offset();
+
+ memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length());
+
+ if (info->mFlags & kIsVorbis) {
+ int32_t numPageSamples;
+ if (!info->mSample->meta_data()->findInt32(
+ kKeyValidSamples, &numPageSamples)) {
+ numPageSamples = -1;
+ }
+
+ memcpy((uint8_t *)buffer->data() + info->mSample->range_length(),
+ &numPageSamples,
+ sizeof(numPageSamples));
+ }
+
+ buffer->setRange(0, sampleSize);
+
+ return OK;
+}
+
+status_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
+ ssize_t minIndex = fetchTrackSamples();
+
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
+ *trackIndex = info->mTrackIndex;
+
+ return OK;
+}
+
+status_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
+ ssize_t minIndex = fetchTrackSamples();
+
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
+ *sampleTimeUs = info->mSampleTimeUs;
+
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 7a805aa73afc..7cdb793b594e 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -335,6 +335,10 @@ status_t OMXClient::connect() {
}
void OMXClient::disconnect() {
+ if (mOMX.get() != NULL) {
+ mOMX.clear();
+ mOMX = NULL;
+ }
}
} // namespace android
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 470f7502be66..1325462714bc 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1541,6 +1541,8 @@ void OMXCodec::setComponentRole(
"video_decoder.mpeg4", "video_encoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_H263,
"video_decoder.h263", "video_encoder.h263" },
+ { MEDIA_MIMETYPE_VIDEO_VPX,
+ "video_decoder.vpx", "video_encoder.vpx" },
};
static const size_t kNumMimeToRole =
@@ -3556,6 +3558,7 @@ status_t OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t
//////////////// output port ////////////////////
// format
OMX_AUDIO_PARAM_PORTFORMATTYPE format;
+ InitOMXParams(&format);
format.nPortIndex = kPortIndexOutput;
format.nIndex = 0;
status_t err = OMX_ErrorNone;
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index aa047d61fbdc..ab2cff0be5b5 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -24,9 +24,8 @@
#include <media/stagefright/MetadataBufferType.h>
#include <ui/GraphicBuffer.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/IGraphicBufferAlloc.h>
#include <OMX_Component.h>
#include <utils/Log.h>
diff --git a/media/libstagefright/codecs/aacenc/basic_op/basic_op.h b/media/libstagefright/codecs/aacenc/basic_op/basic_op.h
index ef3c31bad98e..e878bbaccb7c 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/basic_op.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/basic_op.h
@@ -228,7 +228,7 @@ Word32 L_shr_r (Word32 L_var1, Word16 var2);
__inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2)
{
Word32 result;
- asm volatile(
+ asm (
"MOV %[result], %[L_var1], ASR %[var2] \n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
@@ -239,15 +239,12 @@ __inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2)
__inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2)
{
Word32 result;
- asm volatile(
- "MOV r2, %[L_var1] \n"
- "MOV r3, #0x7fffffff\n"
+ asm (
"MOV %[result], %[L_var1], ASL %[var2] \n"
- "TEQ r2, %[result], ASR %[var2]\n"
- "EORNE %[result],r3,r2,ASR#31\n"
- :[result]"+r"(result)
- :[L_var1]"r"(L_var1), [var2]"r"(var2)
- :"r2", "r3"
+ "TEQ %[L_var1], %[result], ASR %[var2]\n"
+ "EORNE %[result], %[mask], %[L_var1], ASR #31\n"
+ :[result]"=&r"(result)
+ :[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff)
);
return result;
}
@@ -255,10 +252,10 @@ __inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2)
__inline Word32 ASM_shr(Word32 L_var1, Word16 var2)
{
Word32 result;
- asm volatile(
+ asm (
"CMP %[var2], #15\n"
- "MOVGE %[var2], #15\n"
- "MOV %[result], %[L_var1], ASR %[var2]\n"
+ "MOVLT %[result], %[L_var1], ASR %[var2]\n"
+ "MOVGE %[result], %[L_var1], ASR #15\n"
:[result]"=r"(result)
:[L_var1]"r"(L_var1), [var2]"r"(var2)
);
@@ -268,18 +265,16 @@ __inline Word32 ASM_shr(Word32 L_var1, Word16 var2)
__inline Word32 ASM_shl(Word32 L_var1, Word16 var2)
{
Word32 result;
- asm volatile(
+ Word32 tmp;
+ asm (
"CMP %[var2], #16\n"
- "MOVGE %[var2], #16\n"
- "MOV %[result], %[L_var1], ASL %[var2]\n"
- "MOV r3, #1\n"
- "MOV r2, %[result], ASR #15\n"
- "RSB r3,r3,r3,LSL #15 \n"
- "TEQ r2, %[result], ASR #31 \n"
- "EORNE %[result], r3, %[result],ASR #31"
- :[result]"+r"(result)
- :[L_var1]"r"(L_var1), [var2]"r"(var2)
- :"r2", "r3"
+ "MOVLT %[result], %[L_var1], ASL %[var2]\n"
+ "MOVGE %[result], %[L_var1], ASL #16\n"
+ "MOV %[tmp], %[result], ASR #15\n"
+ "TEQ %[tmp], %[result], ASR #31 \n"
+ "EORNE %[result], %[mask], %[result],ASR #31"
+ :[result]"=&r"(result), [tmp]"=&r"(tmp)
+ :[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff)
);
return result;
}
@@ -295,16 +290,14 @@ __inline Word16 saturate(Word32 L_var1)
{
#if ARMV5TE_SAT
Word16 result;
+ Word32 tmp;
asm volatile (
- "MOV %[result], %[L_var1]\n"
- "MOV r3, #1\n"
- "MOV r2,%[L_var1],ASR#15\n"
- "RSB r3, r3, r3, LSL #15\n"
- "TEQ r2,%[L_var1],ASR#31\n"
- "EORNE %[result],r3,%[L_var1],ASR#31\n"
- :[result]"+r"(result)
- :[L_var1]"r"(L_var1)
- :"r2", "r3"
+ "MOV %[tmp], %[L_var1],ASR#15\n"
+ "TEQ %[tmp], %[L_var1],ASR#31\n"
+ "EORNE %[result], %[mask],%[L_var1],ASR#31\n"
+ "MOVEQ %[result], %[L_var1]\n"
+ :[result]"=&r"(result), [tmp]"=&r"(tmp)
+ :[L_var1]"r"(L_var1), [mask]"r"(0x7fff)
);
return result;
@@ -420,10 +413,10 @@ __inline Word32 L_mult(Word16 var1, Word16 var2)
{
#if ARMV5TE_L_MULT
Word32 result;
- asm volatile(
+ asm (
"SMULBB %[result], %[var1], %[var2] \n"
"QADD %[result], %[result], %[result] \n"
- :[result]"+r"(result)
+ :[result]"=r"(result)
:[var1]"r"(var1), [var2]"r"(var2)
);
return result;
@@ -450,11 +443,11 @@ __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
{
#if ARMV5TE_L_MSU
Word32 result;
- asm volatile(
+ asm (
"SMULBB %[result], %[var1], %[var2] \n"
"QADD %[result], %[result], %[result] \n"
"QSUB %[result], %[L_var3], %[result]\n"
- :[result]"+r"(result)
+ :[result]"=&r"(result)
:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
);
return result;
@@ -474,9 +467,9 @@ __inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
{
#if ARMV5TE_L_SUB
Word32 result;
- asm volatile(
+ asm (
"QSUB %[result], %[L_var1], %[L_var2]\n"
- :[result]"+r"(result)
+ :[result]"=r"(result)
:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
);
return result;
@@ -589,16 +582,14 @@ __inline Word16 add (Word16 var1, Word16 var2)
{
#if ARMV5TE_ADD
Word32 result;
- asm volatile(
+ Word32 tmp;
+ asm (
"ADD %[result], %[var1], %[var2] \n"
- "MOV r3, #0x1\n"
- "MOV r2, %[result], ASR #15\n"
- "RSB r3, r3, r3, LSL, #15\n"
- "TEQ r2, %[result], ASR #31\n"
- "EORNE %[result], r3, %[result], ASR #31"
- :[result]"+r"(result)
- :[var1]"r"(var1), [var2]"r"(var2)
- :"r2", "r3"
+ "MOV %[tmp], %[result], ASR #15 \n"
+ "TEQ %[tmp], %[result], ASR #31 \n"
+ "EORNE %[result], %[mask], %[result], ASR #31"
+ :[result]"=&r"(result), [tmp]"=&r"(tmp)
+ :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
);
return result;
#else
@@ -619,16 +610,14 @@ __inline Word16 sub(Word16 var1, Word16 var2)
{
#if ARMV5TE_SUB
Word32 result;
- asm volatile(
- "MOV r3, #1\n"
+ Word32 tmp;
+ asm (
"SUB %[result], %[var1], %[var2] \n"
- "RSB r3,r3,r3,LSL#15\n"
- "MOV r2, %[var1], ASR #15 \n"
- "TEQ r2, %[var1], ASR #31 \n"
- "EORNE %[result], r3, %[result], ASR #31 \n"
- :[result]"+r"(result)
- :[var1]"r"(var1), [var2]"r"(var2)
- :"r2", "r3"
+ "MOV %[tmp], %[var1], ASR #15 \n"
+ "TEQ %[tmp], %[var1], ASR #31 \n"
+ "EORNE %[result], %[mask], %[result], ASR #31 \n"
+ :[result]"=&r"(result), [tmp]"=&r"(tmp)
+ :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
);
return result;
#else
@@ -683,18 +672,15 @@ __inline Word16 div_s (Word16 var1, Word16 var2)
__inline Word16 mult (Word16 var1, Word16 var2)
{
#if ARMV5TE_MULT
- Word32 result;
- asm volatile(
- "SMULBB r2, %[var1], %[var2] \n"
- "MOV r3, #1\n"
- "MOV %[result], r2, ASR #15\n"
- "RSB r3, r3, r3, LSL #15\n"
- "MOV r2, %[result], ASR #15\n"
- "TEQ r2, %[result], ASR #31\n"
- "EORNE %[result], r3, %[result], ASR #31 \n"
- :[result]"+r"(result)
- :[var1]"r"(var1), [var2]"r"(var2)
- :"r2", "r3"
+ Word32 result, tmp;
+ asm (
+ "SMULBB %[tmp], %[var1], %[var2] \n"
+ "MOV %[result], %[tmp], ASR #15\n"
+ "MOV %[tmp], %[result], ASR #15\n"
+ "TEQ %[tmp], %[result], ASR #31\n"
+ "EORNE %[result], %[mask], %[result], ASR #31 \n"
+ :[result]"=&r"(result), [tmp]"=&r"(tmp)
+ :[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
);
return result;
#else
@@ -719,18 +705,17 @@ __inline Word16 norm_s (Word16 var1)
{
#if ARMV5TE_NORM_S
Word16 result;
- asm volatile(
- "MOV r2,%[var1] \n"
- "CMP r2, #0\n"
- "RSBLT %[var1], %[var1], #0 \n"
- "CLZNE %[result], %[var1]\n"
+ Word32 tmp;
+ asm (
+ "RSBS %[tmp], %[var1], #0 \n"
+ "CLZLT %[result], %[var1]\n"
+ "CLZGT %[result], %[tmp]\n"
"SUBNE %[result], %[result], #17\n"
"MOVEQ %[result], #0\n"
- "CMP r2, #-1\n"
+ "CMP %[var1], #-1\n"
"MOVEQ %[result], #15\n"
- :[result]"+r"(result)
+ :[result]"=&r"(result), [tmp]"=&r"(tmp)
:[var1]"r"(var1)
- :"r2"
);
return result;
#else
@@ -774,7 +759,7 @@ __inline Word16 norm_l (Word32 L_var1)
"CLZNE %[result], %[L_var1]\n"
"SUBNE %[result], %[result], #1\n"
"MOVEQ %[result], #0\n"
- :[result]"+r"(result)
+ :[result]"=r"(result)
:[L_var1]"r"(L_var1)
);
return result;
@@ -979,13 +964,11 @@ __inline Word16 round16(Word32 L_var1)
{
#if ARMV5TE_ROUND
Word16 result;
- asm volatile(
- "MOV r1,#0x00008000\n"
- "QADD %[result], %[L_var1], r1\n"
+ asm (
+ "QADD %[result], %[L_var1], %[bias]\n"
"MOV %[result], %[result], ASR #16 \n"
- :[result]"+r"(result)
- :[L_var1]"r"(L_var1)
- :"r1"
+ :[result]"=r"(result)
+ :[L_var1]"r"(L_var1), [bias]"r"(0x8000)
);
return result;
#else
@@ -1005,11 +988,11 @@ __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
{
#if ARMV5TE_L_MAC
Word32 result;
- asm volatile(
+ asm (
"SMULBB %[result], %[var1], %[var2]\n"
"QADD %[result], %[result], %[result]\n"
"QADD %[result], %[result], %[L_var3]\n"
- :[result]"+r"(result)
+ :[result]"=&r"(result)
: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
);
return result;
@@ -1029,9 +1012,9 @@ __inline Word32 L_add (Word32 L_var1, Word32 L_var2)
{
#if ARMV5TE_L_ADD
Word32 result;
- asm volatile(
+ asm (
"QADD %[result], %[L_var1], %[L_var2]\n"
- :[result]"+r"(result)
+ :[result]"=r"(result)
:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
);
return result;
diff --git a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h
index 9ebd1c29d774..6e5844faad34 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.h
@@ -63,7 +63,7 @@ __inline Word32 L_mpy_wx(Word32 L_var2, Word16 var1)
Word32 result;
asm volatile(
"SMULWB %[result], %[L_var2], %[var1] \n"
- :[result]"+r"(result)
+ :[result]"=r"(result)
:[L_var2]"r"(L_var2), [var1]"r"(var1)
);
return result;
diff --git a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
index 2d5d9567f2db..8ef43e265aa5 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
@@ -48,9 +48,7 @@
#define assert(_Expression) ((void)0)
#endif
-#ifdef LINUX
-#define __inline static __inline__
-#endif
+#define __inline static __inline
#define INT_BITS 32
/*
diff --git a/media/libstagefright/codecs/aacenc/inc/aacenc_core.h b/media/libstagefright/codecs/aacenc/inc/aacenc_core.h
index 1acdbbcb705d..bb75b6dc4796 100644
--- a/media/libstagefright/codecs/aacenc/inc/aacenc_core.h
+++ b/media/libstagefright/codecs/aacenc/inc/aacenc_core.h
@@ -102,7 +102,7 @@ Word16 AacEncEncode(AAC_ENCODER *hAacEnc,
const UWord8 *ancBytes, /*!< pointer to ancillary data bytes */
Word16 *numAncBytes, /*!< number of ancillary Data Bytes, send as fill element */
UWord8 *outBytes, /*!< pointer to output buffer */
- Word32 *numOutBytes /*!< number of bytes in output buffer */
+ VO_U32 *numOutBytes /*!< number of bytes in output buffer */
);
/*---------------------------------------------------------------------------
diff --git a/media/libstagefright/codecs/aacenc/inc/bitbuffer.h b/media/libstagefright/codecs/aacenc/inc/bitbuffer.h
index e53806491ac6..7c79f07ec50a 100644
--- a/media/libstagefright/codecs/aacenc/inc/bitbuffer.h
+++ b/media/libstagefright/codecs/aacenc/inc/bitbuffer.h
@@ -76,7 +76,7 @@ Word16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf);
Word16 WriteBits(HANDLE_BIT_BUF hBitBuf,
- Word32 writeValue,
+ UWord32 writeValue,
Word16 noBitsToWrite);
void ResetBitBuf(HANDLE_BIT_BUF hBitBuf,
diff --git a/media/libstagefright/codecs/aacenc/inc/psy_configuration.h b/media/libstagefright/codecs/aacenc/inc/psy_configuration.h
index 9abfc99fc413..f6981fafff95 100644
--- a/media/libstagefright/codecs/aacenc/inc/psy_configuration.h
+++ b/media/libstagefright/codecs/aacenc/inc/psy_configuration.h
@@ -31,7 +31,7 @@ typedef struct{
Word16 sfbCnt;
Word16 sfbActive; /* number of sf bands containing energy after lowpass */
- Word16 *sfbOffset;
+ const Word16 *sfbOffset;
Word32 sfbThresholdQuiet[MAX_SFB_LONG];
@@ -61,7 +61,7 @@ typedef struct{
Word16 sfbCnt;
Word16 sfbActive; /* number of sf bands containing energy after lowpass */
- Word16 *sfbOffset;
+ const Word16 *sfbOffset;
Word32 sfbThresholdQuiet[MAX_SFB_SHORT];
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc_core.c b/media/libstagefright/codecs/aacenc/src/aacenc_core.c
index 2b3bd48c9772..cecbc8f10be6 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc_core.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc_core.c
@@ -146,7 +146,7 @@ Word16 AacEncEncode(AAC_ENCODER *aacEnc, /*!< an encoder handle */
const UWord8 *ancBytes, /*!< pointer to ancillary data bytes */
Word16 *numAncBytes, /*!< number of ancillary Data Bytes */
UWord8 *outBytes, /*!< pointer to output buffer (must be large MINBITS_COEF/8*MAX_CHANNELS bytes) */
- Word32 *numOutBytes /*!< number of bytes in output buffer after processing */
+ VO_U32 *numOutBytes /*!< number of bytes in output buffer after processing */
)
{
ELEMENT_INFO *elInfo = &aacEnc->elInfo;
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index a8ab809f3f60..373b06303985 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -26,6 +26,7 @@
#include "adj_thr.h"
#include "qc_data.h"
#include "line_pe.h"
+#include <string.h>
#define minSnrLimit 0x6666 /* 1 dB */
@@ -1138,6 +1139,7 @@ void AdjustThresholds(ADJ_THR_STATE *adjThrState,
Word16 maxBitresBits = elBits->maxBits;
Word16 sideInfoBits = (qcOE->staticBitsUsed + qcOE->ancBitsUsed);
Word16 ch;
+ memset(&peData, 0, sizeof(peData));
prepareSfbPe(&peData, psyOutChannel, logSfbEnergy, sfbNRelevantLines, nChannels, AdjThrStateElement->peOffset);
diff --git a/media/libstagefright/codecs/aacenc/src/bitbuffer.c b/media/libstagefright/codecs/aacenc/src/bitbuffer.c
index 5615ac3cd65c..a706893d54e9 100644
--- a/media/libstagefright/codecs/aacenc/src/bitbuffer.c
+++ b/media/libstagefright/codecs/aacenc/src/bitbuffer.c
@@ -138,7 +138,7 @@ Word16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf)
*
*****************************************************************************/
Word16 WriteBits(HANDLE_BIT_BUF hBitBuf,
- Word32 writeValue,
+ UWord32 writeValue,
Word16 noBitsToWrite)
{
Word16 wBitPos;
diff --git a/media/libstagefright/codecs/aacenc/src/dyn_bits.c b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
index 3d2efdc1ef32..77691884da2a 100644
--- a/media/libstagefright/codecs/aacenc/src/dyn_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
@@ -281,7 +281,7 @@ noiselessCounter(SECTION_DATA *sectionData,
const Word32 blockType)
{
Word32 grpNdx, i;
- Word16 *sideInfoTab = NULL;
+ const Word16 *sideInfoTab = NULL;
SECTION_INFO *sectionInfo;
/*
diff --git a/media/libstagefright/codecs/aacenc/src/interface.c b/media/libstagefright/codecs/aacenc/src/interface.c
index f2472d8c8680..d0ad4335c9c4 100644
--- a/media/libstagefright/codecs/aacenc/src/interface.c
+++ b/media/libstagefright/codecs/aacenc/src/interface.c
@@ -99,8 +99,8 @@ void BuildInterface(Word32 *groupedMdctSpectrum,
Word32 i;
Word32 accuSumMS=0;
Word32 accuSumLR=0;
- Word32 *pSumMS = sfbEnergySumMS.sfbShort;
- Word32 *pSumLR = sfbEnergySumLR.sfbShort;
+ const Word32 *pSumMS = sfbEnergySumMS.sfbShort;
+ const Word32 *pSumLR = sfbEnergySumLR.sfbShort;
for (i=TRANS_FAC; i; i--) {
accuSumLR = L_add(accuSumLR, *pSumLR); pSumLR++;
diff --git a/media/libstagefright/codecs/aacenc/src/psy_configuration.c b/media/libstagefright/codecs/aacenc/src/psy_configuration.c
index 02d92ab1c4b0..dd40f9b24fbb 100644
--- a/media/libstagefright/codecs/aacenc/src/psy_configuration.c
+++ b/media/libstagefright/codecs/aacenc/src/psy_configuration.c
@@ -139,7 +139,7 @@ static Word16 BarcLineValue(Word16 noOfLines, Word16 fftLine, Word32 samplingFre
*
*****************************************************************************/
static void initThrQuiet(Word16 numPb,
- Word16 *pbOffset,
+ const Word16 *pbOffset,
Word16 *pbBarcVal,
Word32 *pbThresholdQuiet) {
Word16 i;
@@ -250,7 +250,7 @@ static void initSpreading(Word16 numPb,
*
*****************************************************************************/
static void initBarcValues(Word16 numPb,
- Word16 *pbOffset,
+ const Word16 *pbOffset,
Word16 numLines,
Word32 samplingFrequency,
Word16 *pbBval)
diff --git a/media/libstagefright/codecs/aacenc/src/psy_main.c b/media/libstagefright/codecs/aacenc/src/psy_main.c
index 085acb8c8692..4e9218c81a39 100644
--- a/media/libstagefright/codecs/aacenc/src/psy_main.c
+++ b/media/libstagefright/codecs/aacenc/src/psy_main.c
@@ -658,7 +658,8 @@ static Word16 advancePsychShort(PSY_DATA* psyData,
Word32 normEnergyShift = (psyData->mdctScale + 1) << 1; /* in reference code, mdct spectrum must be multipied with 2, so +1 */
Word32 clipEnergy = hPsyConfShort->clipEnergy >> normEnergyShift;
Word32 wOffset = 0;
- Word32 *data0, *data1;
+ Word32 *data0;
+ const Word32 *data1;
for(w = 0; w < TRANS_FAC; w++) {
Word32 i, tdata;
diff --git a/media/libstagefright/codecs/aacenc/src/qc_main.c b/media/libstagefright/codecs/aacenc/src/qc_main.c
index df6d46e68940..48ff30087d43 100644
--- a/media/libstagefright/codecs/aacenc/src/qc_main.c
+++ b/media/libstagefright/codecs/aacenc/src/qc_main.c
@@ -163,7 +163,7 @@ void QCOutDelete(QC_OUT* hQC, VO_MEM_OPERATOR *pMemOP)
Word32 i;
if(hQC)
{
- if(hQC->qcChannel[0].quantSpec);
+ if(hQC->qcChannel[0].quantSpec)
mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);
if(hQC->qcChannel[0].maxValueInSfb)
diff --git a/media/libstagefright/codecs/aacenc/src/quantize.c b/media/libstagefright/codecs/aacenc/src/quantize.c
index 54add2f73f47..0d0f550402e6 100644
--- a/media/libstagefright/codecs/aacenc/src/quantize.c
+++ b/media/libstagefright/codecs/aacenc/src/quantize.c
@@ -110,7 +110,7 @@ static void quantizeLines(const Word16 gain,
Word32 m = gain&3;
Word32 g = (gain >> 2) + 4;
Word32 mdctSpeL;
- Word16 *pquat;
+ const Word16 *pquat;
/* gain&3 */
pquat = quantBorders[m];
@@ -333,7 +333,7 @@ Word32 calcSfbDist(const Word32 *spec,
Word32 m = gain&3;
Word32 g = (gain >> 2) + 4;
Word32 g2 = (g << 1) + 1;
- Word16 *pquat, *repquat;
+ const Word16 *pquat, *repquat;
/* gain&3 */
pquat = quantBorders[m];
diff --git a/media/libstagefright/codecs/aacenc/src/sf_estim.c b/media/libstagefright/codecs/aacenc/src/sf_estim.c
index fe401374c022..bc320ec67df7 100644
--- a/media/libstagefright/codecs/aacenc/src/sf_estim.c
+++ b/media/libstagefright/codecs/aacenc/src/sf_estim.c
@@ -400,7 +400,7 @@ static void assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
Word16 *minScfCalculated,
Flag restartOnSuccess)
{
- Word32 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
+ Word16 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
Word16 *scfLast, *scfNext;
Word32 sfbPeOld, sfbPeNew;
Word32 sfbDistNew;
diff --git a/media/libstagefright/codecs/aacenc/src/transform.c b/media/libstagefright/codecs/aacenc/src/transform.c
index a154a2f9b0b0..a02336f3f030 100644
--- a/media/libstagefright/codecs/aacenc/src/transform.c
+++ b/media/libstagefright/codecs/aacenc/src/transform.c
@@ -339,6 +339,12 @@ static void PostMDCT(int *buf0, int num, const int *csptr)
*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
}
}
+#else
+void Radix4First(int *buf, int num);
+void Radix8First(int *buf, int num);
+void Radix4FFT(int *buf, int num, int bgn, int *twidTab);
+void PreMDCT(int *buf0, int num, const int *csptr);
+void PostMDCT(int *buf0, int num, const int *csptr);
#endif
diff --git a/media/libstagefright/codecs/amrnb/common/include/az_lsp.h b/media/libstagefright/codecs/amrnb/common/include/az_lsp.h
index 3e15ba382a86..7c24ca944053 100644
--- a/media/libstagefright/codecs/amrnb/common/include/az_lsp.h
+++ b/media/libstagefright/codecs/amrnb/common/include/az_lsp.h
@@ -83,7 +83,7 @@ extern "C"
; EXTERNAL VARIABLES REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
- extern Word16 grid[];
+ extern const Word16 grid[];
/*----------------------------------------------------------------------------
; SIMPLE TYPEDEF'S
diff --git a/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h b/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
index 4fb2b11dde37..91ab3e4424af 100644
--- a/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
+++ b/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
@@ -85,7 +85,7 @@ extern "C"
; EXTERNAL VARIABLES REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
- extern Word16 inv_sqrt_tbl[];
+ extern const Word16 inv_sqrt_tbl[];
/*----------------------------------------------------------------------------
; SIMPLE TYPEDEF'S
----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/common/include/log2_norm.h b/media/libstagefright/codecs/amrnb/common/include/log2_norm.h
index b104a69e83ab..46b4e4d8b8b6 100644
--- a/media/libstagefright/codecs/amrnb/common/include/log2_norm.h
+++ b/media/libstagefright/codecs/amrnb/common/include/log2_norm.h
@@ -85,7 +85,7 @@ extern "C"
; EXTERNAL VARIABLES REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
- extern Word16 log2_tbl[];
+ extern const Word16 log2_tbl[];
/*----------------------------------------------------------------------------
; SIMPLE TYPEDEF'S
----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/common/include/pow2.h b/media/libstagefright/codecs/amrnb/common/include/pow2.h
index c96fbddb7cf3..9b944ebafca9 100644
--- a/media/libstagefright/codecs/amrnb/common/include/pow2.h
+++ b/media/libstagefright/codecs/amrnb/common/include/pow2.h
@@ -81,7 +81,7 @@ extern "C"
; EXTERNAL VARIABLES REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
- extern Word16 pow2_tbl[];
+ extern const Word16 pow2_tbl[];
/*----------------------------------------------------------------------------
; SIMPLE TYPEDEF'S
----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h b/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
index 86209bd47165..a6a2ee5fba92 100644
--- a/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
+++ b/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
@@ -82,7 +82,7 @@ extern "C"
; EXTERNAL VARIABLES REFERENCES
; Declare variables used in this module but defined elsewhere
----------------------------------------------------------------------------*/
- extern Word16 sqrt_l_tbl[];
+ extern const Word16 sqrt_l_tbl[];
/*----------------------------------------------------------------------------
; SIMPLE TYPEDEF'S
diff --git a/media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp b/media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp
index bd99b30969af..4135f30ea73f 100644
--- a/media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/az_lsp.cpp
@@ -299,7 +299,7 @@ static Word16 Chebps(Word16 x,
t0 += (Word32) * (p_f) << 13;
- if ((UWord32)(t0 - 0xfe000000L) < 0x01ffffffL - 0xfe000000L)
+ if ((UWord32)(t0 - 0xfe000000L) < (UWord32)0x03ffffffL)
{
cheb = (Word16)(t0 >> 10);
}
diff --git a/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
index fed684d56b53..4ee04a561dec 100644
--- a/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
@@ -152,7 +152,7 @@ extern "C"
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
/* number of parameters per modes (values must be <= MAX_PRM_SIZE!) */
- extern const Word16 prmno[N_MODES] =
+ const Word16 prmno[N_MODES] =
{
PRMNO_MR475,
PRMNO_MR515,
@@ -166,7 +166,7 @@ extern "C"
};
/* number of parameters to first subframe per modes */
- extern const Word16 prmnofsf[N_MODES - 1] =
+ const Word16 prmnofsf[N_MODES - 1] =
{
PRMNOFSF_MR475,
PRMNOFSF_MR515,
@@ -179,7 +179,7 @@ extern "C"
};
/* parameter sizes (# of bits), one table per mode */
- extern const Word16 bitno_MR475[PRMNO_MR475] =
+ const Word16 bitno_MR475[PRMNO_MR475] =
{
8, 8, 7, /* LSP VQ */
8, 7, 2, 8, /* first subframe */
@@ -188,7 +188,7 @@ extern "C"
4, 7, 2, /* fourth subframe */
};
- extern const Word16 bitno_MR515[PRMNO_MR515] =
+ const Word16 bitno_MR515[PRMNO_MR515] =
{
8, 8, 7, /* LSP VQ */
8, 7, 2, 6, /* first subframe */
@@ -197,7 +197,7 @@ extern "C"
4, 7, 2, 6, /* fourth subframe */
};
- extern const Word16 bitno_MR59[PRMNO_MR59] =
+ const Word16 bitno_MR59[PRMNO_MR59] =
{
8, 9, 9, /* LSP VQ */
8, 9, 2, 6, /* first subframe */
@@ -206,7 +206,7 @@ extern "C"
4, 9, 2, 6, /* fourth subframe */
};
- extern const Word16 bitno_MR67[PRMNO_MR67] =
+ const Word16 bitno_MR67[PRMNO_MR67] =
{
8, 9, 9, /* LSP VQ */
8, 11, 3, 7, /* first subframe */
@@ -215,7 +215,7 @@ extern "C"
4, 11, 3, 7, /* fourth subframe */
};
- extern const Word16 bitno_MR74[PRMNO_MR74] =
+ const Word16 bitno_MR74[PRMNO_MR74] =
{
8, 9, 9, /* LSP VQ */
8, 13, 4, 7, /* first subframe */
@@ -224,7 +224,7 @@ extern "C"
5, 13, 4, 7, /* fourth subframe */
};
- extern const Word16 bitno_MR795[PRMNO_MR795] =
+ const Word16 bitno_MR795[PRMNO_MR795] =
{
9, 9, 9, /* LSP VQ */
8, 13, 4, 4, 5, /* first subframe */
@@ -233,7 +233,7 @@ extern "C"
6, 13, 4, 4, 5, /* fourth subframe */
};
- extern const Word16 bitno_MR102[PRMNO_MR102] =
+ const Word16 bitno_MR102[PRMNO_MR102] =
{
8, 9, 9, /* LSP VQ */
8, 1, 1, 1, 1, 10, 10, 7, 7, /* first subframe */
@@ -242,7 +242,7 @@ extern "C"
5, 1, 1, 1, 1, 10, 10, 7, 7, /* fourth subframe */
};
- extern const Word16 bitno_MR122[PRMNO_MR122] =
+ const Word16 bitno_MR122[PRMNO_MR122] =
{
7, 8, 9, 8, 6, /* LSP VQ */
9, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5, /* first subframe */
@@ -251,7 +251,7 @@ extern "C"
6, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5 /* fourth subframe */
};
- extern const Word16 bitno_MRDTX[PRMNO_MRDTX] =
+ const Word16 bitno_MRDTX[PRMNO_MRDTX] =
{
3,
8, 9, 9,
@@ -259,7 +259,7 @@ extern "C"
};
/* overall table with all parameter sizes for all modes */
- extern const Word16 * const bitno[N_MODES] =
+ const Word16 * const bitno[N_MODES] =
{
bitno_MR475,
bitno_MR515,
diff --git a/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
index 69b20fbe1a4a..e284bbcbc7f3 100644
--- a/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
@@ -123,6 +123,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "bitreorder_tab.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -171,7 +172,7 @@ extern "C"
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
/* number of parameters per modes (values must be <= MAX_PRM_SIZE!) */
- extern const Word16 numOfBits[NUM_MODES] =
+ const Word16 numOfBits[NUM_MODES] =
{
NUMBIT_MR475,
NUMBIT_MR515,
@@ -191,7 +192,7 @@ extern "C"
NUMBIT_NO_DATA
};
- extern const Word16 reorderBits_MR475[NUMBIT_MR475] =
+ const Word16 reorderBits_MR475[NUMBIT_MR475] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
@@ -205,7 +206,7 @@ extern "C"
92, 31, 52, 65, 86
};
- extern const Word16 reorderBits_MR515[NUMBIT_MR515] =
+ const Word16 reorderBits_MR515[NUMBIT_MR515] =
{
7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
13, 12, 11, 10, 9, 8, 23, 24, 25, 26,
@@ -220,7 +221,7 @@ extern "C"
53, 72, 91
};
- extern const Word16 reorderBits_MR59[NUMBIT_MR59] =
+ const Word16 reorderBits_MR59[NUMBIT_MR59] =
{
0, 1, 4, 5, 3, 6, 7, 2, 13, 15,
8, 9, 11, 12, 14, 10, 16, 28, 74, 29,
@@ -236,7 +237,7 @@ extern "C"
38, 59, 84, 105, 37, 58, 83, 104
};
- extern const Word16 reorderBits_MR67[NUMBIT_MR67] =
+ const Word16 reorderBits_MR67[NUMBIT_MR67] =
{
0, 1, 4, 3, 5, 6, 13, 7, 2, 8,
9, 11, 15, 12, 14, 10, 28, 82, 29, 83,
@@ -254,7 +255,7 @@ extern "C"
36, 61, 90, 115
};
- extern const Word16 reorderBits_MR74[NUMBIT_MR74] =
+ const Word16 reorderBits_MR74[NUMBIT_MR74] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 26, 87, 27,
@@ -273,7 +274,7 @@ extern "C"
39, 68, 100, 129, 40, 69, 101, 130
};
- extern const Word16 reorderBits_MR795[NUMBIT_MR795] =
+ const Word16 reorderBits_MR795[NUMBIT_MR795] =
{
8, 7, 6, 5, 4, 3, 2, 14, 16, 9,
10, 12, 13, 15, 11, 17, 20, 22, 24, 23,
@@ -293,7 +294,7 @@ extern "C"
139, 37, 69, 103, 135, 38, 70, 104, 136
};
- extern const Word16 reorderBits_MR102[NUMBIT_MR102] =
+ const Word16 reorderBits_MR102[NUMBIT_MR102] =
{
7, 6, 5, 4, 3, 2, 1, 0, 16, 15,
14, 13, 12, 11, 10, 9, 8, 26, 27, 28,
@@ -318,7 +319,7 @@ extern "C"
63, 46, 55, 56
};
- extern const Word16 reorderBits_MR122[NUMBIT_MR122] =
+ const Word16 reorderBits_MR122[NUMBIT_MR122] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
@@ -348,7 +349,7 @@ extern "C"
};
/* overall table with all parameter sizes for all modes */
- extern const Word16 * const reorderBits[NUM_MODES-1] =
+ const Word16 * const reorderBits[NUM_MODES-1] =
{
reorderBits_MR475,
reorderBits_MR515,
@@ -361,7 +362,7 @@ extern "C"
};
/* Number of Frames (16-bit segments sent for each mode */
- extern const Word16 numCompressedBytes[16] =
+ const Word16 numCompressedBytes[16] =
{
13, /*4.75*/
14, /*5.15*/
diff --git a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp b/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
index 9552206eb9eb..b61bac4d9fc7 100644
--- a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
@@ -152,7 +152,7 @@ extern "C"
; LOCAL STORE/BUFFER/POINTER DEFINITIONS
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
- extern const short BytesUsed[16] =
+ const short BytesUsed[16] =
{
13, /* 4.75 */
14, /* 5.15 */
diff --git a/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
index 471bee86eb11..20de9d63ff97 100644
--- a/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
@@ -86,7 +86,8 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 startPos[2*4*2] = {0, 2, 0, 3,
+ extern const Word16 startPos[];
+ const Word16 startPos[2*4*2] = {0, 2, 0, 3,
0, 2, 0, 3,
1, 3, 2, 4,
1, 4, 1, 4
diff --git a/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
index a08dd2dce2aa..a7cd6fbea66f 100644
--- a/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
@@ -86,14 +86,16 @@ extern "C"
----------------------------------------------------------------------------*/
- extern const Word16 qua_gain_pitch[NB_QUA_PITCH] =
+ extern const Word16 qua_gain_pitch[];
+ const Word16 qua_gain_pitch[NB_QUA_PITCH] =
{
0, 3277, 6556, 8192, 9830, 11469, 12288, 13107,
13926, 14746, 15565, 16384, 17203, 18022, 18842, 19661
};
- extern const Word16 qua_gain_code[(NB_QUA_CODE+1)*3] =
+ extern const Word16 qua_gain_code[];
+ const Word16 qua_gain_code[(NB_QUA_CODE+1)*3] =
{
/* gain factor (g_fac) and quantized energy error (qua_ener_MR122, qua_ener)
* are stored:
diff --git a/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
index 99073d91a9ef..c4b2dbc138ab 100644
--- a/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
@@ -83,8 +83,10 @@ extern "C"
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 gray[8] = {0, 1, 3, 2, 6, 4, 5, 7};
- extern const Word16 dgray[8] = {0, 1, 3, 2, 5, 6, 4, 7};
+ extern const Word16 gray[];
+ extern const Word16 dgray[];
+ const Word16 gray[8] = {0, 1, 3, 2, 6, 4, 5, 7};
+ const Word16 dgray[8] = {0, 1, 3, 2, 5, 6, 4, 7};
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
diff --git a/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
index cd81566accd2..48566cca56c2 100644
--- a/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
@@ -63,6 +63,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "az_lsp.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -91,7 +92,7 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 grid[grid_points + 1] =
+ const Word16 grid[grid_points + 1] =
{
32760, 32723, 32588, 32364, 32051, 31651,
31164, 30591, 29935, 29196, 28377, 27481,
diff --git a/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
index bde2c4e2c3cf..13c3b24053b4 100644
--- a/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
@@ -55,6 +55,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "inv_sqrt.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -82,7 +83,7 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 inv_sqrt_tbl[49] =
+ const Word16 inv_sqrt_tbl[49] =
{
32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
diff --git a/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
index 25d63b27216a..9b9b099efc10 100644
--- a/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
@@ -54,6 +54,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "log2_norm.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -82,7 +83,7 @@ extern "C"
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 log2_tbl[33] =
+ const Word16 log2_tbl[33] =
{
0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716,
12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033,
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
index cee0f32c47b7..ddeeba4282a5 100644
--- a/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
@@ -77,7 +77,8 @@ extern "C"
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 table[65] =
+ extern const Word16 table[];
+ const Word16 table[65] =
{
32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
@@ -94,7 +95,8 @@ extern "C"
/* slope used to compute y = acos(x) */
- extern const Word16 slope[64] =
+ extern const Word16 slope[];
+ const Word16 slope[64] =
{
-26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811,
-1608, -1450, -1322, -1219, -1132, -1059, -998, -946,
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
index deded935bf4a..0a32dd7a092a 100644
--- a/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
@@ -117,6 +117,7 @@ terms listed above has been obtained from the copyright holder.
----------------------------------------------------------------------------*/
#include "typedef.h"
#include "cnst.h"
+#include "lsp_tab.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -146,7 +147,7 @@ extern "C"
; LOCAL STORE/BUFFER/POINTER DEFINITIONS
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
- extern const Word16 lsp_init_data[M] = {30000, 26000, 21000, 15000, 8000,
+ const Word16 lsp_init_data[M] = {30000, 26000, 21000, 15000, 8000,
0, -8000, -15000, -21000, -26000
};
diff --git a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
index e5d42d6c8f8e..c4a016d557b9 100644
--- a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
@@ -81,7 +81,7 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word32 overflow_tbl [32] = {0x7fffffffL, 0x3fffffffL,
+ const Word32 overflow_tbl [32] = {0x7fffffffL, 0x3fffffffL,
0x1fffffffL, 0x0fffffffL,
0x07ffffffL, 0x03ffffffL,
0x01ffffffL, 0x00ffffffL,
diff --git a/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
index 99725dfdaa21..d568b780a0f0 100644
--- a/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
@@ -81,14 +81,16 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 ph_imp_low_MR795[40] =
+ extern const Word16 ph_imp_low_MR795[];
+ const Word16 ph_imp_low_MR795[40] =
{
26777, 801, 2505, -683, -1382, 582, 604, -1274, 3511, -5894,
4534, -499, -1940, 3011, -5058, 5614, -1990, -1061, -1459, 4442,
-700, -5335, 4609, 452, -589, -3352, 2953, 1267, -1212, -2590,
1731, 3670, -4475, -975, 4391, -2537, 949, -1363, -979, 5734
};
- extern const Word16 ph_imp_mid_MR795[40] =
+ extern const Word16 ph_imp_mid_MR795[];
+ const Word16 ph_imp_mid_MR795[40] =
{
30274, 3831, -4036, 2972, -1048, -1002, 2477, -3043, 2815, -2231,
1753, -1611, 1714, -1775, 1543, -1008, 429, -169, 472, -1264,
@@ -96,14 +98,16 @@ extern "C"
-2063, 2644, -3060, 2897, -1978, 557, 780, -1369, 842, 655
};
- extern const Word16 ph_imp_low[40] =
+ extern const Word16 ph_imp_low[];
+ const Word16 ph_imp_low[40] =
{
14690, 11518, 1268, -2761, -5671, 7514, -35, -2807, -3040, 4823,
2952, -8424, 3785, 1455, 2179, -8637, 8051, -2103, -1454, 777,
1108, -2385, 2254, -363, -674, -2103, 6046, -5681, 1072, 3123,
-5058, 5312, -2329, -3728, 6924, -3889, 675, -1775, 29, 10145
};
- extern const Word16 ph_imp_mid[40] =
+ extern const Word16 ph_imp_mid[];
+ const Word16 ph_imp_mid[40] =
{
30274, 3831, -4036, 2972, -1048, -1002, 2477, -3043, 2815, -2231,
1753, -1611, 1714, -1775, 1543, -1008, 429, -169, 472, -1264,
diff --git a/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
index e0183a69451e..902ea0f5bbc5 100644
--- a/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
@@ -53,6 +53,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "pow2.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -81,7 +82,7 @@ extern "C"
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 pow2_tbl[33] =
+ const Word16 pow2_tbl[33] =
{
16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
index ceb1e1ee1e95..caa81cbf972f 100644
--- a/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
@@ -56,6 +56,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "q_plsf_5_tbl.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -94,7 +95,7 @@ extern "C"
----------------------------------------------------------------------------*/
/* LSF means ->normalize frequency domain */
- extern const Word16 mean_lsf_5[10] =
+ const Word16 mean_lsf_5[10] =
{
1384,
2077,
@@ -108,7 +109,7 @@ extern "C"
13701
};
- extern const Word16 dico1_lsf_5[DICO1_5_SIZE * 4] =
+ const Word16 dico1_lsf_5[DICO1_5_SIZE * 4] =
{
-451, -1065, -529, -1305,
-450, -756, -497, -863,
@@ -240,7 +241,7 @@ extern "C"
1469, 2181, 1443, 2016
};
- extern const Word16 dico2_lsf_5[DICO2_5_SIZE * 4] =
+ const Word16 dico2_lsf_5[DICO2_5_SIZE * 4] =
{
-1631, -1600, -1796, -2290,
-1027, -1770, -1100, -2025,
@@ -500,7 +501,7 @@ extern "C"
2374, 2787, 1821, 2788
};
- extern const Word16 dico3_lsf_5[DICO3_5_SIZE * 4] =
+ const Word16 dico3_lsf_5[DICO3_5_SIZE * 4] =
{
-1812, -2275, -1879, -2537,
-1640, -1848, -1695, -2004,
@@ -760,7 +761,7 @@ extern "C"
2180, 1975, 2326, 2020
};
- extern const Word16 dico4_lsf_5[DICO4_5_SIZE * 4] =
+ const Word16 dico4_lsf_5[DICO4_5_SIZE * 4] =
{
-1857, -1681, -1857, -1755,
-2056, -1150, -2134, -1654,
@@ -1020,7 +1021,7 @@ extern "C"
1716, 1376, 1948, 1465
};
- extern const Word16 dico5_lsf_5[DICO5_5_SIZE * 4] =
+ const Word16 dico5_lsf_5[DICO5_5_SIZE * 4] =
{
-1002, -929, -1096, -1203,
-641, -931, -604, -961,
diff --git a/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
index 52f77e97786a..2d913b8063f9 100644
--- a/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
@@ -54,6 +54,7 @@ terms listed above has been obtained from the copyright holder.
----------------------------------------------------------------------------*/
#include "typedef.h"
#include "qua_gain.h"
+#include "qua_gain_tbl.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -96,7 +97,7 @@ extern "C"
/* table used in 'high' rates: MR67 MR74 */
- extern const Word16 table_gain_highrates[VQ_SIZE_HIGHRATES*4] =
+ const Word16 table_gain_highrates[VQ_SIZE_HIGHRATES*4] =
{
/*
@@ -240,7 +241,7 @@ extern "C"
/* table used in 'low' rates: MR475, MR515, MR59 */
- extern const Word16 table_gain_lowrates[VQ_SIZE_LOWRATES*4] =
+ const Word16 table_gain_lowrates[VQ_SIZE_LOWRATES*4] =
{
/*g_pit, g_fac, qua_ener_MR122, qua_ener */
10813, 28753, 2879, 17333,
diff --git a/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
index 5e9898c8f6c6..5a84b63e6c93 100644
--- a/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
@@ -58,6 +58,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "sqrt_l.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -85,7 +86,7 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 sqrt_l_tbl[50] =
+ const Word16 sqrt_l_tbl[50] =
{
16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480,
20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232,
diff --git a/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
index fa5faa6aa82d..d8fc8cce9ccf 100644
--- a/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
@@ -117,6 +117,7 @@ terms listed above has been obtained from the copyright holder.
----------------------------------------------------------------------------*/
#include "typedef.h"
#include "cnst.h"
+#include "window_tab.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -154,7 +155,7 @@ extern "C"
/* window for non-EFR modesm; uses 40 samples lookahead */
- extern const Word16 window_200_40[L_WINDOW] =
+ const Word16 window_200_40[L_WINDOW] =
{
2621, 2623, 2629, 2638, 2651, 2668, 2689, 2713, 2741, 2772,
2808, 2847, 2890, 2936, 2986, 3040, 3097, 3158, 3223, 3291,
@@ -185,7 +186,7 @@ extern "C"
/* window for EFR, first two subframes, no lookahead */
- extern const Word16 window_160_80[L_WINDOW] =
+ const Word16 window_160_80[L_WINDOW] =
{
2621, 2624, 2633, 2648, 2668, 2695, 2727, 2765, 2809, 2859,
2915, 2976, 3043, 3116, 3194, 3279, 3368, 3464, 3565, 3671,
@@ -215,7 +216,7 @@ extern "C"
/* window for EFR, last two subframes, no lookahead */
- extern const Word16 window_232_8[L_WINDOW] =
+ const Word16 window_232_8[L_WINDOW] =
{
2621, 2623, 2627, 2634, 2644, 2656, 2671, 2689, 2710, 2734,
2760, 2789, 2821, 2855, 2893, 2933, 2975, 3021, 3069, 3120,
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp b/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
index a59f5fafea58..fffbbfd82420 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
@@ -121,6 +121,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "amrdecode.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -152,7 +153,7 @@ extern "C"
----------------------------------------------------------------------------*/
/* Table containing the number of core AMR data bytes for */
/* each codec mode for WMF input format(number excludes frame type byte) */
- extern const Word16 WmfDecBytesPerFrame[16] =
+ const Word16 WmfDecBytesPerFrame[16] =
{
12, /* 4.75 */
13, /* 5.15 */
@@ -174,7 +175,7 @@ extern "C"
/* Table containing the number of core AMR data bytes for */
/* each codec mode for IF2 input format. */
- extern const Word16 If2DecBytesPerFrame[16] =
+ const Word16 If2DecBytesPerFrame[16] =
{
13, /* 4.75 */
14, /* 5.15 */
diff --git a/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp b/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
index fbcd41285e71..1a08efa3a600 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
@@ -92,7 +92,7 @@ extern "C"
* g_fac(2) (Q12) // frame 1 and 3
*
*/
- extern const Word16 table_gain_MR475[MR475_VQ_SIZE*4] =
+ const Word16 table_gain_MR475[MR475_VQ_SIZE*4] =
{
/*g_pit(0), g_fac(0), g_pit(1), g_fac(1) */
812, 128, 542, 140,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
index 769e7bafd252..b3ed02d213ac 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
@@ -57,6 +57,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "p_ol_wgh.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -84,7 +85,7 @@ extern "C"
; LOCAL VARIABLE DEFINITIONS
; [Variable declaration - defined here and used outside this module]
----------------------------------------------------------------------------*/
- extern const Word16 corrweight[251] =
+ const Word16 corrweight[251] =
{
20473, 20506, 20539, 20572, 20605, 20644, 20677,
20716, 20749, 20788, 20821, 20860, 20893, 20932,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
index 147989f865b7..4551fd7febf8 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
@@ -117,6 +117,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "amrencode.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -150,7 +151,7 @@ extern "C"
/* for WMF output format. */
/* Each entry is the sum of the 3GPP frame type byte and the */
/* number of packed core AMR data bytes */
- extern const Word16 WmfEncBytesPerFrame[16] =
+ const Word16 WmfEncBytesPerFrame[16] =
{
13, /* 4.75 */
14, /* 5.15 */
@@ -173,7 +174,7 @@ extern "C"
/* Number of data bytes in an encoder frame for each codec mode */
/* for IF2 output format */
- extern const Word16 If2EncBytesPerFrame[16] =
+ const Word16 If2EncBytesPerFrame[16] =
{
13, /* 4.75 */
14, /* 5.15 */
diff --git a/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
index 27f33e9959da..c8d7b1393297 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
@@ -123,6 +123,7 @@ terms listed above has been obtained from the copyright holder.
----------------------------------------------------------------------------*/
#include "typedef.h"
#include "cnst.h"
+#include "inter_36_tab.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -162,7 +163,7 @@ extern "C"
inter_3[k] = inter_6[2*k], 0 <= k <= 3*L_INTER_SRCH
*/
- extern const Word16 inter_6[FIR_SIZE] =
+ const Word16 inter_6[FIR_SIZE] =
{
29519,
28316, 24906, 19838, 13896, 7945, 2755,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
index 53889bb4860f..b0f5b3a142ba 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
@@ -138,6 +138,7 @@ terms listed above has been obtained from the copyright holder.
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
+#include "lag_wind_tab.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -167,7 +168,7 @@ extern "C"
; LOCAL STORE/BUFFER/POINTER DEFINITIONS
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
- extern const Word16 lag_h[10] =
+ const Word16 lag_h[10] =
{
32728,
32619,
@@ -181,7 +182,7 @@ extern "C"
29321
};
- extern const Word16 lag_l[10] =
+ const Word16 lag_l[10] =
{
11904,
17280,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp b/media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp
index dedf91acd7e7..d626de37e5a4 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/set_sign.cpp
@@ -552,10 +552,10 @@ void set_sign12k2(
else
{
*(p_sign--) = -32767; /* sign = -1 */
- cor = - (cor);
+ cor = negate(cor);
/* modify dn[] according to the fixed sign */
- dn[i] = - val;
+ dn[i] = negate(val);
}
*(p_en--) = cor;
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp b/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
index 3c4494d009ae..455a51028a2c 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
@@ -791,7 +791,8 @@ void update_gp_clipping(tonStabState *st, /* i/o : State struct */
)
{
OSCL_UNUSED_ARG(pOverflow);
- for (int i = 0; i < N_FRAME - 1; i++)
+ int i;
+ for (i = 0; i < N_FRAME - 1; i++)
{
st->gp[i] = st->gp[i+1];
}
diff --git a/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h b/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
index 457c21f963ee..eca5ae007725 100644
--- a/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
+++ b/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
@@ -106,7 +106,7 @@ extern "C"
#define NUM_OF_MODES 10
- const int16 AMR_WB_COMPRESSED[NUM_OF_MODES] =
+ static const int16 AMR_WB_COMPRESSED[NUM_OF_MODES] =
{
NBBITS_7k,
NBBITS_9k,
diff --git a/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp b/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
index d7287f3153ce..b325e8fc1f64 100644
--- a/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
+++ b/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
@@ -119,8 +119,9 @@ int16 Serial_parm( /* Return the parameter */
)
{
int16 value = 0;
+ int16 i;
- for (int16 i = no_of_bits >> 1; i != 0; i--)
+ for (i = no_of_bits >> 1; i != 0; i--)
{
value <<= 2;
diff --git a/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp b/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
index 59c6c0abbf33..f032a085e52b 100644
--- a/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
+++ b/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
@@ -134,7 +134,7 @@ extern "C"
; LOCAL STORE/BUFFER/POINTER DEFINITIONS
; Variable declaration - defined here and used outside this module
----------------------------------------------------------------------------*/
-const int16 prmnofsf[NUM_OF_SPMODES] =
+static const int16 prmnofsf[NUM_OF_SPMODES] =
{
63, 81, 100,
108, 116, 128,
@@ -142,21 +142,21 @@ const int16 prmnofsf[NUM_OF_SPMODES] =
};
-const int16 dfh_M7k[PRMN_7k] =
+static const int16 dfh_M7k[PRMN_7k] =
{
3168, 29954, 29213, 16121,
64, 13440, 30624, 16430,
19008
};
-const int16 dfh_M9k[PRMN_9k] =
+static const int16 dfh_M9k[PRMN_9k] =
{
3168, 31665, 9943, 9123,
15599, 4358, 20248, 2048,
17040, 27787, 16816, 13888
};
-const int16 dfh_M12k[PRMN_12k] =
+static const int16 dfh_M12k[PRMN_12k] =
{
3168, 31665, 9943, 9128,
3647, 8129, 30930, 27926,
@@ -165,7 +165,7 @@ const int16 dfh_M12k[PRMN_12k] =
13948
};
-const int16 dfh_M14k[PRMN_14k] =
+static const int16 dfh_M14k[PRMN_14k] =
{
3168, 31665, 9943, 9131,
24815, 655, 26616, 26764,
@@ -174,7 +174,7 @@ const int16 dfh_M14k[PRMN_14k] =
221, 20321, 17823
};
-const int16 dfh_M16k[PRMN_16k] =
+static const int16 dfh_M16k[PRMN_16k] =
{
3168, 31665, 9943, 9131,
24815, 700, 3824, 7271,
@@ -184,7 +184,7 @@ const int16 dfh_M16k[PRMN_16k] =
6759, 24576
};
-const int16 dfh_M18k[PRMN_18k] =
+static const int16 dfh_M18k[PRMN_18k] =
{
3168, 31665, 9943, 9135,
14787, 14423, 30477, 24927,
@@ -195,7 +195,7 @@ const int16 dfh_M18k[PRMN_18k] =
0
};
-const int16 dfh_M20k[PRMN_20k] =
+static const int16 dfh_M20k[PRMN_20k] =
{
3168, 31665, 9943, 9129,
8637, 31807, 24646, 736,
@@ -206,7 +206,7 @@ const int16 dfh_M20k[PRMN_20k] =
30249, 29123, 0
};
-const int16 dfh_M23k[PRMN_23k] =
+static const int16 dfh_M23k[PRMN_23k] =
{
3168, 31665, 9943, 9132,
16748, 3202, 28179, 16317,
@@ -218,7 +218,7 @@ const int16 dfh_M23k[PRMN_23k] =
23392, 26053, 31216
};
-const int16 dfh_M24k[PRMN_24k] =
+static const int16 dfh_M24k[PRMN_24k] =
{
3168, 31665, 9943, 9134,
24776, 5857, 18475, 28535,
diff --git a/media/libstagefright/codecs/amrwb/src/isp_isf.cpp b/media/libstagefright/codecs/amrwb/src/isp_isf.cpp
index 41db7e34c5c2..05527334d7e5 100644
--- a/media/libstagefright/codecs/amrwb/src/isp_isf.cpp
+++ b/media/libstagefright/codecs/amrwb/src/isp_isf.cpp
@@ -108,7 +108,7 @@ terms listed above has been obtained from the copyright holder.
/* table of cos(x) in Q15 */
-const int16 table[129] =
+static const int16 table[129] =
{
32767,
32758, 32729, 32679, 32610, 32522, 32413, 32286, 32138,
diff --git a/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp b/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
index 143c26e74bb7..806851ea42e8 100644
--- a/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
+++ b/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
@@ -240,11 +240,11 @@ void AmrWbUp_samp(
{
int32 i;
- int16 frac;
+ int16 frac, j;
int16 * pt_sig_u = sig_u;
frac = 1;
- for (int16 j = 0; j < L_frame; j++)
+ for (j = 0; j < L_frame; j++)
{
i = ((int32)j * INV_FAC5) >> 13; /* integer part = pos * 1/5 */
@@ -337,6 +337,6 @@ int16 AmrWbInterpol( /* return result of interpolation */
L_sum = shl_int32(L_sum, 2); /* saturation can occur here */
- return ((int16(L_sum >> 16)));
+ return ((int16)(L_sum >> 16));
}
diff --git a/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp b/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
index f90a534070f2..7b08a4060e35 100644
--- a/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
+++ b/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
@@ -109,7 +109,7 @@ terms listed above has been obtained from the copyright holder.
/* impulse response with phase dispersion */
/* 2.0 - 6.4 kHz phase dispersion */
-const int16 ph_imp_low[L_SUBFR] =
+static const int16 ph_imp_low[L_SUBFR] =
{
20182, 9693, 3270, -3437, 2864, -5240, 1589, -1357,
600, 3893, -1497, -698, 1203, -5249, 1199, 5371,
@@ -122,7 +122,7 @@ const int16 ph_imp_low[L_SUBFR] =
};
/* 3.2 - 6.4 kHz phase dispersion */
-const int16 ph_imp_mid[L_SUBFR] =
+static const int16 ph_imp_mid[L_SUBFR] =
{
24098, 10460, -5263, -763, 2048, -927, 1753, -3323,
2212, 652, -2146, 2487, -3539, 4109, -2107, -374,
diff --git a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab b/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
index 97c3b684e664..865eea0ac570 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
+++ b/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
@@ -21,7 +21,7 @@
/* table of cos(x) in Q15 */
-const static Word16 table[129] = {
+static const Word16 table[129] = {
32767,
32758, 32729, 32679, 32610, 32522, 32413, 32286, 32138,
31972, 31786, 31581, 31357, 31114, 30853, 30572, 30274,
@@ -42,7 +42,7 @@ const static Word16 table[129] = {
/* slope in Q11 used to compute y = acos(x) */
-const static Word16 slope[128] = {
+static const Word16 slope[128] = {
-26214, -9039, -5243, -3799, -2979, -2405, -2064, -1771,
-1579, -1409, -1279, -1170, -1079, -1004, -933, -880,
-827, -783, -743, -708, -676, -647, -621, -599,
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index 0f4d689aaa79..ea9da5238710 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -1702,7 +1702,7 @@ VO_U32 VO_API voAMRWB_SetInputData(
gData = (Coder_State *)hCodec;
stream = gData->stream;
- if(NULL == pInput || NULL == pInput->Buffer || 0 > pInput->Length)
+ if(NULL == pInput || NULL == pInput->Buffer)
{
return VO_ERR_INVALID_ARG;
}
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index e892f921fca3..059d6b9866be 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -19,12 +19,9 @@
#include "../include/SoftwareRenderer.h"
-#include <binder/MemoryHeapBase.h>
-#include <binder/MemoryHeapPmem.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MetaData.h>
-#include <surfaceflinger/Surface.h>
-#include <ui/android_native_buffer.h>
+#include <system/window.h>
#include <ui/GraphicBufferMapper.h>
#include <gui/ISurfaceTexture.h>
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 0a6776ef5130..9a001865e50b 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -19,6 +19,7 @@
#include <ctype.h>
#include "AAtomizer.h"
+#include "ABuffer.h"
#include "ADebug.h"
#include "ALooperRoster.h"
#include "AString.h"
@@ -157,14 +158,23 @@ void AMessage::setString(
item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);
}
-void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
+void AMessage::setObjectInternal(
+ const char *name, const sp<RefBase> &obj, Type type) {
Item *item = allocateItem(name);
- item->mType = kTypeObject;
+ item->mType = type;
if (obj != NULL) { obj->incStrong(this); }
item->u.refValue = obj.get();
}
+void AMessage::setObject(const char *name, const sp<RefBase> &obj) {
+ setObjectInternal(name, obj, kTypeObject);
+}
+
+void AMessage::setBuffer(const char *name, const sp<ABuffer> &buffer) {
+ setObjectInternal(name, sp<RefBase>(buffer), kTypeBuffer);
+}
+
void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
Item *item = allocateItem(name);
item->mType = kTypeMessage;
@@ -203,6 +213,15 @@ bool AMessage::findObject(const char *name, sp<RefBase> *obj) const {
return false;
}
+bool AMessage::findBuffer(const char *name, sp<ABuffer> *buf) const {
+ const Item *item = findItem(name, kTypeBuffer);
+ if (item) {
+ *buf = (ABuffer *)(item->u.refValue);
+ return true;
+ }
+ return false;
+}
+
bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
const Item *item = findItem(name, kTypeMessage);
if (item) {
@@ -542,4 +561,20 @@ void AMessage::writeToParcel(Parcel *parcel) const {
}
}
+size_t AMessage::countEntries() const {
+ return mNumItems;
+}
+
+const char *AMessage::getEntryNameAt(size_t index, Type *type) const {
+ if (index >= mNumItems) {
+ *type = kTypeInt32;
+
+ return NULL;
+ }
+
+ *type = mItems[index].mType;
+
+ return mItems[index].mName;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h
index 8f2ea9503f21..7ab004239069 100644
--- a/media/libstagefright/include/SoftwareRenderer.h
+++ b/media/libstagefright/include/SoftwareRenderer.h
@@ -20,7 +20,7 @@
#include <media/stagefright/ColorConverter.h>
#include <utils/RefBase.h>
-#include <ui/android_native_buffer.h>
+#include <system/window.h>
namespace android {
diff --git a/media/libstagefright/rtsp/AAMRAssembler.cpp b/media/libstagefright/rtsp/AAMRAssembler.cpp
index 9d72b1fd9a85..fb8abc580c17 100644
--- a/media/libstagefright/rtsp/AAMRAssembler.cpp
+++ b/media/libstagefright/rtsp/AAMRAssembler.cpp
@@ -211,7 +211,7 @@ ARTPAssembler::AssemblyStatus AAMRAssembler::addPacket(
}
sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
+ msg->setBuffer("access-unit", accessUnit);
msg->post();
queue->erase(queue->begin());
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index ed8b1df2dda8..7ea132e54cf4 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -345,7 +345,7 @@ void AAVCAssembler::submitAccessUnit() {
mAccessUnitDamaged = false;
sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
+ msg->setBuffer("access-unit", accessUnit);
msg->post();
}
diff --git a/media/libstagefright/rtsp/AH263Assembler.cpp b/media/libstagefright/rtsp/AH263Assembler.cpp
index 498295c46e1b..ded70fa17439 100644
--- a/media/libstagefright/rtsp/AH263Assembler.cpp
+++ b/media/libstagefright/rtsp/AH263Assembler.cpp
@@ -166,7 +166,7 @@ void AH263Assembler::submitAccessUnit() {
mAccessUnitDamaged = false;
sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
+ msg->setBuffer("access-unit", accessUnit);
msg->post();
}
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index b0c7007c3737..24c2f30209ef 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -571,7 +571,7 @@ void AMPEG4AudioAssembler::submitAccessUnit() {
mAccessUnitDamaged = false;
sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
+ msg->setBuffer("access-unit", accessUnit);
msg->post();
}
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 2f2e2c26e395..687d72bbda56 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -368,7 +368,7 @@ void AMPEG4ElementaryAssembler::submitAccessUnit() {
mAccessUnitDamaged = false;
sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", accessUnit);
+ msg->setBuffer("access-unit", accessUnit);
msg->post();
}
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 8c9dd8d3d5ce..44988a34733f 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -639,7 +639,7 @@ sp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
void ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) {
sp<AMessage> msg = new AMessage(kWhatInjectPacket, id());
msg->setInt32("index", index);
- msg->setObject("buffer", buffer);
+ msg->setBuffer("buffer", buffer);
msg->post();
}
@@ -647,10 +647,8 @@ void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
int32_t index;
CHECK(msg->findInt32("index", &index));
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
-
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
List<StreamInfo>::iterator it = mStreams.begin();
while (it != mStreams.end()
diff --git a/media/libstagefright/rtsp/ARTPSession.cpp b/media/libstagefright/rtsp/ARTPSession.cpp
index 7a05b888f630..ba4e33c813db 100644
--- a/media/libstagefright/rtsp/ARTPSession.cpp
+++ b/media/libstagefright/rtsp/ARTPSession.cpp
@@ -145,10 +145,8 @@ void ARTPSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- sp<RefBase> obj;
- CHECK(msg->findObject("access-unit", &obj));
-
- sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> accessUnit;
+ CHECK(msg->findBuffer("access-unit", &accessUnit));
uint64_t ntpTime;
CHECK(accessUnit->meta()->findInt64(
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 80a010e2f466..539a88823cab 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -612,7 +612,7 @@ bool ARTSPConnection::receiveRTSPReponse() {
if (mObserveBinaryMessage != NULL) {
sp<AMessage> notify = mObserveBinaryMessage->dup();
- notify->setObject("buffer", buffer);
+ notify->setBuffer("buffer", buffer);
notify->post();
} else {
ALOGW("received binary data, but no one cares.");
diff --git a/media/libstagefright/rtsp/ARawAudioAssembler.cpp b/media/libstagefright/rtsp/ARawAudioAssembler.cpp
index 98bee82e23a0..0da5dd250e9b 100644
--- a/media/libstagefright/rtsp/ARawAudioAssembler.cpp
+++ b/media/libstagefright/rtsp/ARawAudioAssembler.cpp
@@ -94,7 +94,7 @@ ARTPAssembler::AssemblyStatus ARawAudioAssembler::addPacket(
}
sp<AMessage> msg = mNotifyMsg->dup();
- msg->setObject("access-unit", buffer);
+ msg->setBuffer("access-unit", buffer);
msg->post();
queue->erase(queue->begin());
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 9a7dd704807a..deee30f14600 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -857,10 +857,8 @@ struct MyHandler : public AHandler {
return;
}
- sp<RefBase> obj;
- CHECK(msg->findObject("access-unit", &obj));
-
- sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> accessUnit;
+ CHECK(msg->findBuffer("access-unit", &accessUnit));
uint32_t seqNum = (uint32_t)accessUnit->int32Data();
@@ -1005,9 +1003,8 @@ struct MyHandler : public AHandler {
case 'biny':
{
- sp<RefBase> obj;
- CHECK(msg->findObject("buffer", &obj));
- sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+ sp<ABuffer> buffer;
+ CHECK(msg->findBuffer("buffer", &buffer));
int32_t index;
CHECK(buffer->meta()->findInt32("index", &index));
@@ -1488,7 +1485,7 @@ private:
sp<AMessage> msg = mNotify->dup();
msg->setInt32("what", kWhatAccessUnit);
msg->setSize("trackIndex", trackIndex);
- msg->setObject("accessUnit", accessUnit);
+ msg->setBuffer("accessUnit", accessUnit);
msg->post();
}
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index d7cec04e0c93..3dcd9fc1e08a 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -26,11 +26,11 @@
#include <media/stagefright/SurfaceMediaSource.h>
#include <media/mediarecorder.h>
-#include <gui/SurfaceTextureClient.h>
#include <ui/GraphicBuffer.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
#include <binder/ProcessState.h>
#include <ui/FramebufferNativeWindow.h>
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index 8b23dee0c0c7..dde206673e9a 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
TextDescriptions.cpp \
TimedTextDriver.cpp \
- TimedTextInBandSource.cpp \
+ TimedText3GPPSource.cpp \
TimedTextSource.cpp \
TimedTextSRTSource.cpp \
TimedTextPlayer.cpp
@@ -12,8 +12,7 @@ LOCAL_SRC_FILES:= \
LOCAL_CFLAGS += -Wno-multichar
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
- $(TOP)/frameworks/base/media/libstagefright \
- $(TOP)/frameworks/base/include/media/stagefright/openmax
+ $(TOP)/frameworks/base/media/libstagefright
LOCAL_MODULE:= libstagefright_timedtext
diff --git a/media/libstagefright/timedtext/TimedTextInBandSource.cpp b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
index afb73fb50313..4a3bfd323e74 100644
--- a/media/libstagefright/timedtext/TimedTextInBandSource.cpp
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.cpp
@@ -15,7 +15,7 @@
*/
//#define LOG_NDEBUG 0
-#define LOG_TAG "TimedTextInBandSource"
+#define LOG_TAG "TimedText3GPPSource"
#include <utils/Log.h>
#include <binder/Parcel.h>
@@ -26,19 +26,19 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
-#include "TimedTextInBandSource.h"
+#include "TimedText3GPPSource.h"
#include "TextDescriptions.h"
namespace android {
-TimedTextInBandSource::TimedTextInBandSource(const sp<MediaSource>& mediaSource)
+TimedText3GPPSource::TimedText3GPPSource(const sp<MediaSource>& mediaSource)
: mSource(mediaSource) {
}
-TimedTextInBandSource::~TimedTextInBandSource() {
+TimedText3GPPSource::~TimedText3GPPSource() {
}
-status_t TimedTextInBandSource::read(
+status_t TimedText3GPPSource::read(
int64_t *timeUs, Parcel *parcel, const MediaSource::ReadOptions *options) {
MediaBuffer *textBuffer = NULL;
status_t err = mSource->read(&textBuffer, options);
@@ -60,7 +60,7 @@ status_t TimedTextInBandSource::read(
// text style for the string of text. These descriptions are present only
// if they are needed. This method is used to extract the modifier
// description and append it at the end of the text.
-status_t TimedTextInBandSource::extractAndAppendLocalDescriptions(
+status_t TimedText3GPPSource::extractAndAppendLocalDescriptions(
int64_t timeUs, const MediaBuffer *textBuffer, Parcel *parcel) {
const void *data;
size_t size = 0;
@@ -68,51 +68,46 @@ status_t TimedTextInBandSource::extractAndAppendLocalDescriptions(
const char *mime;
CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+ CHECK(strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0);
- if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0) {
- data = textBuffer->data();
- size = textBuffer->size();
-
- if (size > 0) {
- parcel->freeData();
- flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
- return TextDescriptions::getParcelOfDescriptions(
- (const uint8_t *)data, size, flag, timeUs / 1000, parcel);
- }
- return OK;
+ data = textBuffer->data();
+ size = textBuffer->size();
+
+ if (size > 0) {
+ parcel->freeData();
+ flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
+ return TextDescriptions::getParcelOfDescriptions(
+ (const uint8_t *)data, size, flag, timeUs / 1000, parcel);
}
- return ERROR_UNSUPPORTED;
+ return OK;
}
// To extract and send the global text descriptions for all the text samples
// in the text track or text file.
// TODO: send error message to application via notifyListener()...?
-status_t TimedTextInBandSource::extractGlobalDescriptions(Parcel *parcel) {
+status_t TimedText3GPPSource::extractGlobalDescriptions(Parcel *parcel) {
const void *data;
size_t size = 0;
int32_t flag = TextDescriptions::GLOBAL_DESCRIPTIONS;
const char *mime;
CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+ CHECK(strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0);
+
+ uint32_t type;
+ // get the 'tx3g' box content. This box contains the text descriptions
+ // used to render the text track
+ if (!mSource->getFormat()->findData(
+ kKeyTextFormatData, &type, &data, &size)) {
+ return ERROR_MALFORMED;
+ }
- // support 3GPP only for now
- if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0) {
- uint32_t type;
- // get the 'tx3g' box content. This box contains the text descriptions
- // used to render the text track
- if (!mSource->getFormat()->findData(
- kKeyTextFormatData, &type, &data, &size)) {
- return ERROR_MALFORMED;
- }
-
- if (size > 0) {
- flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
- return TextDescriptions::getParcelOfDescriptions(
- (const uint8_t *)data, size, flag, 0, parcel);
- }
- return OK;
+ if (size > 0) {
+ flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
+ return TextDescriptions::getParcelOfDescriptions(
+ (const uint8_t *)data, size, flag, 0, parcel);
}
- return ERROR_UNSUPPORTED;
+ return OK;
}
} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextInBandSource.h b/media/libstagefright/timedtext/TimedText3GPPSource.h
index 26e5737f06ee..cb7e47c9def3 100644
--- a/media/libstagefright/timedtext/TimedTextInBandSource.h
+++ b/media/libstagefright/timedtext/TimedText3GPPSource.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef TIMED_TEXT_IN_BAND_SOURCE_H_
-#define TIMED_TEXT_IN_BAND_SOURCE_H_
+#ifndef TIMED_TEXT_3GPP_SOURCE_H_
+#define TIMED_TEXT_3GPP_SOURCE_H_
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
@@ -27,9 +27,9 @@ namespace android {
class MediaBuffer;
class Parcel;
-class TimedTextInBandSource : public TimedTextSource {
+class TimedText3GPPSource : public TimedTextSource {
public:
- TimedTextInBandSource(const sp<MediaSource>& mediaSource);
+ TimedText3GPPSource(const sp<MediaSource>& mediaSource);
virtual status_t start() { return mSource->start(); }
virtual status_t stop() { return mSource->stop(); }
virtual status_t read(
@@ -39,7 +39,7 @@ class TimedTextInBandSource : public TimedTextSource {
virtual status_t extractGlobalDescriptions(Parcel *parcel);
protected:
- virtual ~TimedTextInBandSource();
+ virtual ~TimedText3GPPSource();
private:
sp<MediaSource> mSource;
@@ -47,9 +47,9 @@ class TimedTextInBandSource : public TimedTextSource {
status_t extractAndAppendLocalDescriptions(
int64_t timeUs, const MediaBuffer *textBuffer, Parcel *parcel);
- DISALLOW_EVIL_CONSTRUCTORS(TimedTextInBandSource);
+ DISALLOW_EVIL_CONSTRUCTORS(TimedText3GPPSource);
};
} // namespace android
-#endif // TIMED_TEXT_IN_BAND_SOURCE_H_
+#endif // TIMED_TEXT_3GPP_SOURCE_H_
diff --git a/media/libstagefright/timedtext/TimedTextSource.cpp b/media/libstagefright/timedtext/TimedTextSource.cpp
index 9efe67c45af0..ffbe1c3bca41 100644
--- a/media/libstagefright/timedtext/TimedTextSource.cpp
+++ b/media/libstagefright/timedtext/TimedTextSource.cpp
@@ -18,12 +18,15 @@
#define LOG_TAG "TimedTextSource"
#include <utils/Log.h>
+#include <media/stagefright/foundation/ADebug.h> // CHECK_XX macro
#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx
#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
#include "TimedTextSource.h"
-#include "TimedTextInBandSource.h"
+#include "TimedText3GPPSource.h"
#include "TimedTextSRTSource.h"
namespace android {
@@ -31,7 +34,13 @@ namespace android {
// static
sp<TimedTextSource> TimedTextSource::CreateTimedTextSource(
const sp<MediaSource>& mediaSource) {
- return new TimedTextInBandSource(mediaSource);
+ const char *mime;
+ CHECK(mediaSource->getFormat()->findCString(kKeyMIMEType, &mime));
+ if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0) {
+ return new TimedText3GPPSource(mediaSource);
+ }
+ ALOGE("Unsupported mime type for subtitle. : %s", mime);
+ return NULL;
}
// static
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index 6b37a127182f..c58ee00a64d7 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -18,7 +18,7 @@
#include <utils/Log.h>
#include <android/native_window_jni.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index 6a006aabfac1..06d45cc22e18 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -19,8 +19,6 @@
#include "context.h"
#include "TextureObjectManager.h"
-#include <private/ui/android_natives_priv.h>
-
namespace android {
// ----------------------------------------------------------------------------
diff --git a/opengl/libagl/context.h b/opengl/libagl/context.h
index ef36b569d965..7065a30324ea 100644
--- a/opengl/libagl/context.h
+++ b/opengl/libagl/context.h
@@ -1,20 +1,642 @@
-/* libs/opengles/context.h
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <private/opengles/gl_context.h>
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_OPENGLES_CONTEXT_H
+#define ANDROID_OPENGLES_CONTEXT_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <pthread.h>
+#ifdef HAVE_ANDROID_OS
+#include <bionic_tls.h>
+#endif
+
+#include <private/pixelflinger/ggl_context.h>
+#include <hardware/gralloc.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+namespace android {
+
+
+const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
+#ifdef GL_OES_compressed_ETC1_RGB8_texture
+ + 1
+#endif
+ ;
+
+class EGLTextureObject;
+class EGLSurfaceManager;
+class EGLBufferObjectManager;
+
+namespace gl {
+
+struct ogles_context_t;
+struct matrixx_t;
+struct transform_t;
+struct buffer_t;
+
+ogles_context_t* getGlContext();
+
+template<typename T>
+static inline void swap(T& a, T& b) {
+ T t(a); a = b; b = t;
+}
+template<typename T>
+inline T max(T a, T b) {
+ return a<b ? b : a;
+}
+template<typename T>
+inline T max(T a, T b, T c) {
+ return max(a, max(b, c));
+}
+template<typename T>
+inline T min(T a, T b) {
+ return a<b ? a : b;
+}
+template<typename T>
+inline T min(T a, T b, T c) {
+ return min(a, min(b, c));
+}
+template<typename T>
+inline T min(T a, T b, T c, T d) {
+ return min(min(a,b), min(c,d));
+}
+
+// ----------------------------------------------------------------------------
+// vertices
+// ----------------------------------------------------------------------------
+
+struct vec3_t {
+ union {
+ struct { GLfixed x, y, z; };
+ struct { GLfixed r, g, b; };
+ struct { GLfixed S, T, R; };
+ GLfixed v[3];
+ };
+};
+
+struct vec4_t {
+ union {
+ struct { GLfixed x, y, z, w; };
+ struct { GLfixed r, g, b, a; };
+ struct { GLfixed S, T, R, Q; };
+ GLfixed v[4];
+ };
+};
+
+struct vertex_t {
+ enum {
+ // these constant matter for our clipping
+ CLIP_L = 0x0001, // clipping flags
+ CLIP_R = 0x0002,
+ CLIP_B = 0x0004,
+ CLIP_T = 0x0008,
+ CLIP_N = 0x0010,
+ CLIP_F = 0x0020,
+
+ EYE = 0x0040,
+ RESERVED = 0x0080,
+
+ USER_CLIP_0 = 0x0100, // user clipping flags
+ USER_CLIP_1 = 0x0200,
+ USER_CLIP_2 = 0x0400,
+ USER_CLIP_3 = 0x0800,
+ USER_CLIP_4 = 0x1000,
+ USER_CLIP_5 = 0x2000,
+
+ LIT = 0x4000, // lighting has been applied
+ TT = 0x8000, // texture coords transformed
+
+ FRUSTUM_CLIP_ALL= 0x003F,
+ USER_CLIP_ALL = 0x3F00,
+ CLIP_ALL = 0x3F3F,
+ };
+
+ // the fields below are arranged to minimize d-cache usage
+ // we group together, by cache-line, the fields most likely to be used
+
+ union {
+ vec4_t obj;
+ vec4_t eye;
+ };
+ vec4_t clip;
+
+ uint32_t flags;
+ size_t index; // cache tag, and vertex index
+ GLfixed fog;
+ uint8_t locked;
+ uint8_t mru;
+ uint8_t reserved[2];
+ vec4_t window;
+
+ vec4_t color;
+ vec4_t texture[GGL_TEXTURE_UNIT_COUNT];
+ uint32_t reserved1[4];
+
+ inline void clear() {
+ flags = index = locked = mru = 0;
+ }
+};
+
+struct point_size_t {
+ GGLcoord size;
+ GLboolean smooth;
+};
+
+struct line_width_t {
+ GGLcoord width;
+ GLboolean smooth;
+};
+
+struct polygon_offset_t {
+ GLfixed factor;
+ GLfixed units;
+ GLboolean enable;
+};
+
+// ----------------------------------------------------------------------------
+// arrays
+// ----------------------------------------------------------------------------
+
+struct array_t {
+ typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
+ fetcher_t fetch;
+ GLvoid const* physical_pointer;
+ GLint size;
+ GLsizei stride;
+ GLvoid const* pointer;
+ buffer_t const* bo;
+ uint16_t type;
+ GLboolean enable;
+ GLboolean pad;
+ GLsizei bounds;
+ void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
+ inline void resolve();
+ inline const GLubyte* element(GLint i) const {
+ return (const GLubyte*)physical_pointer + i * stride;
+ }
+};
+
+struct array_machine_t {
+ array_t vertex;
+ array_t normal;
+ array_t color;
+ array_t texture[GGL_TEXTURE_UNIT_COUNT];
+ uint8_t activeTexture;
+ uint8_t tmu;
+ uint16_t cull;
+ uint32_t flags;
+ GLenum indicesType;
+ buffer_t const* array_buffer;
+ buffer_t const* element_array_buffer;
+
+ void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
+ void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
+
+ void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
+ void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
+ void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
+ void (*perspective)(ogles_context_t*c, vertex_t* v);
+ void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
+ GGLfixed t, const vertex_t* s, const vertex_t* p);
+ void (*clipEye)(ogles_context_t* c, vertex_t* nv,
+ GGLfixed t, const vertex_t* s, const vertex_t* p);
+};
+
+struct vertex_cache_t {
+ enum {
+ // must be at least 4
+ // 3 vertice for triangles
+ // or 2 + 2 for indexed triangles w/ cache contention
+ VERTEX_BUFFER_SIZE = 8,
+ // must be a power of two and at least 3
+ VERTEX_CACHE_SIZE = 64, // 8 KB
+
+ INDEX_BITS = 16,
+ INDEX_MASK = ((1LU<<INDEX_BITS)-1),
+ INDEX_SEQ = 1LU<<INDEX_BITS,
+ };
+ vertex_t* vBuffer;
+ vertex_t* vCache;
+ uint32_t sequence;
+ void* base;
+ uint32_t total;
+ uint32_t misses;
+ int64_t startTime;
+ void init();
+ void uninit();
+ void clear();
+ void dump_stats(GLenum mode);
+};
+
+// ----------------------------------------------------------------------------
+// fog
+// ----------------------------------------------------------------------------
+
+struct fog_t {
+ GLfixed density;
+ GLfixed start;
+ GLfixed end;
+ GLfixed invEndMinusStart;
+ GLenum mode;
+ GLfixed (*fog)(ogles_context_t* c, GLfixed z);
+};
+
+// ----------------------------------------------------------------------------
+// user clip planes
+// ----------------------------------------------------------------------------
+
+const unsigned int OGLES_MAX_CLIP_PLANES = 6;
+
+struct clip_plane_t {
+ vec4_t equation;
+};
+
+struct user_clip_planes_t {
+ clip_plane_t plane[OGLES_MAX_CLIP_PLANES];
+ uint32_t enable;
+};
+
+// ----------------------------------------------------------------------------
+// lighting
+// ----------------------------------------------------------------------------
+
+const unsigned int OGLES_MAX_LIGHTS = 8;
+
+struct light_t {
+ vec4_t ambient;
+ vec4_t diffuse;
+ vec4_t specular;
+ vec4_t implicitAmbient;
+ vec4_t implicitDiffuse;
+ vec4_t implicitSpecular;
+ vec4_t position; // position in eye space
+ vec4_t objPosition;
+ vec4_t normalizedObjPosition;
+ vec4_t spotDir;
+ vec4_t normalizedSpotDir;
+ GLfixed spotExp;
+ GLfixed spotCutoff;
+ GLfixed spotCutoffCosine;
+ GLfixed attenuation[3];
+ GLfixed rConstAttenuation;
+ GLboolean enable;
+};
+
+struct material_t {
+ vec4_t ambient;
+ vec4_t diffuse;
+ vec4_t specular;
+ vec4_t emission;
+ GLfixed shininess;
+};
+
+struct light_model_t {
+ vec4_t ambient;
+ GLboolean twoSide;
+};
+
+struct color_material_t {
+ GLenum face;
+ GLenum mode;
+ GLboolean enable;
+};
+
+struct lighting_t {
+ light_t lights[OGLES_MAX_LIGHTS];
+ material_t front;
+ light_model_t lightModel;
+ color_material_t colorMaterial;
+ vec4_t implicitSceneEmissionAndAmbient;
+ vec4_t objViewer;
+ uint32_t enabledLights;
+ GLboolean enable;
+ GLenum shadeModel;
+ typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
+ void (*lightVertex)(ogles_context_t* c, vertex_t* v);
+ void (*lightTriangle)(ogles_context_t* c,
+ vertex_t* v0, vertex_t* v1, vertex_t* v2);
+};
+
+struct culling_t {
+ GLenum cullFace;
+ GLenum frontFace;
+ GLboolean enable;
+};
+
+// ----------------------------------------------------------------------------
+// textures
+// ----------------------------------------------------------------------------
+
+struct texture_unit_t {
+ GLuint name;
+ EGLTextureObject* texture;
+ uint8_t dirty;
+};
+
+struct texture_state_t
+{
+ texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT];
+ int active; // active tmu
+ EGLTextureObject* defaultTexture;
+ GGLContext* ggl;
+ uint8_t packAlignment;
+ uint8_t unpackAlignment;
+};
+
+// ----------------------------------------------------------------------------
+// transformation and matrices
+// ----------------------------------------------------------------------------
+
+struct matrixf_t;
+
+struct matrixx_t {
+ GLfixed m[16];
+ void load(const matrixf_t& rhs);
+};
+
+struct matrix_stack_t;
+
+
+struct matrixf_t {
+ void loadIdentity();
+ void load(const matrixf_t& rhs);
+
+ inline GLfloat* editElements() { return m; }
+ inline GLfloat const* elements() const { return m; }
+
+ void set(const GLfixed* rhs);
+ void set(const GLfloat* rhs);
+
+ static void multiply(matrixf_t& r,
+ const matrixf_t& lhs, const matrixf_t& rhs);
+
+ void dump(const char* what);
+
+private:
+ friend struct matrix_stack_t;
+ GLfloat m[16];
+ void load(const GLfixed* rhs);
+ void load(const GLfloat* rhs);
+ void multiply(const matrixf_t& rhs);
+ void translate(GLfloat x, GLfloat y, GLfloat z);
+ void scale(GLfloat x, GLfloat y, GLfloat z);
+ void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
+};
+
+enum {
+ OP_IDENTITY = 0x00,
+ OP_TRANSLATE = 0x01,
+ OP_UNIFORM_SCALE = 0x02,
+ OP_SCALE = 0x05,
+ OP_ROTATE = 0x08,
+ OP_SKEW = 0x10,
+ OP_ALL = 0x1F
+};
+
+struct transform_t {
+ enum {
+ FLAGS_2D_PROJECTION = 0x1
+ };
+ matrixx_t matrix;
+ uint32_t flags;
+ uint32_t ops;
+
+ union {
+ struct {
+ void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
+ void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
+ void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
+ };
+ void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
+ };
+
+ void loadIdentity();
+ void picker();
+ void dump(const char* what);
+};
+
+struct mvui_transform_t : public transform_t
+{
+ void picker();
+};
+
+struct matrix_stack_t {
+ enum {
+ DO_PICKER = 0x1,
+ DO_FLOAT_TO_FIXED = 0x2
+ };
+ transform_t transform;
+ uint8_t maxDepth;
+ uint8_t depth;
+ uint8_t dirty;
+ uint8_t reserved;
+ matrixf_t *stack;
+ uint8_t *ops;
+ void init(int depth);
+ void uninit();
+ void loadIdentity();
+ void load(const GLfixed* rhs);
+ void load(const GLfloat* rhs);
+ void multiply(const matrixf_t& rhs);
+ void translate(GLfloat x, GLfloat y, GLfloat z);
+ void scale(GLfloat x, GLfloat y, GLfloat z);
+ void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
+ GLint push();
+ GLint pop();
+ void validate();
+ matrixf_t& top() { return stack[depth]; }
+ const matrixf_t& top() const { return stack[depth]; }
+ uint32_t top_ops() const { return ops[depth]; }
+ inline bool isRigidBody() const {
+ return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
+ }
+};
+
+struct vp_transform_t {
+ transform_t transform;
+ matrixf_t matrix;
+ GLfloat zNear;
+ GLfloat zFar;
+ void loadIdentity();
+};
+
+struct transform_state_t {
+ enum {
+ MODELVIEW = 0x01,
+ PROJECTION = 0x02,
+ VIEWPORT = 0x04,
+ TEXTURE = 0x08,
+ MVUI = 0x10,
+ MVIT = 0x20,
+ MVP = 0x40,
+ };
+ matrix_stack_t *current;
+ matrix_stack_t modelview;
+ matrix_stack_t projection;
+ matrix_stack_t texture[GGL_TEXTURE_UNIT_COUNT];
+
+ // modelview * projection
+ transform_t mvp __attribute__((aligned(32)));
+ // viewport transformation
+ vp_transform_t vpt __attribute__((aligned(32)));
+ // same for 4-D vertices
+ transform_t mvp4;
+ // full modelview inverse transpose
+ transform_t mvit4;
+ // upper 3x3 of mv-inverse-transpose (for normals)
+ mvui_transform_t mvui;
+
+ GLenum matrixMode;
+ GLenum rescaleNormals;
+ uint32_t dirty;
+ void invalidate();
+ void update_mvp();
+ void update_mvit();
+ void update_mvui();
+};
+
+struct viewport_t {
+ GLint x;
+ GLint y;
+ GLsizei w;
+ GLsizei h;
+ struct {
+ GLint x;
+ GLint y;
+ } surfaceport;
+ struct {
+ GLint x;
+ GLint y;
+ GLsizei w;
+ GLsizei h;
+ } scissor;
+};
+
+// ----------------------------------------------------------------------------
+// Lerping
+// ----------------------------------------------------------------------------
+
+struct compute_iterators_t
+{
+ void initTriangle(
+ vertex_t const* v0,
+ vertex_t const* v1,
+ vertex_t const* v2);
+
+ void initLine(
+ vertex_t const* v0,
+ vertex_t const* v1);
+
+ inline void initLerp(vertex_t const* v0, uint32_t enables);
+
+ int iteratorsScale(int32_t it[3],
+ int32_t c0, int32_t c1, int32_t c2) const;
+
+ void iterators1616(GGLfixed it[3],
+ GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
+
+ void iterators0032(int32_t it[3],
+ int32_t c0, int32_t c1, int32_t c2) const;
+
+ void iterators0032(int64_t it[3],
+ int32_t c0, int32_t c1, int32_t c2) const;
+
+ GGLcoord area() const { return m_area; }
+
+private:
+ // don't change order of members here -- used by iterators.S
+ GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
+ GGLcoord m_x0, m_y0;
+ GGLcoord m_area;
+ uint8_t m_scale;
+ uint8_t m_area_scale;
+ uint8_t m_reserved[2];
+
+};
+
+// ----------------------------------------------------------------------------
+// state
+// ----------------------------------------------------------------------------
+
+#ifdef HAVE_ANDROID_OS
+ // We have a dedicated TLS slot in bionic
+ inline void setGlThreadSpecific(ogles_context_t *value) {
+ ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
+ }
+ inline ogles_context_t* getGlThreadSpecific() {
+ return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
+ }
+#else
+ extern pthread_key_t gGLKey;
+ inline void setGlThreadSpecific(ogles_context_t *value) {
+ pthread_setspecific(gGLKey, value);
+ }
+ inline ogles_context_t* getGlThreadSpecific() {
+ return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
+ }
+#endif
+
+
+struct prims_t {
+ typedef ogles_context_t* GL;
+ void (*renderPoint)(GL, vertex_t*);
+ void (*renderLine)(GL, vertex_t*, vertex_t*);
+ void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
+};
+
+struct ogles_context_t {
+ context_t rasterizer;
+ array_machine_t arrays __attribute__((aligned(32)));
+ texture_state_t textures;
+ transform_state_t transforms;
+ vertex_cache_t vc;
+ prims_t prims;
+ culling_t cull;
+ lighting_t lighting;
+ user_clip_planes_t clipPlanes;
+ compute_iterators_t lerp; __attribute__((aligned(32)));
+ vertex_t current;
+ vec4_t currentColorClamped;
+ vec3_t currentNormal;
+ viewport_t viewport;
+ point_size_t point;
+ line_width_t line;
+ polygon_offset_t polygonOffset;
+ fog_t fog;
+ uint32_t perspective : 1;
+ uint32_t transformTextures : 1;
+ EGLSurfaceManager* surfaceManager;
+ EGLBufferObjectManager* bufferObjectManager;
+
+ GLenum error;
+
+ static inline ogles_context_t* get() {
+ return getGlThreadSpecific();
+ }
+
+};
+
+}; // namespace gl
+}; // namespace android
using namespace android::gl;
+
+#endif // ANDROID_OPENGLES_CONTEXT_H
+
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index eb55beefd9af..92d32a282b2e 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -30,6 +30,7 @@
#include <cutils/atomic.h>
#include <utils/threads.h>
+#include <ui/ANativeObjectBase.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -39,8 +40,6 @@
#include <pixelflinger/format.h>
#include <pixelflinger/pixelflinger.h>
-#include <private/ui/android_natives_priv.h>
-
#include "context.h"
#include "state.h"
#include "texture.h"
@@ -49,13 +48,14 @@
#undef NELEM
#define NELEM(x) (sizeof(x)/sizeof(*(x)))
+// ----------------------------------------------------------------------------
EGLBoolean EGLAPI eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
EGLint left, EGLint top, EGLint width, EGLint height);
-
// ----------------------------------------------------------------------------
namespace android {
+
// ----------------------------------------------------------------------------
const unsigned int NUM_DISPLAYS = 1;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 88e865124ec7..08536dfd2589 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -23,7 +23,6 @@
#include "texture.h"
#include "TextureObjectManager.h"
-#include <private/ui/android_natives_priv.h>
#include <ETC1/etc1.h>
namespace android {
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index a5dc832bf6de..a1bd82dfff29 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -14,6 +14,8 @@
** limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@@ -34,6 +36,7 @@
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
+#include <utils/Trace.h>
#include "egl_impl.h"
#include "egl_tls.h"
@@ -348,6 +351,7 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
}
void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
+ ATRACE_CALL();
clearError();
egl_display_t const * const dp = validate_display(dpy);
@@ -712,6 +716,7 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
+ ATRACE_CALL();
clearError();
egl_display_t const * const dp = validate_display(dpy);
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.cpp b/opengl/libs/GLES_trace/src/gltrace_api.cpp
index 358bf54ce445..cef6cbb1657f 100644
--- a/opengl/libs/GLES_trace/src/gltrace_api.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_api.cpp
@@ -49,9 +49,12 @@ void GLTrace_glActiveTexture(GLenum texture) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -80,9 +83,12 @@ void GLTrace_glAttachShader(GLuint program, GLuint shader) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -117,9 +123,13 @@ void GLTrace_glBindAttribLocation(GLuint program, GLuint index, const GLchar* na
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) name,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -148,9 +158,12 @@ void GLTrace_glBindBuffer(GLenum target, GLuint buffer) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -179,9 +192,12 @@ void GLTrace_glBindFramebuffer(GLenum target, GLuint framebuffer) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -210,9 +226,12 @@ void GLTrace_glBindRenderbuffer(GLenum target, GLuint renderbuffer) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -241,9 +260,12 @@ void GLTrace_glBindTexture(GLenum target, GLuint texture) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -284,9 +306,12 @@ void GLTrace_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -309,9 +334,12 @@ void GLTrace_glBlendEquation(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -340,9 +368,12 @@ void GLTrace_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -371,9 +402,12 @@ void GLTrace_glBlendFunc(GLenum sfactor, GLenum dfactor) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -414,9 +448,12 @@ void GLTrace_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -436,7 +473,7 @@ void GLTrace_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GL
GLMessage_DataType *arg_size = glmsg.add_args();
arg_size->set_isarray(false);
arg_size->set_type(GLMessage::DataType::INT);
- arg_size->add_intvalue((int)size);
+ arg_size->add_intvalue(size);
// copy argument data
GLMessage_DataType *arg_data = glmsg.add_args();
@@ -457,9 +494,13 @@ void GLTrace_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -479,13 +520,13 @@ void GLTrace_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, co
GLMessage_DataType *arg_offset = glmsg.add_args();
arg_offset->set_isarray(false);
arg_offset->set_type(GLMessage::DataType::INT);
- arg_offset->add_intvalue((int)offset);
+ arg_offset->add_intvalue(offset);
// copy argument size
GLMessage_DataType *arg_size = glmsg.add_args();
arg_size->set_isarray(false);
arg_size->set_type(GLMessage::DataType::INT);
- arg_size->add_intvalue((int)size);
+ arg_size->add_intvalue(size);
// copy argument data
GLMessage_DataType *arg_data = glmsg.add_args();
@@ -500,9 +541,13 @@ void GLTrace_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, co
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -531,9 +576,12 @@ GLenum GLTrace_glCheckFramebufferStatus(GLenum target) {
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -558,9 +606,12 @@ void GLTrace_glClear(GLbitfield mask) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -601,9 +652,12 @@ void GLTrace_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -626,9 +680,12 @@ void GLTrace_glClearDepthf(GLclampf depth) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -651,9 +708,12 @@ void GLTrace_glClearStencil(GLint s) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -694,9 +754,12 @@ void GLTrace_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboole
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -719,9 +782,12 @@ void GLTrace_glCompileShader(GLuint shader) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -786,9 +852,13 @@ void GLTrace_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalf
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -859,9 +929,13 @@ void GLTrace_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -926,9 +1000,12 @@ void GLTrace_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -993,9 +1070,12 @@ void GLTrace_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLin
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1018,9 +1098,12 @@ GLuint GLTrace_glCreateProgram(void) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -1051,9 +1134,12 @@ GLuint GLTrace_glCreateShader(GLenum type) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -1078,9 +1164,12 @@ void GLTrace_glCullFace(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1109,9 +1198,13 @@ void GLTrace_glDeleteBuffers(GLsizei n, const GLuint* buffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) buffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1140,9 +1233,13 @@ void GLTrace_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) framebuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1165,9 +1262,12 @@ void GLTrace_glDeleteProgram(GLuint program) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1196,9 +1296,13 @@ void GLTrace_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) renderbuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1221,9 +1325,12 @@ void GLTrace_glDeleteShader(GLuint shader) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1252,9 +1359,13 @@ void GLTrace_glDeleteTextures(GLsizei n, const GLuint* textures) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) textures,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1277,9 +1388,12 @@ void GLTrace_glDepthFunc(GLenum func) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1302,9 +1416,12 @@ void GLTrace_glDepthMask(GLboolean flag) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1333,9 +1450,12 @@ void GLTrace_glDepthRangef(GLclampf zNear, GLclampf zFar) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1364,9 +1484,12 @@ void GLTrace_glDetachShader(GLuint program, GLuint shader) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1389,9 +1512,12 @@ void GLTrace_glDisable(GLenum cap) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1414,9 +1540,12 @@ void GLTrace_glDisableVertexAttribArray(GLuint index) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1451,9 +1580,12 @@ void GLTrace_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1494,9 +1626,13 @@ void GLTrace_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoi
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) indices,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1519,9 +1655,12 @@ void GLTrace_glEnable(GLenum cap) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1544,9 +1683,12 @@ void GLTrace_glEnableVertexAttribArray(GLuint index) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1563,9 +1705,12 @@ void GLTrace_glFinish(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1582,9 +1727,12 @@ void GLTrace_glFlush(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1625,9 +1773,12 @@ void GLTrace_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1674,9 +1825,12 @@ void GLTrace_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum tex
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1699,9 +1853,12 @@ void GLTrace_glFrontFace(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1730,9 +1887,13 @@ void GLTrace_glGenBuffers(GLsizei n, GLuint* buffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) buffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1755,9 +1916,12 @@ void GLTrace_glGenerateMipmap(GLenum target) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1786,9 +1950,13 @@ void GLTrace_glGenFramebuffers(GLsizei n, GLuint* framebuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) framebuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1817,9 +1985,13 @@ void GLTrace_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) renderbuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1848,9 +2020,13 @@ void GLTrace_glGenTextures(GLsizei n, GLuint* textures) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) textures,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1909,9 +2085,16 @@ void GLTrace_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) size,
+ (void *) type,
+ (void *) name,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -1970,9 +2153,16 @@ void GLTrace_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, G
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) size,
+ (void *) type,
+ (void *) name,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2013,9 +2203,14 @@ void GLTrace_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* cou
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) count,
+ (void *) shaders,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2050,9 +2245,13 @@ int GLTrace_glGetAttribLocation(GLuint program, const GLchar* name) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
+ void *pointerArgs[] = {
+ (void *) name,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2083,9 +2282,13 @@ void GLTrace_glGetBooleanv(GLenum pname, GLboolean* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2120,9 +2323,13 @@ void GLTrace_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2145,9 +2352,12 @@ GLenum GLTrace_glGetError(void) {
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2178,9 +2388,13 @@ void GLTrace_glGetFloatv(GLenum pname, GLfloat* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2221,9 +2435,13 @@ void GLTrace_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachm
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2252,9 +2470,13 @@ void GLTrace_glGetIntegerv(GLenum pname, GLint* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2289,9 +2511,13 @@ void GLTrace_glGetProgramiv(GLuint program, GLenum pname, GLint* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2332,9 +2558,14 @@ void GLTrace_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* lengt
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) infolog,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2369,9 +2600,13 @@ void GLTrace_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* pa
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2406,9 +2641,13 @@ void GLTrace_glGetShaderiv(GLuint shader, GLenum pname, GLint* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2449,9 +2688,14 @@ void GLTrace_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) infolog,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2492,9 +2736,14 @@ void GLTrace_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) range,
+ (void *) precision,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2535,9 +2784,14 @@ void GLTrace_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) source,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2566,9 +2820,13 @@ const GLubyte* GLTrace_glGetString(GLenum name) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue((int)retValue);
+ void *pointerArgs[] = {
+ (void *) retValue,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2605,9 +2863,13 @@ void GLTrace_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2642,9 +2904,13 @@ void GLTrace_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2679,9 +2945,13 @@ void GLTrace_glGetUniformfv(GLuint program, GLint location, GLfloat* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2716,9 +2986,13 @@ void GLTrace_glGetUniformiv(GLuint program, GLint location, GLint* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2753,9 +3027,13 @@ int GLTrace_glGetUniformLocation(GLuint program, const GLchar* name) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
+ void *pointerArgs[] = {
+ (void *) name,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2792,9 +3070,13 @@ void GLTrace_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2829,9 +3111,13 @@ void GLTrace_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2866,9 +3152,13 @@ void GLTrace_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** poin
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2897,9 +3187,12 @@ void GLTrace_glHint(GLenum target, GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -2928,9 +3221,12 @@ GLboolean GLTrace_glIsBuffer(GLuint buffer) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2961,9 +3257,12 @@ GLboolean GLTrace_glIsEnabled(GLenum cap) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2994,9 +3293,12 @@ GLboolean GLTrace_glIsFramebuffer(GLuint framebuffer) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -3027,9 +3329,12 @@ GLboolean GLTrace_glIsProgram(GLuint program) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -3060,9 +3365,12 @@ GLboolean GLTrace_glIsRenderbuffer(GLuint renderbuffer) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -3093,9 +3401,12 @@ GLboolean GLTrace_glIsShader(GLuint shader) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -3126,9 +3437,12 @@ GLboolean GLTrace_glIsTexture(GLuint texture) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -3153,9 +3467,12 @@ void GLTrace_glLineWidth(GLfloat width) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3178,9 +3495,12 @@ void GLTrace_glLinkProgram(GLuint program) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3209,9 +3529,12 @@ void GLTrace_glPixelStorei(GLenum pname, GLint param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3240,9 +3563,12 @@ void GLTrace_glPolygonOffset(GLfloat factor, GLfloat units) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3301,9 +3627,13 @@ void GLTrace_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenu
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pixels,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3320,9 +3650,12 @@ void GLTrace_glReleaseShaderCompiler(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3363,9 +3696,12 @@ void GLTrace_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3394,9 +3730,12 @@ void GLTrace_glSampleCoverage(GLclampf value, GLboolean invert) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3437,9 +3776,12 @@ void GLTrace_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3486,9 +3828,14 @@ void GLTrace_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryforma
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) shaders,
+ (void *) binary,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3529,9 +3876,14 @@ void GLTrace_glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) string,
+ (void *) length,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3566,9 +3918,12 @@ void GLTrace_glStencilFunc(GLenum func, GLint ref, GLuint mask) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3609,9 +3964,12 @@ void GLTrace_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint m
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3634,9 +3992,12 @@ void GLTrace_glStencilMask(GLuint mask) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3665,9 +4026,12 @@ void GLTrace_glStencilMaskSeparate(GLenum face, GLuint mask) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3702,9 +4066,12 @@ void GLTrace_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3745,9 +4112,12 @@ void GLTrace_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3818,9 +4188,13 @@ void GLTrace_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsi
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pixels,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3855,9 +4229,12 @@ void GLTrace_glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3892,9 +4269,13 @@ void GLTrace_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3929,9 +4310,12 @@ void GLTrace_glTexParameteri(GLenum target, GLenum pname, GLint param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -3966,9 +4350,13 @@ void GLTrace_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4039,9 +4427,13 @@ void GLTrace_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yo
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pixels,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4070,9 +4462,12 @@ void GLTrace_glUniform1f(GLint location, GLfloat x) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4107,9 +4502,13 @@ void GLTrace_glUniform1fv(GLint location, GLsizei count, const GLfloat* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4138,9 +4537,12 @@ void GLTrace_glUniform1i(GLint location, GLint x) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4175,9 +4577,13 @@ void GLTrace_glUniform1iv(GLint location, GLsizei count, const GLint* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4212,9 +4618,12 @@ void GLTrace_glUniform2f(GLint location, GLfloat x, GLfloat y) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4249,9 +4658,13 @@ void GLTrace_glUniform2fv(GLint location, GLsizei count, const GLfloat* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4286,9 +4699,12 @@ void GLTrace_glUniform2i(GLint location, GLint x, GLint y) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4323,9 +4739,13 @@ void GLTrace_glUniform2iv(GLint location, GLsizei count, const GLint* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4366,9 +4786,12 @@ void GLTrace_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4403,9 +4826,13 @@ void GLTrace_glUniform3fv(GLint location, GLsizei count, const GLfloat* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4446,9 +4873,12 @@ void GLTrace_glUniform3i(GLint location, GLint x, GLint y, GLint z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4483,9 +4913,13 @@ void GLTrace_glUniform3iv(GLint location, GLsizei count, const GLint* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4532,9 +4966,12 @@ void GLTrace_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloa
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4569,9 +5006,13 @@ void GLTrace_glUniform4fv(GLint location, GLsizei count, const GLfloat* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4618,9 +5059,12 @@ void GLTrace_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4655,9 +5099,13 @@ void GLTrace_glUniform4iv(GLint location, GLsizei count, const GLint* v) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) v,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4698,9 +5146,13 @@ void GLTrace_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpo
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4741,9 +5193,13 @@ void GLTrace_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpo
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4784,9 +5240,13 @@ void GLTrace_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpo
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4809,9 +5269,12 @@ void GLTrace_glUseProgram(GLuint program) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4834,9 +5297,12 @@ void GLTrace_glValidateProgram(GLuint program) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4865,9 +5331,12 @@ void GLTrace_glVertexAttrib1f(GLuint indx, GLfloat x) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4896,9 +5365,13 @@ void GLTrace_glVertexAttrib1fv(GLuint indx, const GLfloat* values) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) values,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4933,9 +5406,12 @@ void GLTrace_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -4964,9 +5440,13 @@ void GLTrace_glVertexAttrib2fv(GLuint indx, const GLfloat* values) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) values,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5007,9 +5487,12 @@ void GLTrace_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5038,9 +5521,13 @@ void GLTrace_glVertexAttrib3fv(GLuint indx, const GLfloat* values) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) values,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5087,9 +5574,12 @@ void GLTrace_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfl
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5118,9 +5608,13 @@ void GLTrace_glVertexAttrib4fv(GLuint indx, const GLfloat* values) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) values,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5173,9 +5667,13 @@ void GLTrace_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboole
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) ptr,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5216,9 +5714,12 @@ void GLTrace_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5250,9 +5751,13 @@ void GLTrace_glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) image,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5281,9 +5786,13 @@ void GLTrace_glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) image,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5330,9 +5839,15 @@ void GLTrace_glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *len
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) binaryFormat,
+ (void *) binary,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5373,9 +5888,13 @@ void GLTrace_glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoi
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) binary,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5410,9 +5929,13 @@ void* GLTrace_glMapBufferOES(GLenum target, GLenum access) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue((int)retValue);
+ void *pointerArgs[] = {
+ (void *) retValue,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -5443,9 +5966,12 @@ GLboolean GLTrace_glUnmapBufferOES(GLenum target) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -5482,9 +6008,13 @@ void GLTrace_glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid** params
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5561,9 +6091,13 @@ void GLTrace_glTexImage3DOES(GLenum target, GLint level, GLenum internalformat,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pixels,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5646,9 +6180,13 @@ void GLTrace_glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pixels,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5719,9 +6257,12 @@ void GLTrace_glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, G
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5792,9 +6333,13 @@ void GLTrace_glCompressedTexImage3DOES(GLenum target, GLint level, GLenum intern
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5877,9 +6422,13 @@ void GLTrace_glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoff
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5932,9 +6481,12 @@ void GLTrace_glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5957,9 +6509,12 @@ void GLTrace_glBindVertexArrayOES(GLuint array) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -5988,9 +6543,13 @@ void GLTrace_glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) arrays,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6019,9 +6578,13 @@ void GLTrace_glGenVertexArraysOES(GLsizei n, GLuint *arrays) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) arrays,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6050,9 +6613,12 @@ GLboolean GLTrace_glIsVertexArrayOES(GLuint array) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -6089,9 +6655,14 @@ void GLTrace_glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLu
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) numGroups,
+ (void *) groups,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6138,9 +6709,15 @@ void GLTrace_glGetPerfMonitorCountersAMD(GLuint group, GLint *numCounters, GLint
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) numCounters,
+ (void *) maxActiveCounters,
+ (void *) counters,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6181,9 +6758,14 @@ void GLTrace_glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsiz
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) groupString,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6230,9 +6812,14 @@ void GLTrace_glGetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, GLsi
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) counterString,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6273,9 +6860,13 @@ void GLTrace_glGetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6304,9 +6895,13 @@ void GLTrace_glGenPerfMonitorsAMD(GLsizei n, GLuint *monitors) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) monitors,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6335,9 +6930,13 @@ void GLTrace_glDeletePerfMonitorsAMD(GLsizei n, GLuint *monitors) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) monitors,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6384,9 +6983,13 @@ void GLTrace_glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) countersList,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6409,9 +7012,12 @@ void GLTrace_glBeginPerfMonitorAMD(GLuint monitor) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6434,9 +7040,12 @@ void GLTrace_glEndPerfMonitorAMD(GLuint monitor) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6483,9 +7092,14 @@ void GLTrace_glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsize
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ (void *) bytesWritten,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6562,9 +7176,12 @@ void GLTrace_glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6611,9 +7228,12 @@ void GLTrace_glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei sample
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6660,9 +7280,12 @@ void GLTrace_glRenderbufferStorageMultisampleAPPLE(GLenum target, GLsizei sample
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6679,9 +7302,12 @@ void GLTrace_glResolveMultisampleFramebufferAPPLE(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6722,9 +7348,13 @@ void GLTrace_glLabelObjectEXT(GLenum type, GLuint object, GLsizei length, const
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) label,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6771,9 +7401,14 @@ void GLTrace_glGetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) label,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6802,9 +7437,13 @@ void GLTrace_glInsertEventMarkerEXT(GLsizei length, const GLchar *marker) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) marker,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6833,9 +7472,13 @@ void GLTrace_glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) marker,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6852,9 +7495,12 @@ void GLTrace_glPopGroupMarkerEXT(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6889,9 +7535,13 @@ void GLTrace_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, cons
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) attachments,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6938,9 +7588,12 @@ void GLTrace_glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -6993,9 +7646,12 @@ void GLTrace_glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachme
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7036,9 +7692,14 @@ void GLTrace_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLs
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) first,
+ (void *) count,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7085,9 +7746,14 @@ void GLTrace_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum ty
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) count,
+ (void *) indices,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7116,9 +7782,13 @@ void GLTrace_glGenQueriesEXT(GLsizei n, GLuint *ids) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) ids,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7147,9 +7817,13 @@ void GLTrace_glDeleteQueriesEXT(GLsizei n, const GLuint *ids) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) ids,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7178,9 +7852,12 @@ GLboolean GLTrace_glIsQueryEXT(GLuint id) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -7211,9 +7888,12 @@ void GLTrace_glBeginQueryEXT(GLenum target, GLuint id) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7236,9 +7916,12 @@ void GLTrace_glEndQueryEXT(GLenum target) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7273,9 +7956,13 @@ void GLTrace_glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7310,9 +7997,13 @@ void GLTrace_glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7335,9 +8026,12 @@ GLenum GLTrace_glGetGraphicsResetStatusEXT(void) {
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -7404,9 +8098,13 @@ void GLTrace_glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, G
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) data,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7447,9 +8145,13 @@ void GLTrace_glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7490,9 +8192,13 @@ void GLTrace_glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7527,9 +8233,12 @@ void GLTrace_glUseProgramStagesEXT(GLuint pipeline, GLbitfield stages, GLuint pr
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7558,9 +8267,12 @@ void GLTrace_glActiveShaderProgramEXT(GLuint pipeline, GLuint program) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7601,9 +8313,13 @@ GLuint GLTrace_glCreateShaderProgramvEXT(GLenum type, GLsizei count, const GLcha
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
+ void *pointerArgs[] = {
+ (void *) strings,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -7628,9 +8344,12 @@ void GLTrace_glBindProgramPipelineEXT(GLuint pipeline) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7659,9 +8378,13 @@ void GLTrace_glDeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pipelines,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7690,9 +8413,13 @@ void GLTrace_glGenProgramPipelinesEXT(GLsizei n, GLuint *pipelines) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pipelines,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7721,9 +8448,12 @@ GLboolean GLTrace_glIsProgramPipelineEXT(GLuint pipeline) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -7760,9 +8490,12 @@ void GLTrace_glProgramParameteriEXT(GLuint program, GLenum pname, GLint value) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7797,9 +8530,13 @@ void GLTrace_glGetProgramPipelineivEXT(GLuint pipeline, GLenum pname, GLint *par
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7834,9 +8571,12 @@ void GLTrace_glProgramUniform1iEXT(GLuint program, GLint location, GLint x) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7877,9 +8617,12 @@ void GLTrace_glProgramUniform2iEXT(GLuint program, GLint location, GLint x, GLin
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7926,9 +8669,12 @@ void GLTrace_glProgramUniform3iEXT(GLuint program, GLint location, GLint x, GLin
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -7981,9 +8727,12 @@ void GLTrace_glProgramUniform4iEXT(GLuint program, GLint location, GLint x, GLin
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8018,9 +8767,12 @@ void GLTrace_glProgramUniform1fEXT(GLuint program, GLint location, GLfloat x) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8061,9 +8813,12 @@ void GLTrace_glProgramUniform2fEXT(GLuint program, GLint location, GLfloat x, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8110,9 +8865,12 @@ void GLTrace_glProgramUniform3fEXT(GLuint program, GLint location, GLfloat x, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8165,9 +8923,12 @@ void GLTrace_glProgramUniform4fEXT(GLuint program, GLint location, GLfloat x, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8208,9 +8969,13 @@ void GLTrace_glProgramUniform1ivEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8251,9 +9016,13 @@ void GLTrace_glProgramUniform2ivEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8294,9 +9063,13 @@ void GLTrace_glProgramUniform3ivEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8337,9 +9110,13 @@ void GLTrace_glProgramUniform4ivEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8380,9 +9157,13 @@ void GLTrace_glProgramUniform1fvEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8423,9 +9204,13 @@ void GLTrace_glProgramUniform2fvEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8466,9 +9251,13 @@ void GLTrace_glProgramUniform3fvEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8509,9 +9298,13 @@ void GLTrace_glProgramUniform4fvEXT(GLuint program, GLint location, GLsizei coun
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8558,9 +9351,13 @@ void GLTrace_glProgramUniformMatrix2fvEXT(GLuint program, GLint location, GLsize
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8607,9 +9404,13 @@ void GLTrace_glProgramUniformMatrix3fvEXT(GLuint program, GLint location, GLsize
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8656,9 +9457,13 @@ void GLTrace_glProgramUniformMatrix4fvEXT(GLuint program, GLint location, GLsize
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) value,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8681,9 +9486,12 @@ void GLTrace_glValidateProgramPipelineEXT(GLuint pipeline) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8724,9 +9532,14 @@ void GLTrace_glGetProgramPipelineInfoLogEXT(GLuint pipeline, GLsizei bufSize, GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) infoLog,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8767,9 +9580,12 @@ void GLTrace_glTexStorage1DEXT(GLenum target, GLsizei levels, GLenum internalfor
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8816,9 +9632,12 @@ void GLTrace_glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalfor
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8871,9 +9690,12 @@ void GLTrace_glTexStorage3DEXT(GLenum target, GLsizei levels, GLenum internalfor
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8920,9 +9742,12 @@ void GLTrace_glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -8975,9 +9800,12 @@ void GLTrace_glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9036,9 +9864,12 @@ void GLTrace_glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9085,9 +9916,12 @@ void GLTrace_glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9140,9 +9974,12 @@ void GLTrace_glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachme
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9165,9 +10002,12 @@ void GLTrace_glCoverageMaskNV(GLboolean mask) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9190,9 +10030,12 @@ void GLTrace_glCoverageOperationNV(GLenum operation) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9221,9 +10064,13 @@ void GLTrace_glDrawBuffersNV(GLsizei n, const GLenum *bufs) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) bufs,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9252,9 +10099,13 @@ void GLTrace_glDeleteFencesNV(GLsizei n, const GLuint *fences) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) fences,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9283,9 +10134,13 @@ void GLTrace_glGenFencesNV(GLsizei n, GLuint *fences) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) fences,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9314,9 +10169,12 @@ GLboolean GLTrace_glIsFenceNV(GLuint fence) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -9347,9 +10205,12 @@ GLboolean GLTrace_glTestFenceNV(GLuint fence) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -9386,9 +10247,13 @@ void GLTrace_glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9411,9 +10276,12 @@ void GLTrace_glFinishFenceNV(GLuint fence) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9442,9 +10310,12 @@ void GLTrace_glSetFenceNV(GLuint fence, GLenum condition) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9467,9 +10338,12 @@ void GLTrace_glReadBufferNV(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9498,9 +10372,12 @@ void GLTrace_glAlphaFuncQCOM(GLenum func, GLclampf ref) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9535,9 +10412,14 @@ void GLTrace_glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverCon
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) num,
+ (void *) driverControls,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9578,9 +10460,14 @@ void GLTrace_glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) length,
+ (void *) driverControlString,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9603,9 +10490,12 @@ void GLTrace_glEnableDriverControlQCOM(GLuint driverControl) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9628,9 +10518,12 @@ void GLTrace_glDisableDriverControlQCOM(GLuint driverControl) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9665,9 +10558,14 @@ void GLTrace_glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *nu
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) textures,
+ (void *) numTextures,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9702,9 +10600,14 @@ void GLTrace_glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBu
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) buffers,
+ (void *) numBuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9739,9 +10642,14 @@ void GLTrace_glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuf
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) renderbuffers,
+ (void *) numRenderbuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9776,9 +10684,14 @@ void GLTrace_glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffer
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) framebuffers,
+ (void *) numFramebuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9825,9 +10738,13 @@ void GLTrace_glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9862,9 +10779,12 @@ void GLTrace_glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9947,9 +10867,13 @@ void GLTrace_glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) texels,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -9978,9 +10902,13 @@ void GLTrace_glExtGetBufferPointervQCOM(GLenum target, GLvoid **params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10015,9 +10943,14 @@ void GLTrace_glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numSh
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) shaders,
+ (void *) numShaders,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10052,9 +10985,14 @@ void GLTrace_glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *nu
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) programs,
+ (void *) numPrograms,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10083,9 +11021,12 @@ GLboolean GLTrace_glExtIsProgramBinaryQCOM(GLuint program) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -10128,9 +11069,14 @@ void GLTrace_glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) source,
+ (void *) length,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10177,9 +11123,12 @@ void GLTrace_glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10202,9 +11151,12 @@ void GLTrace_glEndTilingQCOM(GLbitfield preserveMask) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10236,9 +11188,12 @@ void GLTrace_glAlphaFunc(GLenum func, GLclampf ref) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10267,9 +11222,13 @@ void GLTrace_glClipPlanef(GLenum plane, const GLfloat *equation) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) equation,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10310,9 +11269,12 @@ void GLTrace_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10341,9 +11303,12 @@ void GLTrace_glFogf(GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10372,9 +11337,13 @@ void GLTrace_glFogfv(GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10427,9 +11396,12 @@ void GLTrace_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10458,9 +11430,13 @@ void GLTrace_glGetClipPlanef(GLenum pname, GLfloat eqn[4]) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) eqn,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10495,9 +11471,13 @@ void GLTrace_glGetLightfv(GLenum light, GLenum pname, GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10532,9 +11512,13 @@ void GLTrace_glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10569,9 +11553,13 @@ void GLTrace_glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10600,9 +11588,12 @@ void GLTrace_glLightModelf(GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10631,9 +11622,13 @@ void GLTrace_glLightModelfv(GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10668,9 +11663,12 @@ void GLTrace_glLightf(GLenum light, GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10705,9 +11703,13 @@ void GLTrace_glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10730,9 +11732,13 @@ void GLTrace_glLoadMatrixf(const GLfloat *m) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) m,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10767,9 +11773,12 @@ void GLTrace_glMaterialf(GLenum face, GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10804,9 +11813,13 @@ void GLTrace_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10829,9 +11842,13 @@ void GLTrace_glMultMatrixf(const GLfloat *m) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) m,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10878,9 +11895,12 @@ void GLTrace_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, G
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10915,9 +11935,12 @@ void GLTrace_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -10970,9 +11993,12 @@ void GLTrace_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11001,9 +12027,12 @@ void GLTrace_glPointParameterf(GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11032,9 +12061,13 @@ void GLTrace_glPointParameterfv(GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11057,9 +12090,12 @@ void GLTrace_glPointSize(GLfloat size) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11100,9 +12136,12 @@ void GLTrace_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11137,9 +12176,12 @@ void GLTrace_glScalef(GLfloat x, GLfloat y, GLfloat z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11174,9 +12216,12 @@ void GLTrace_glTexEnvf(GLenum target, GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11211,9 +12256,13 @@ void GLTrace_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11248,9 +12297,12 @@ void GLTrace_glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11279,9 +12331,12 @@ void GLTrace_glAlphaFuncx(GLenum func, GLclampx ref) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11322,9 +12377,12 @@ void GLTrace_glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11347,9 +12405,12 @@ void GLTrace_glClearDepthx(GLclampx depth) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11372,9 +12433,12 @@ void GLTrace_glClientActiveTexture(GLenum texture) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11403,9 +12467,13 @@ void GLTrace_glClipPlanex(GLenum plane, const GLfixed *equation) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) equation,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11446,9 +12514,12 @@ void GLTrace_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11489,9 +12560,12 @@ void GLTrace_glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11532,9 +12606,13 @@ void GLTrace_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoi
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11563,9 +12641,12 @@ void GLTrace_glDepthRangex(GLclampx zNear, GLclampx zFar) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11588,9 +12669,12 @@ void GLTrace_glDisableClientState(GLenum array) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11613,9 +12697,12 @@ void GLTrace_glEnableClientState(GLenum array) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11644,9 +12731,12 @@ void GLTrace_glFogx(GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11675,9 +12765,13 @@ void GLTrace_glFogxv(GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11730,9 +12824,12 @@ void GLTrace_glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11761,9 +12858,13 @@ void GLTrace_glGetClipPlanex(GLenum pname, GLfixed eqn[4]) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) eqn,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11792,9 +12893,13 @@ void GLTrace_glGetFixedv(GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11829,9 +12934,13 @@ void GLTrace_glGetLightxv(GLenum light, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11866,9 +12975,13 @@ void GLTrace_glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11897,9 +13010,13 @@ void GLTrace_glGetPointerv(GLenum pname, GLvoid **params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11934,9 +13051,13 @@ void GLTrace_glGetTexEnviv(GLenum env, GLenum pname, GLint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -11971,9 +13092,13 @@ void GLTrace_glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12008,9 +13133,13 @@ void GLTrace_glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12039,9 +13168,12 @@ void GLTrace_glLightModelx(GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12070,9 +13202,13 @@ void GLTrace_glLightModelxv(GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12107,9 +13243,12 @@ void GLTrace_glLightx(GLenum light, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12144,9 +13283,13 @@ void GLTrace_glLightxv(GLenum light, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12169,9 +13312,12 @@ void GLTrace_glLineWidthx(GLfixed width) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12188,9 +13334,12 @@ void GLTrace_glLoadIdentity(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12213,9 +13362,13 @@ void GLTrace_glLoadMatrixx(const GLfixed *m) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) m,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12238,9 +13391,12 @@ void GLTrace_glLogicOp(GLenum opcode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12275,9 +13431,12 @@ void GLTrace_glMaterialx(GLenum face, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12312,9 +13471,13 @@ void GLTrace_glMaterialxv(GLenum face, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12337,9 +13500,12 @@ void GLTrace_glMatrixMode(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12362,9 +13528,13 @@ void GLTrace_glMultMatrixx(const GLfixed *m) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) m,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12411,9 +13581,12 @@ void GLTrace_glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, G
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12448,9 +13621,12 @@ void GLTrace_glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12485,9 +13661,13 @@ void GLTrace_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12540,9 +13720,12 @@ void GLTrace_glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top,
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12571,9 +13754,12 @@ void GLTrace_glPointParameterx(GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12602,9 +13788,13 @@ void GLTrace_glPointParameterxv(GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12627,9 +13817,12 @@ void GLTrace_glPointSizex(GLfixed size) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12658,9 +13851,12 @@ void GLTrace_glPolygonOffsetx(GLfixed factor, GLfixed units) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12677,9 +13873,12 @@ void GLTrace_glPopMatrix(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12696,9 +13895,12 @@ void GLTrace_glPushMatrix(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12739,9 +13941,12 @@ void GLTrace_glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12770,9 +13975,12 @@ void GLTrace_glSampleCoveragex(GLclampx value, GLboolean invert) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12807,9 +14015,12 @@ void GLTrace_glScalex(GLfixed x, GLfixed y, GLfixed z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12832,9 +14043,12 @@ void GLTrace_glShadeModel(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12875,9 +14089,13 @@ void GLTrace_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GL
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12912,9 +14130,12 @@ void GLTrace_glTexEnvi(GLenum target, GLenum pname, GLint param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12949,9 +14170,12 @@ void GLTrace_glTexEnvx(GLenum target, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -12986,9 +14210,13 @@ void GLTrace_glTexEnviv(GLenum target, GLenum pname, const GLint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13023,9 +14251,13 @@ void GLTrace_glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13060,9 +14292,12 @@ void GLTrace_glTexParameterx(GLenum target, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13097,9 +14332,13 @@ void GLTrace_glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13134,9 +14373,12 @@ void GLTrace_glTranslatex(GLfixed x, GLfixed y, GLfixed z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13177,9 +14419,13 @@ void GLTrace_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvo
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13214,9 +14460,13 @@ void GLTrace_glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *po
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13248,9 +14498,12 @@ void GLTrace_glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13291,9 +14544,12 @@ void GLTrace_glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlph
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13316,9 +14572,12 @@ void GLTrace_glBlendEquationOES(GLenum mode) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13365,9 +14624,12 @@ void GLTrace_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLsho
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13414,9 +14676,12 @@ void GLTrace_glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13463,9 +14728,12 @@ void GLTrace_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfix
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13488,9 +14756,13 @@ void GLTrace_glDrawTexsvOES(const GLshort *coords) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) coords,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13513,9 +14785,13 @@ void GLTrace_glDrawTexivOES(const GLint *coords) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) coords,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13538,9 +14814,13 @@ void GLTrace_glDrawTexxvOES(const GLfixed *coords) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) coords,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13587,9 +14867,12 @@ void GLTrace_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLflo
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13612,9 +14895,13 @@ void GLTrace_glDrawTexfvOES(const GLfloat *coords) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) coords,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13643,9 +14930,12 @@ void GLTrace_glAlphaFuncxOES(GLenum func, GLclampx ref) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13686,9 +14976,12 @@ void GLTrace_glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLcla
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13711,9 +15004,12 @@ void GLTrace_glClearDepthxOES(GLclampx depth) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13742,9 +15038,13 @@ void GLTrace_glClipPlanexOES(GLenum plane, const GLfixed *equation) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) equation,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13785,9 +15085,12 @@ void GLTrace_glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alph
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13816,9 +15119,12 @@ void GLTrace_glDepthRangexOES(GLclampx zNear, GLclampx zFar) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13847,9 +15153,12 @@ void GLTrace_glFogxOES(GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13878,9 +15187,13 @@ void GLTrace_glFogxvOES(GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13933,9 +15246,12 @@ void GLTrace_glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13964,9 +15280,13 @@ void GLTrace_glGetClipPlanexOES(GLenum pname, GLfixed eqn[4]) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) eqn,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -13995,9 +15315,13 @@ void GLTrace_glGetFixedvOES(GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14032,9 +15356,13 @@ void GLTrace_glGetLightxvOES(GLenum light, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14069,9 +15397,13 @@ void GLTrace_glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14106,9 +15438,13 @@ void GLTrace_glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14143,9 +15479,13 @@ void GLTrace_glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14174,9 +15514,12 @@ void GLTrace_glLightModelxOES(GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14205,9 +15548,13 @@ void GLTrace_glLightModelxvOES(GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14242,9 +15589,12 @@ void GLTrace_glLightxOES(GLenum light, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14279,9 +15629,13 @@ void GLTrace_glLightxvOES(GLenum light, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14304,9 +15658,12 @@ void GLTrace_glLineWidthxOES(GLfixed width) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14329,9 +15686,13 @@ void GLTrace_glLoadMatrixxOES(const GLfixed *m) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) m,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14366,9 +15727,12 @@ void GLTrace_glMaterialxOES(GLenum face, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14403,9 +15767,13 @@ void GLTrace_glMaterialxvOES(GLenum face, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14428,9 +15796,13 @@ void GLTrace_glMultMatrixxOES(const GLfixed *m) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) m,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14477,9 +15849,12 @@ void GLTrace_glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14514,9 +15889,12 @@ void GLTrace_glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14569,9 +15947,12 @@ void GLTrace_glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed to
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14600,9 +15981,12 @@ void GLTrace_glPointParameterxOES(GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14631,9 +16015,13 @@ void GLTrace_glPointParameterxvOES(GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14656,9 +16044,12 @@ void GLTrace_glPointSizexOES(GLfixed size) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14687,9 +16078,12 @@ void GLTrace_glPolygonOffsetxOES(GLfixed factor, GLfixed units) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14730,9 +16124,12 @@ void GLTrace_glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14761,9 +16158,12 @@ void GLTrace_glSampleCoveragexOES(GLclampx value, GLboolean invert) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14798,9 +16198,12 @@ void GLTrace_glScalexOES(GLfixed x, GLfixed y, GLfixed z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14835,9 +16238,12 @@ void GLTrace_glTexEnvxOES(GLenum target, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14872,9 +16278,13 @@ void GLTrace_glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14909,9 +16319,12 @@ void GLTrace_glTexParameterxOES(GLenum target, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14946,9 +16359,13 @@ void GLTrace_glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed *par
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -14983,9 +16400,12 @@ void GLTrace_glTranslatexOES(GLfixed x, GLfixed y, GLfixed z) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15014,9 +16434,12 @@ GLboolean GLTrace_glIsRenderbufferOES(GLuint renderbuffer) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -15047,9 +16470,12 @@ void GLTrace_glBindRenderbufferOES(GLenum target, GLuint renderbuffer) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15078,9 +16504,13 @@ void GLTrace_glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) renderbuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15109,9 +16539,13 @@ void GLTrace_glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) renderbuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15152,9 +16586,12 @@ void GLTrace_glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsi
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15189,9 +16626,13 @@ void GLTrace_glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint*
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15220,9 +16661,12 @@ GLboolean GLTrace_glIsFramebufferOES(GLuint framebuffer) {
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -15253,9 +16697,12 @@ void GLTrace_glBindFramebufferOES(GLenum target, GLuint framebuffer) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15284,9 +16731,13 @@ void GLTrace_glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) framebuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15315,9 +16766,13 @@ void GLTrace_glGenFramebuffersOES(GLsizei n, GLuint* framebuffers) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) framebuffers,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15346,9 +16801,12 @@ GLenum GLTrace_glCheckFramebufferStatusOES(GLenum target) {
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -15391,9 +16849,12 @@ void GLTrace_glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLen
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15440,9 +16901,12 @@ void GLTrace_glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15483,9 +16947,13 @@ void GLTrace_glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum atta
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15508,9 +16976,12 @@ void GLTrace_glGenerateMipmapOES(GLenum target) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15533,9 +17004,12 @@ void GLTrace_glCurrentPaletteMatrixOES(GLuint matrixpaletteindex) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15552,9 +17026,12 @@ void GLTrace_glLoadPaletteFromModelViewMatrixOES(void) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15595,9 +17072,13 @@ void GLTrace_glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, co
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15638,9 +17119,13 @@ void GLTrace_glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const G
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) pointer,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15675,9 +17160,14 @@ GLbitfield GLTrace_glQueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]) {
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
+ void *pointerArgs[] = {
+ (void *) mantissa,
+ (void *) exponent,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -15708,9 +17198,12 @@ void GLTrace_glDepthRangefOES(GLclampf zNear, GLclampf zFar) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15763,9 +17256,12 @@ void GLTrace_glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15818,9 +17314,12 @@ void GLTrace_glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat to
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15849,9 +17348,13 @@ void GLTrace_glClipPlanefOES(GLenum plane, const GLfloat *equation) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) equation,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15880,9 +17383,13 @@ void GLTrace_glGetClipPlanefOES(GLenum pname, GLfloat eqn[4]) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) eqn,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15905,9 +17412,12 @@ void GLTrace_glClearDepthfOES(GLclampf depth) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15942,9 +17452,12 @@ void GLTrace_glTexGenfOES(GLenum coord, GLenum pname, GLfloat param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -15979,9 +17492,13 @@ void GLTrace_glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16016,9 +17533,12 @@ void GLTrace_glTexGeniOES(GLenum coord, GLenum pname, GLint param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16053,9 +17573,13 @@ void GLTrace_glTexGenivOES(GLenum coord, GLenum pname, const GLint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16090,9 +17614,12 @@ void GLTrace_glTexGenxOES(GLenum coord, GLenum pname, GLfixed param) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16127,9 +17654,13 @@ void GLTrace_glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16164,9 +17695,13 @@ void GLTrace_glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16201,9 +17736,13 @@ void GLTrace_glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16238,9 +17777,13 @@ void GLTrace_glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) params,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16269,9 +17812,13 @@ void GLTrace_glClipPlanefIMG(GLenum p, const GLfloat *eqn) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) eqn,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
@@ -16300,9 +17847,13 @@ void GLTrace_glClipPlanexIMG(GLenum p, const GLfixed *eqn) {
nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ void *pointerArgs[] = {
+ (void *) eqn,
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
}
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index 6c4feb5a56d7..c69ba5e1b4e9 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -76,21 +76,64 @@ unsigned getBytesPerTexel(const GLenum format, const GLenum type) {
return 1; // in doubt...
}
+void fixup_GenericFloatArray(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
+ GLMessage_DataType *arg_floatarray = glmsg->mutable_args(argIndex);
+ GLfloat *floatp = (GLfloat *)src;
+
+ if (floatp == NULL) {
+ return;
+ }
+
+ arg_floatarray->set_type(GLMessage::DataType::FLOAT);
+ arg_floatarray->set_isarray(true);
+ arg_floatarray->clear_floatvalue();
+
+ for (int i = 0; i < nFloats; i++, floatp++) {
+ arg_floatarray->add_floatvalue(*floatp);
+ }
+}
+
+void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg, void *src) {
+ GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
+ GLint *intp = (GLint *)src;
+
+ if (intp == NULL) {
+ return;
+ }
+
+ arg_intarray->set_type(GLMessage::DataType::INT);
+ arg_intarray->set_isarray(true);
+ arg_intarray->clear_intvalue();
+
+ for (int i = 0; i < nInts; i++, intp++) {
+ arg_intarray->add_intvalue(*intp);
+ }
+}
+
+void fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg, void *src) {
+ // fixup as if they were ints
+ fixup_GenericIntArray(argIndex, nEnums, glmsg, src);
+
+ // and then set the data type to be enum
+ GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
+ arg_enumarray->set_type(GLMessage::DataType::ENUM);
+}
+
/** Generic helper function: extract pointer at argIndex and
replace it with the C style string at *pointer */
-void fixup_CStringPtr(int argIndex, GLMessage *glmsg) {
+void fixup_CStringPtr(int argIndex, GLMessage *glmsg, void *src) {
GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
- GLchar *ptr = (GLchar *)arg->intvalue(0);
+ GLchar *ptr = (GLchar *) src;
arg->set_type(GLMessage::DataType::CHAR);
arg->set_isarray(true);
arg->add_charvalue(ptr);
}
-void fixup_glGetString(GLMessage *glmsg) {
+void fixup_glGetString(GLMessage *glmsg, void *pointersToFixup[]) {
/* const GLubyte* GLTrace_glGetString(GLenum name) */
GLMessage_DataType *ret = glmsg->mutable_returnvalue();
- GLchar *ptr = (GLchar *)ret->intvalue(0);
+ GLchar *ptr = (GLchar *) pointersToFixup[0];
if (ptr != NULL) {
ret->set_type(GLMessage::DataType::CHAR);
@@ -112,7 +155,7 @@ void fixup_addFBContents(GLTraceContext *context, GLMessage *glmsg, FBBinding fb
}
/** Common fixup routing for glTexImage2D & glTexSubImage2D. */
-void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg) {
+void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg, void *dataSrc) {
GLMessage_DataType arg_width = glmsg->args(widthIndex);
GLMessage_DataType arg_height = glmsg->args(heightIndex);
@@ -124,7 +167,7 @@ void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg) {
GLsizei height = arg_height.intvalue(0);
GLenum format = arg_format.intvalue(0);
GLenum type = arg_type.intvalue(0);
- void *data = (void *)arg_data->intvalue(0);
+ void *data = (void *) dataSrc;
int bytesPerTexel = getBytesPerTexel(format, type);
@@ -141,7 +184,7 @@ void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg) {
}
-void fixup_glTexImage2D(GLMessage *glmsg) {
+void fixup_glTexImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glTexImage2D(GLenum target,
GLint level,
GLint internalformat,
@@ -154,10 +197,10 @@ void fixup_glTexImage2D(GLMessage *glmsg) {
*/
int widthIndex = 3;
int heightIndex = 4;
- fixup_glTexImage(widthIndex, heightIndex, glmsg);
+ fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
}
-void fixup_glTexSubImage2D(GLMessage *glmsg) {
+void fixup_glTexSubImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
/*
void glTexSubImage2D(GLenum target,
GLint level,
@@ -171,10 +214,10 @@ void fixup_glTexSubImage2D(GLMessage *glmsg) {
*/
int widthIndex = 4;
int heightIndex = 5;
- fixup_glTexImage(widthIndex, heightIndex, glmsg);
+ fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
}
-void fixup_glShaderSource(GLMessage *glmsg) {
+void fixup_glShaderSource(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
const GLint* length) */
GLMessage_DataType arg_count = glmsg->args(1);
@@ -182,8 +225,8 @@ void fixup_glShaderSource(GLMessage *glmsg) {
GLMessage_DataType *arg_strpp = glmsg->mutable_args(2);
GLsizei count = arg_count.intvalue(0);
- GLchar **stringpp = (GLchar **)arg_strpp->intvalue(0);
- GLint *lengthp = (GLint *)arg_lenp.intvalue(0);
+ GLchar **stringpp = (GLchar **) pointersToFixup[0];
+ GLint *lengthp = (GLint *) pointersToFixup[1];
arg_strpp->set_type(GLMessage::DataType::CHAR);
arg_strpp->set_isarray(true);
@@ -202,87 +245,64 @@ void fixup_glShaderSource(GLMessage *glmsg) {
arg_strpp->add_charvalue(src);
}
-void fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg) {
+void fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg,
+ void *pointersToFixup[]) {
/* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
- GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
- GLint *src = (GLint*)arg_values->intvalue(0);
-
- arg_values->set_type(GLMessage::DataType::INT);
- arg_values->set_isarray(true);
- arg_values->clear_intvalue();
-
- for (int i = 0; i < nIntegers; i++) {
- arg_values->add_intvalue(*src++);
- }
+ fixup_GenericIntArray(argIndex, nIntegers, glmsg, pointersToFixup[0]);
}
-void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg) {
- GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
- GLfloat *src = (GLfloat*)arg_values->intvalue(0);
-
- arg_values->set_type(GLMessage::DataType::FLOAT);
- arg_values->set_isarray(true);
- arg_values->clear_floatvalue();
-
- for (int i = 0; i < nFloats; i++) {
- arg_values->add_floatvalue(*src++);
- }
+void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
+ fixup_GenericFloatArray(argIndex, nFloats, glmsg, src);
}
-void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg) {
+void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg, void *pointersToFixup[]) {
/* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat* value) */
GLMessage_DataType arg_count = glmsg->args(1);
int n_matrices = arg_count.intvalue(0);
- fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg);
+ fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg, pointersToFixup[0]);
}
-void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) {
- GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
- GLint *intp = (GLint *)arg_intarray->intvalue(0);
+void fixup_glBufferData(int sizeIndex, int dataIndex, GLMessage *glmsg, void *pointersToFixup[]) {
+ /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
+ /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
+ GLsizeiptr size = glmsg->args(sizeIndex).intvalue(0);
- if (intp == NULL) {
- return;
- }
+ GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
+ GLvoid *datap = (GLvoid *) pointersToFixup[0];
- arg_intarray->set_type(GLMessage::DataType::INT);
- arg_intarray->set_isarray(true);
- arg_intarray->clear_intvalue();
-
- for (int i = 0; i < nInts; i++, intp++) {
- arg_intarray->add_intvalue(*intp);
+ if (datap == NULL) {
+ // glBufferData can be called with a NULL data pointer
+ return;
}
-}
-void fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg) {
- // fixup as if they were ints
- fixup_GenericIntArray(argIndex, nEnums, glmsg);
+ arg_datap->set_type(GLMessage::DataType::VOID);
+ arg_datap->set_isarray(true);
+ arg_datap->clear_intvalue();
- // and then set the data type to be enum
- GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
- arg_enumarray->set_type(GLMessage::DataType::ENUM);
+ arg_datap->add_rawbytes(datap, size);
}
-void fixup_glGenGeneric(GLMessage *glmsg) {
+void fixup_glGenGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glGen*(GLsizei n, GLuint * buffers); */
GLMessage_DataType arg_n = glmsg->args(0);
GLsizei n = arg_n.intvalue(0);
- fixup_GenericIntArray(1, n, glmsg);
+ fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
}
-void fixup_glDeleteGeneric(GLMessage *glmsg) {
+void fixup_glDeleteGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glDelete*(GLsizei n, GLuint *buffers); */
GLMessage_DataType arg_n = glmsg->args(0);
GLsizei n = arg_n.intvalue(0);
- fixup_GenericIntArray(1, n, glmsg);
+ fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
}
-void fixup_glGetBooleanv(GLMessage *glmsg) {
+void fixup_glGetBooleanv(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glGetBooleanv(GLenum pname, GLboolean *params); */
GLMessage_DataType *arg_params = glmsg->mutable_args(1);
- GLboolean *src = (GLboolean*)arg_params->intvalue(0);
+ GLboolean *src = (GLboolean*) pointersToFixup[0];
arg_params->set_type(GLMessage::DataType::BOOL);
arg_params->set_isarray(true);
@@ -290,10 +310,10 @@ void fixup_glGetBooleanv(GLMessage *glmsg) {
arg_params->add_boolvalue(*src);
}
-void fixup_glGetFloatv(GLMessage *glmsg) {
+void fixup_glGetFloatv(GLMessage *glmsg, void *pointersToFixup[]) {
/* void glGetFloatv(GLenum pname, GLfloat *params); */
GLMessage_DataType *arg_params = glmsg->mutable_args(1);
- GLfloat *src = (GLfloat*)arg_params->intvalue(0);
+ GLfloat *src = (GLfloat*) pointersToFixup[0];
arg_params->set_type(GLMessage::DataType::FLOAT);
arg_params->set_isarray(true);
@@ -338,16 +358,15 @@ void fixup_glLinkProgram(GLMessage *glmsg) {
}
/** Given a glGetActive[Uniform|Attrib] call, obtain the location
- * of the variable in the call.
+ * of the variable of given name in the call.
*/
-int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg) {
+int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg, GLchar *name) {
GLMessage_Function func = glmsg->function();
if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
return -1;
}
int program = glmsg->args(0).intvalue(0);
- GLchar *name = (GLchar*) glmsg->args(6).intvalue(0);
if (func == GLMessage::glGetActiveAttrib) {
return context->hooks->gl.glGetAttribLocation(program, name);
@@ -356,16 +375,17 @@ int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg) {
}
}
-void fixup_glGetActiveAttribOrUniform(GLMessage *glmsg, int location) {
+void fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg,
+ void *pointersToFixup[]) {
/* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
/* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
GLsizei* length, GLint* size, GLenum* type, GLchar* name) */
- fixup_GenericIntArray(3, 1, glmsg); // length
- fixup_GenericIntArray(4, 1, glmsg); // size
- fixup_GenericEnumArray(5, 1, glmsg); // type
- fixup_CStringPtr(6, glmsg); // name
+ fixup_GenericIntArray(3, 1, glmsg, pointersToFixup[0]); // length
+ fixup_GenericIntArray(4, 1, glmsg, pointersToFixup[1]); // size
+ fixup_GenericEnumArray(5, 1, glmsg, pointersToFixup[2]); // type
+ fixup_CStringPtr(6, glmsg, pointersToFixup[3]); // name
// The index argument in the glGetActive[Attrib|Uniform] functions
// does not correspond to the actual location index as used in
@@ -373,6 +393,7 @@ void fixup_glGetActiveAttribOrUniform(GLMessage *glmsg, int location) {
// In order to make things simpler for the debugger, we also pass
// a hidden location argument that stores the actual location.
// append the location value to the end of the argument list
+ int location = getShaderVariableLocation(context, glmsg, (GLchar*)pointersToFixup[3]);
GLMessage_DataType *arg_location = glmsg->add_args();
arg_location->set_isarray(false);
arg_location->set_type(GLMessage::DataType::INT);
@@ -381,7 +402,7 @@ void fixup_glGetActiveAttribOrUniform(GLMessage *glmsg, int location) {
void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
nsecs_t threadStart, nsecs_t threadEnd,
- GLMessage *glmsg) {
+ GLMessage *glmsg, void *pointersToFixup[]) {
// for all messages, set the current context id
glmsg->set_context_id(context->getId());
@@ -396,41 +417,41 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
case GLMessage::glDeleteFramebuffers: /* glDeleteFramebuffers(GLsizei n, GLuint *buffers); */
case GLMessage::glDeleteRenderbuffers:/* glDeleteRenderbuffers(GLsizei n, GLuint *buffers); */
case GLMessage::glDeleteTextures: /* glDeleteTextures(GLsizei n, GLuint *textures); */
- fixup_glDeleteGeneric(glmsg);
+ fixup_glDeleteGeneric(glmsg, pointersToFixup);
break;
case GLMessage::glGenBuffers: /* void glGenBuffers(GLsizei n, GLuint *buffers); */
case GLMessage::glGenFramebuffers: /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
case GLMessage::glGenRenderbuffers: /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
case GLMessage::glGenTextures: /* void glGenTextures(GLsizei n, GLuint *textures); */
- fixup_glGenGeneric(glmsg);
+ fixup_glGenGeneric(glmsg, pointersToFixup);
break;
case GLMessage::glLinkProgram: /* void glLinkProgram(GLuint program); */
fixup_glLinkProgram(glmsg);
break;
case GLMessage::glGetActiveAttrib:
- fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
+ fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
break;
case GLMessage::glGetActiveUniform:
- fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
+ fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
break;
case GLMessage::glBindAttribLocation:
/* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
- fixup_CStringPtr(2, glmsg);
+ fixup_CStringPtr(2, glmsg, pointersToFixup[0]);
break;
case GLMessage::glGetAttribLocation:
case GLMessage::glGetUniformLocation:
/* int glGetAttribLocation(GLuint program, const GLchar* name) */
/* int glGetUniformLocation(GLuint program, const GLchar* name) */
- fixup_CStringPtr(1, glmsg);
+ fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
break;
case GLMessage::glGetBooleanv:
- fixup_glGetBooleanv(glmsg);
+ fixup_glGetBooleanv(glmsg, pointersToFixup);
break;
case GLMessage::glGetFloatv:
- fixup_glGetFloatv(glmsg);
+ fixup_glGetFloatv(glmsg, pointersToFixup);
break;
case GLMessage::glGetIntegerv: /* void glGetIntegerv(GLenum pname, GLint *params); */
- fixup_GenericIntArray(1, 1, glmsg);
+ fixup_GenericIntArray(1, 1, glmsg, pointersToFixup[0]);
break;
case GLMessage::glGetProgramiv:
case GLMessage::glGetRenderbufferParameteriv:
@@ -438,70 +459,78 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
/* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */
/* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */
/* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */
- fixup_GenericIntArray(2, 1, glmsg);
+ fixup_GenericIntArray(2, 1, glmsg, pointersToFixup[0]);
break;
case GLMessage::glGetString:
- fixup_glGetString(glmsg);
+ fixup_glGetString(glmsg, pointersToFixup);
break;
case GLMessage::glTexImage2D:
if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
- fixup_glTexImage2D(glmsg);
+ fixup_glTexImage2D(glmsg, pointersToFixup);
}
break;
case GLMessage::glTexSubImage2D:
if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
- fixup_glTexSubImage2D(glmsg);
+ fixup_glTexSubImage2D(glmsg, pointersToFixup);
}
break;
case GLMessage::glShaderSource:
- fixup_glShaderSource(glmsg);
+ fixup_glShaderSource(glmsg, pointersToFixup);
break;
case GLMessage::glUniform1iv:
/* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
- fixup_glUniformGenericInteger(2, 1, glmsg);
+ fixup_glUniformGenericInteger(2, 1, glmsg, pointersToFixup);
break;
case GLMessage::glUniform2iv:
/* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
- fixup_glUniformGenericInteger(2, 2, glmsg);
+ fixup_glUniformGenericInteger(2, 2, glmsg, pointersToFixup);
break;
case GLMessage::glUniform3iv:
/* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
- fixup_glUniformGenericInteger(2, 3, glmsg);
+ fixup_glUniformGenericInteger(2, 3, glmsg, pointersToFixup);
break;
case GLMessage::glUniform4iv:
/* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
- fixup_glUniformGenericInteger(2, 4, glmsg);
+ fixup_glUniformGenericInteger(2, 4, glmsg, pointersToFixup);
break;
case GLMessage::glUniform1fv:
/* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
- fixup_glUniformGeneric(2, 1, glmsg);
+ fixup_glUniformGeneric(2, 1, glmsg, pointersToFixup[0]);
break;
case GLMessage::glUniform2fv:
/* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
- fixup_glUniformGeneric(2, 2, glmsg);
+ fixup_glUniformGeneric(2, 2, glmsg, pointersToFixup[0]);
break;
case GLMessage::glUniform3fv:
/* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
- fixup_glUniformGeneric(2, 3, glmsg);
+ fixup_glUniformGeneric(2, 3, glmsg, pointersToFixup[0]);
break;
case GLMessage::glUniform4fv:
/* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
- fixup_glUniformGeneric(2, 4, glmsg);
+ fixup_glUniformGeneric(2, 4, glmsg, pointersToFixup[0]);
break;
case GLMessage::glUniformMatrix2fv:
/* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat* value) */
- fixup_glUniformMatrixGeneric(2, glmsg);
+ fixup_glUniformMatrixGeneric(2, glmsg, pointersToFixup);
break;
case GLMessage::glUniformMatrix3fv:
/* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat* value) */
- fixup_glUniformMatrixGeneric(3, glmsg);
+ fixup_glUniformMatrixGeneric(3, glmsg, pointersToFixup);
break;
case GLMessage::glUniformMatrix4fv:
/* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat* value) */
- fixup_glUniformMatrixGeneric(4, glmsg);
+ fixup_glUniformMatrixGeneric(4, glmsg, pointersToFixup);
+ break;
+ case GLMessage::glBufferData:
+ /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
+ fixup_glBufferData(1, 2, glmsg, pointersToFixup);
+ break;
+ case GLMessage::glBufferSubData:
+ /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
+ fixup_glBufferData(2, 3, glmsg, pointersToFixup);
break;
case GLMessage::glDrawArrays:
/* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
@@ -517,11 +546,11 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
break;
case GLMessage::glPushGroupMarkerEXT:
/* void PushGroupMarkerEXT(sizei length, const char *marker); */
- fixup_CStringPtr(1, glmsg);
+ fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
break;
case GLMessage::glInsertEventMarkerEXT:
/* void InsertEventMarkerEXT(sizei length, const char *marker); */
- fixup_CStringPtr(1, glmsg);
+ fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
break;
default:
break;
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.h b/opengl/libs/GLES_trace/src/gltrace_fixup.h
index f63b0569036e..fe301254d6ed 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.h
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.h
@@ -27,7 +27,7 @@ namespace gltrace {
void fixupGLMessage(GLTraceContext *curContext, nsecs_t wallStart, nsecs_t wallEnd,
nsecs_t threadStart, nsecs_t threadEnd,
- GLMessage *message);
+ GLMessage *message, void *pointersToFixup[]);
void fixup_addFBContents(GLTraceContext *curContext, GLMessage *message, FBBinding fbToRead);
};
diff --git a/opengl/libs/GLES_trace/tools/genapi.py b/opengl/libs/GLES_trace/tools/genapi.py
index e1660be1aa3b..24034c13ec9f 100755
--- a/opengl/libs/GLES_trace/tools/genapi.py
+++ b/opengl/libs/GLES_trace/tools/genapi.py
@@ -92,8 +92,8 @@ GL2PROTOBUF_TYPE_MAP = {
"GLclampf":DataType.FLOAT,
"GLfixed":DataType.INT,
"GLclampx":DataType.INT,
- "GLsizeiptr":DataType.POINTER,
- "GLintptr":DataType.POINTER,
+ "GLsizeiptr":DataType.INT,
+ "GLintptr":DataType.INT,
"GLeglImageOES":DataType.POINTER,
}
@@ -180,9 +180,20 @@ TRACE_CALL_TEMPLATE = pyratemp.Template(
rt->$!retDataType.getProtobufCall()!$retValue);
<!--(end)-->
+ void *pointerArgs[] = {
+<!--(for argname, argtype in parsedArgs)-->
+ <!--(if argtype == DataType.POINTER)-->
+ (void *) $!argname!$,
+ <!--(end)-->
+<!--(end)-->
+<!--(if retDataType == DataType.POINTER)-->
+ (void *) retValue,
+<!--(end)-->
+ };
+
fixupGLMessage(glContext, wallStartTime, wallEndTime,
threadStartTime, threadEndTime,
- &glmsg);
+ &glmsg, pointerArgs);
glContext->traceGLMessage(&glmsg);
<!--(if retType != "void")-->
diff --git a/opengl/tests/angeles/Android.mk b/opengl/tests/angeles/Android.mk
index d0c3221cfba4..84b754b515c8 100644
--- a/opengl/tests/angeles/Android.mk
+++ b/opengl/tests/angeles/Android.mk
@@ -4,14 +4,7 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= app-linux.cpp demo.c.arm
LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
LOCAL_MODULE:= angeles
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
-
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= gpustate.c
-LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM
-LOCAL_MODULE:= gpustate
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp
index 4d10ee509924..6ac68a2aee45 100644
--- a/opengl/tests/angeles/app-linux.cpp
+++ b/opengl/tests/angeles/app-linux.cpp
@@ -53,7 +53,7 @@
#include <GLES/gl.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/angeles/gpustate.c b/opengl/tests/angeles/gpustate.c
deleted file mode 100644
index 3c540c9ca5fd..000000000000
--- a/opengl/tests/angeles/gpustate.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-static void *map_memory(const char *fn, unsigned base, unsigned size)
-{
- int fd;
- void *ptr;
-
- fd = open(fn, O_RDWR | O_SYNC);
- if(fd < 0) {
- perror("cannot open %s for mapping");
- return MAP_FAILED;
- }
-
- ptr = mmap(0, size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, base);
- close(fd);
-
- if(ptr == MAP_FAILED) {
- fprintf(stderr,"cannot map %s (@%08x,%08x)\n", fn, base, size);
- }
- return ptr;
-}
-
-
-int main(int argc, char** argv)
-{
- void *grp_regs = map_memory("/dev/hw3d", 0, 1024 * 1024);
- printf("GPU base mapped at %p\n", grp_regs);
- int state_offset = 0x10140;
- printf("GPU state = %08lx\n",
- *((long*)((char*)grp_regs + state_offset)) );
-
- return 0;
-}
diff --git a/opengl/tests/fillrate/Android.mk b/opengl/tests/fillrate/Android.mk
index 191c59b5abb3..835f858e5316 100644
--- a/opengl/tests/fillrate/Android.mk
+++ b/opengl/tests/fillrate/Android.mk
@@ -11,6 +11,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-fillrate
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/fillrate/fillrate.cpp b/opengl/tests/fillrate/fillrate.cpp
index 911d35469b1e..a708647a9a55 100644
--- a/opengl/tests/fillrate/fillrate.cpp
+++ b/opengl/tests/fillrate/fillrate.cpp
@@ -26,7 +26,7 @@
#include <utils/StopWatch.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/filter/Android.mk b/opengl/tests/filter/Android.mk
index a254127e7846..d780362b5d4f 100644
--- a/opengl/tests/filter/Android.mk
+++ b/opengl/tests/filter/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-filter
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/filter/filter.cpp b/opengl/tests/filter/filter.cpp
index 2351909743b0..00673275502b 100644
--- a/opengl/tests/filter/filter.cpp
+++ b/opengl/tests/filter/filter.cpp
@@ -6,7 +6,7 @@
#include <GLES/glext.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/finish/Android.mk b/opengl/tests/finish/Android.mk
index aa607c6a2788..8f4f9c399faa 100644
--- a/opengl/tests/finish/Android.mk
+++ b/opengl/tests/finish/Android.mk
@@ -11,6 +11,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-finish
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/finish/finish.cpp b/opengl/tests/finish/finish.cpp
index 91f5c45dde8f..11f0c22c3317 100644
--- a/opengl/tests/finish/finish.cpp
+++ b/opengl/tests/finish/finish.cpp
@@ -27,7 +27,7 @@
#include <utils/Timers.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/gl2_basic/Android.mk b/opengl/tests/gl2_basic/Android.mk
index a642eafef199..07469a06ed06 100644
--- a/opengl/tests/gl2_basic/Android.mk
+++ b/opengl/tests/gl2_basic/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-gl2_basic
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index f274c7c4ef9a..7007871dad45 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -27,7 +27,7 @@
#include <utils/Timers.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/gl2_copyTexImage/Android.mk b/opengl/tests/gl2_copyTexImage/Android.mk
index bef1f908b1f8..b6164284a2f6 100644
--- a/opengl/tests/gl2_copyTexImage/Android.mk
+++ b/opengl/tests/gl2_copyTexImage/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-gl2_copyTexImage
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
index c2bfdecfca10..988d7ac0ff37 100644
--- a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
+++ b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
@@ -27,7 +27,7 @@
#include <utils/Timers.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk
index 6304700f17f9..e36f319c55b1 100644
--- a/opengl/tests/gl2_yuvtex/Android.mk
+++ b/opengl/tests/gl2_yuvtex/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-gl2_yuvtex
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
index f0b8d1259a2c..d3e493263470 100644
--- a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
+++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
@@ -29,7 +29,7 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/gl_basic/Android.mk b/opengl/tests/gl_basic/Android.mk
index 6b6341fc3581..2ba327bfe36f 100644
--- a/opengl/tests/gl_basic/Android.mk
+++ b/opengl/tests/gl_basic/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-gl_basic
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index 0cc8398a4ada..23ce93480f28 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -6,7 +6,7 @@
#include <GLES/glext.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
#include <stdio.h>
diff --git a/opengl/tests/gl_perf/Android.mk b/opengl/tests/gl_perf/Android.mk
index 37647ca682c9..f32abd3b5a1e 100644
--- a/opengl/tests/gl_perf/Android.mk
+++ b/opengl/tests/gl_perf/Android.mk
@@ -11,6 +11,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-gl2_perf
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl_perf/gl2_perf.cpp b/opengl/tests/gl_perf/gl2_perf.cpp
index 9dfcf1cc0efe..224acafa7a99 100644
--- a/opengl/tests/gl_perf/gl2_perf.cpp
+++ b/opengl/tests/gl_perf/gl2_perf.cpp
@@ -27,7 +27,7 @@
#include <utils/Timers.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk
index a78db25571f0..5b87f2ee6e72 100644
--- a/opengl/tests/gl_yuvtex/Android.mk
+++ b/opengl/tests/gl_yuvtex/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-gl_yuvtex
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
index fbe65f12ed35..7a00f76f845b 100644
--- a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
+++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
@@ -29,7 +29,7 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp
index 1d039481cf2f..bb305dcafedf 100644
--- a/opengl/tests/hwc/hwcColorEquiv.cpp
+++ b/opengl/tests/hwc/hwcColorEquiv.cpp
@@ -87,7 +87,6 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
#define LOG_TAG "hwcColorEquivTest"
#include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp
index 66ccdae709d9..685dc5d0b85f 100644
--- a/opengl/tests/hwc/hwcCommit.cpp
+++ b/opengl/tests/hwc/hwcCommit.cpp
@@ -98,7 +98,6 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
#define LOG_TAG "hwcCommitTest"
#include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp
index 523e3dea7875..80cde23a7a77 100644
--- a/opengl/tests/hwc/hwcRects.cpp
+++ b/opengl/tests/hwc/hwcRects.cpp
@@ -106,7 +106,6 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
#define LOG_TAG "hwcRectsTest"
#include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp
index 1cefb4b8ff84..7d7bc1f9cc30 100644
--- a/opengl/tests/hwc/hwcStress.cpp
+++ b/opengl/tests/hwc/hwcStress.cpp
@@ -103,7 +103,6 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
#define LOG_TAG "hwcStressTest"
#include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcTestLib.cpp b/opengl/tests/hwc/hwcTestLib.cpp
index 925405e69a26..63f42bafc436 100644
--- a/opengl/tests/hwc/hwcTestLib.cpp
+++ b/opengl/tests/hwc/hwcTestLib.cpp
@@ -27,6 +27,8 @@
#include <hwc/hwcTestLib.h>
+#include "EGLUtils.h"
+
// Defines
#define NUMA(a) (sizeof(a) / sizeof(a [0]))
diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h
index 99ee60867da8..b0c301249113 100644
--- a/opengl/tests/hwc/hwcTestLib.h
+++ b/opengl/tests/hwc/hwcTestLib.h
@@ -29,7 +29,6 @@
#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
#include <utils/Log.h>
#include <testUtil.h>
diff --git a/libs/ui/EGLUtils.cpp b/opengl/tests/include/EGLUtils.h
index f24a71d88d9d..014c2611ae1f 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/opengl/tests/include/EGLUtils.h
@@ -15,21 +15,42 @@
*/
-#define LOG_TAG "EGLUtils"
+#ifndef ANDROID_UI_EGLUTILS_H
+#define ANDROID_UI_EGLUTILS_H
-#include <cutils/log.h>
-#include <utils/Errors.h>
-
-#include <ui/EGLUtils.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <system/window.h>
+#include <utils/Errors.h>
#include <EGL/egl.h>
-#include <private/ui/android_natives_priv.h>
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
+class EGLUtils
+{
+public:
+
+ static inline const char *strerror(EGLint err);
+
+ static inline status_t selectConfigForPixelFormat(
+ EGLDisplay dpy,
+ EGLint const* attrs,
+ int32_t format,
+ EGLConfig* outConfig);
+
+ static inline status_t selectConfigForNativeWindow(
+ EGLDisplay dpy,
+ EGLint const* attrs,
+ EGLNativeWindowType window,
+ EGLConfig* outConfig);
+};
+
+// ----------------------------------------------------------------------------
+
const char *EGLUtils::strerror(EGLint err)
{
switch (err){
@@ -55,7 +76,7 @@ const char *EGLUtils::strerror(EGLint err)
status_t EGLUtils::selectConfigForPixelFormat(
EGLDisplay dpy,
EGLint const* attrs,
- PixelFormat format,
+ int32_t format,
EGLConfig* outConfig)
{
EGLint numConfigs = -1, n=0;
@@ -65,7 +86,7 @@ status_t EGLUtils::selectConfigForPixelFormat(
if (outConfig == NULL)
return BAD_VALUE;
-
+
// Get all the "potential match" configs...
if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
@@ -75,7 +96,7 @@ status_t EGLUtils::selectConfigForPixelFormat(
free(configs);
return BAD_VALUE;
}
-
+
int i;
EGLConfig config = NULL;
for (i=0 ; i<n ; i++) {
@@ -88,7 +109,7 @@ status_t EGLUtils::selectConfigForPixelFormat(
}
free(configs);
-
+
if (i<n) {
*outConfig = config;
return NO_ERROR;
@@ -105,10 +126,10 @@ status_t EGLUtils::selectConfigForNativeWindow(
{
int err;
int format;
-
+
if (!window)
return BAD_VALUE;
-
+
if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) {
return err;
}
@@ -119,3 +140,5 @@ status_t EGLUtils::selectConfigForNativeWindow(
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
+
+#endif /* ANDROID_UI_EGLUTILS_H */
diff --git a/opengl/tests/include/glTestLib.h b/opengl/tests/include/glTestLib.h
index 06fbf5d54920..c91c5948828b 100644
--- a/opengl/tests/include/glTestLib.h
+++ b/opengl/tests/include/glTestLib.h
@@ -24,9 +24,7 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-//#include <ui/FramebufferNativeWindow.h>
-//#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
void glTestPrintGLString(const char *name, GLenum s);
void glTestCheckEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
diff --git a/opengl/tests/lib/glTestLib.cpp b/opengl/tests/lib/glTestLib.cpp
index 052cbd75cfd3..b434fc7efa02 100644
--- a/opengl/tests/lib/glTestLib.cpp
+++ b/opengl/tests/lib/glTestLib.cpp
@@ -26,7 +26,7 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
#include <utils/Log.h>
#include <testUtil.h>
diff --git a/opengl/tests/linetex/Android.mk b/opengl/tests/linetex/Android.mk
index 6ff248dcce34..261940e4eb40 100644
--- a/opengl/tests/linetex/Android.mk
+++ b/opengl/tests/linetex/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-linetex
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp
index 68429409403b..86694921c308 100644
--- a/opengl/tests/linetex/linetex.cpp
+++ b/opengl/tests/linetex/linetex.cpp
@@ -27,7 +27,7 @@
#include <utils/StopWatch.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/swapinterval/Android.mk b/opengl/tests/swapinterval/Android.mk
index 9a4145eb4874..d014cc94dbc0 100644
--- a/opengl/tests/swapinterval/Android.mk
+++ b/opengl/tests/swapinterval/Android.mk
@@ -11,6 +11,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-swapinterval
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/swapinterval/swapinterval.cpp b/opengl/tests/swapinterval/swapinterval.cpp
index 8ca031bef5d2..a0f4bc4663e5 100644
--- a/opengl/tests/swapinterval/swapinterval.cpp
+++ b/opengl/tests/swapinterval/swapinterval.cpp
@@ -24,7 +24,7 @@
#include <utils/StopWatch.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/textures/Android.mk b/opengl/tests/textures/Android.mk
index b2fa18557744..fe9f43c406ff 100644
--- a/opengl/tests/textures/Android.mk
+++ b/opengl/tests/textures/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-textures
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/textures/textures.cpp b/opengl/tests/textures/textures.cpp
index cbe8ffddc941..5d3d94e7dab9 100644
--- a/opengl/tests/textures/textures.cpp
+++ b/opengl/tests/textures/textures.cpp
@@ -23,7 +23,7 @@
#include <GLES/glext.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
using namespace android;
diff --git a/opengl/tests/tritex/Android.mk b/opengl/tests/tritex/Android.mk
index 6db3f49a99e1..fc544e44c9d3 100644
--- a/opengl/tests/tritex/Android.mk
+++ b/opengl/tests/tritex/Android.mk
@@ -10,6 +10,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv1_CM \
libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
LOCAL_MODULE:= test-opengl-tritex
LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/tritex/tritex.cpp b/opengl/tests/tritex/tritex.cpp
index 3365ab47ef47..f18348367d26 100644
--- a/opengl/tests/tritex/tritex.cpp
+++ b/opengl/tests/tritex/tritex.cpp
@@ -9,7 +9,7 @@
#include <GLES/glext.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 3a2ea65937ee..a08b99a01e87 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -22,7 +22,6 @@
<drawable name="notification_item_background_color_pressed">#ff257390</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
- <drawable name="status_bar_recents_background_solid">#b3000000</drawable>
<drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
<color name="status_bar_recents_app_label_color">#ffffffff</color>
<drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index cd8bd4ecd3be..14ce266c63db 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -236,10 +236,6 @@ public class SwipeHelper {
public void onAnimationEnd(Animator animation) {
mCallback.onChildDismissed(view);
animView.setLayerType(View.LAYER_TYPE_NONE, null);
- // Restore the alpha/translation parameters to what they were before swiping
- // (for when these items are recycled)
- animView.setAlpha(1f);
- setTranslation(animView, 0f);
}
});
anim.addUpdateListener(new AnimatorUpdateListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
index 78050a2abde4..deb5670da259 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
@@ -27,9 +27,5 @@ public interface RecentsCallback {
void handleOnClick(View selectedView);
void handleSwipe(View selectedView);
void handleLongPress(View selectedView, View anchorView, View thumbnailView);
- void handleShowBackground(boolean show);
void dismiss();
-
- // TODO: find another way to get this info from RecentsPanelView
- boolean isRecentsVisible();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 4718a1719dcb..76e6ee8975a6 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -181,6 +181,11 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
mLinearLayout.removeView(v);
mCallback.handleSwipe(v);
v.setActivated(false);
+ // Restore the alpha/translation parameters to what they were before swiping
+ // (for when these items are recycled)
+ View contentView = getChildContentView(v);
+ contentView.setAlpha(1f);
+ contentView.setTranslationY(0);
}
public void onBeginDrag(View v) {
@@ -212,14 +217,6 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
}
@Override
- protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (mPerformanceHelper != null) {
- mPerformanceHelper.onLayoutCallback();
- }
- }
-
- @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -322,12 +319,6 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
});
}
- public void onRecentsVisibilityChanged() {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.updateShowBackground();
- }
- }
-
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -374,9 +365,6 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
@Override
public void setLayoutTransition(LayoutTransition transition) {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.setLayoutTransitionCallback(transition);
- }
// The layout transition applies to our embedded LinearLayout
mLinearLayout.setLayoutTransition(transition);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 78967203e889..18132ffdea12 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -32,13 +32,14 @@ import android.net.Uri;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewRootImpl;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
@@ -325,18 +326,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
}
}
- public void handleShowBackground(boolean show) {
- if (show) {
- mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background_solid);
- } else {
- mRecentsScrim.setBackgroundDrawable(null);
- }
- }
-
- public boolean isRecentsVisible() {
- return getVisibility() == VISIBLE;
- }
-
public void onAnimationCancel(Animator animation) {
}
@@ -457,9 +446,15 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
mRecentsNoApps = findViewById(R.id.recents_no_apps);
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
- // In order to save space, we make the background texture repeat in the Y direction
- if (mRecentsScrim != null && mRecentsScrim.getBackground() instanceof BitmapDrawable) {
- ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
+ if (mRecentsScrim != null) {
+ Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay();
+ if (!ActivityManager.isHighEndGfx(d)) {
+ mRecentsScrim.setBackgroundDrawable(null);
+ } else if (mRecentsScrim.getBackground() instanceof BitmapDrawable) {
+ // In order to save space, we make the background texture repeat in the Y direction
+ ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
+ }
}
mPreloadTasksRunnable = new Runnable() {
@@ -478,21 +473,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
}
- @Override
- protected void onVisibilityChanged(View changedView, int visibility) {
- super.onVisibilityChanged(changedView, visibility);
- if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")");
-
- if (mRecentsContainer instanceof RecentsHorizontalScrollView) {
- ((RecentsHorizontalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
- } else if (mRecentsContainer instanceof RecentsVerticalScrollView) {
- ((RecentsVerticalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
- } else {
- throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
- }
- }
-
-
private void updateIcon(ViewHolder h, Drawable icon, boolean show, boolean anim) {
if (icon != null) {
h.iconView.setImageDrawable(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
index 813099adb076..5529d0caff16 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
@@ -78,39 +78,13 @@ public class RecentsScrollViewPerformanceHelper {
mScrollView.setVerticalFadingEdgeEnabled(false);
mScrollView.setHorizontalFadingEdgeEnabled(false);
}
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- mCallback = callback;
- mLinearLayout = layout;
- mAttachedToWindow = true;
- mBackgroundDrawable = mContext.getResources()
- .getDrawable(R.drawable.status_bar_recents_background_solid).getConstantState();
- updateShowBackground();
- }
-
}
public void addViewCallback(View newLinearLayoutChild) {
if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
final View view = newLinearLayoutChild;
- if (mShowBackground) {
- view.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
- view.setDrawingCacheEnabled(true);
- view.buildDrawingCache();
- } else {
- view.setBackgroundDrawable(null);
- view.setDrawingCacheEnabled(false);
- view.destroyDrawingCache();
- }
- }
- }
-
- public void onLayoutCallback() {
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- mScrollView.post(new Runnable() {
- public void run() {
- updateShowBackground();
- }
- });
+ view.setDrawingCacheEnabled(true);
+ view.buildDrawingCache();
}
}
@@ -118,37 +92,6 @@ public class RecentsScrollViewPerformanceHelper {
int left, int right, int top, int bottom, int scrollX, int scrollY,
float topFadingEdgeStrength, float bottomFadingEdgeStrength,
float leftFadingEdgeStrength, float rightFadingEdgeStrength) {
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- if (mIsVertical) {
- if (scrollY < 0) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(0, scrollY, mScrollView.getWidth(), 0);
- d.draw(canvas);
- } else {
- final int childHeight = mLinearLayout.getHeight();
- if (scrollY + mScrollView.getHeight() > childHeight) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(0, childHeight, mScrollView.getWidth(),
- scrollY + mScrollView.getHeight());
- d.draw(canvas);
- }
- }
- } else {
- if (scrollX < 0) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(scrollX, 0, 0, mScrollView.getHeight());
- d.draw(canvas);
- } else {
- final int childWidth = mLinearLayout.getWidth();
- if (scrollX + mScrollView.getWidth() > childWidth) {
- Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
- d.setBounds(childWidth, 0,
- scrollX + mScrollView.getWidth(), mScrollView.getHeight());
- d.draw(canvas);
- }
- }
- }
- }
if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
|| USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
@@ -241,64 +184,4 @@ public class RecentsScrollViewPerformanceHelper {
return mFadingEdgeLength;
}
- public void setLayoutTransitionCallback(LayoutTransition transition) {
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- if (transition != null) {
- transition.addTransitionListener(new LayoutTransition.TransitionListener() {
- @Override
- public void startTransition(LayoutTransition transition,
- ViewGroup container, View view, int transitionType) {
- updateShowBackground();
- }
-
- @Override
- public void endTransition(LayoutTransition transition,
- ViewGroup container, View view, int transitionType) {
- updateShowBackground();
- }
- });
- }
- }
- }
-
- // Turn on/off drawing the background in our ancestor, and turn on/off drawing
- // in the items in LinearLayout contained by this scrollview.
- // Moving the background drawing to our children, and turning on a drawing cache
- // for each of them, gives us a ~20fps gain when Recents is rendered in software
- public void updateShowBackground() {
- if (!mAttachedToWindow) {
- // We haven't been initialized yet-- we'll get called again when we are
- return;
- }
- if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
- LayoutTransition transition = mLinearLayout.getLayoutTransition();
- int linearLayoutSize =
- mIsVertical ? mLinearLayout.getHeight() : mLinearLayout.getWidth();
- int scrollViewSize =
- mIsVertical ? mScrollView.getHeight() : mScrollView.getWidth();
- boolean show = !mScrollView.isHardwareAccelerated() &&
- (linearLayoutSize > scrollViewSize) &&
- !(transition != null && transition.isRunning()) &&
- mCallback.isRecentsVisible();
-
- if (!mFirstTime && show == mShowBackground) return;
- mShowBackground = show;
- mFirstTime = false;
-
- mCallback.handleShowBackground(!show);
- for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
- View v = mLinearLayout.getChildAt(i);
- if (show) {
- v.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
- v.setDrawingCacheEnabled(true);
- v.buildDrawingCache();
- } else {
- v.setDrawingCacheEnabled(false);
- v.destroyDrawingCache();
- v.setBackgroundDrawable(null);
- }
- }
- }
- }
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 0605c4c039a2..1bfd0005fce1 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -187,6 +187,11 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
mLinearLayout.removeView(v);
mCallback.handleSwipe(v);
v.setActivated(false);
+ // Restore the alpha/translation parameters to what they were before swiping
+ // (for when these items are recycled)
+ View contentView = getChildContentView(v);
+ contentView.setAlpha(1f);
+ contentView.setTranslationX(0);
}
public void onBeginDrag(View v) {
@@ -219,14 +224,6 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
}
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (mPerformanceHelper != null) {
- mPerformanceHelper.onLayoutCallback();
- }
- }
-
- @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -329,12 +326,6 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
});
}
- public void onRecentsVisibilityChanged() {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.updateShowBackground();
- }
- }
-
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -382,9 +373,6 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
@Override
public void setLayoutTransition(LayoutTransition transition) {
- if (mPerformanceHelper != null) {
- mPerformanceHelper.setLayoutTransitionCallback(transition);
- }
// The layout transition applies to our embedded LinearLayout
mLinearLayout.setLayoutTransition(transition);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 3d904ee52bda..6fbcd64786c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -47,12 +47,13 @@ public class NotificationData {
}
private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() {
+ // sort first by score, then by when
public int compare(Entry a, Entry b) {
final StatusBarNotification na = a.notification;
final StatusBarNotification nb = b.notification;
- int priDiff = na.priority - nb.priority;
- return (priDiff != 0)
- ? priDiff
+ int d = na.score - nb.score;
+ return (d != 0)
+ ? d
: (int)(na.notification.when - nb.notification.when);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b3cef9063e39..b2d9e642608f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -102,6 +102,8 @@ public class PhoneStatusBar extends StatusBar {
public static final String ACTION_STATUSBAR_START
= "com.android.internal.policy.statusbar.START";
+ private static final boolean ENABLE_INTRUDERS = false;
+
static final int EXPANDED_LEAVE_ALONE = -10000;
static final int EXPANDED_FULL_OPEN = -10001;
@@ -232,6 +234,11 @@ public class PhoneStatusBar extends StatusBar {
private int mNavigationIconHints = 0;
+ // TODO(dsandler): codify this stuff in NotificationManager's header somewhere
+ private int mDisplayMinScore = Notification.PRIORITY_LOW * 10;
+ private int mIntruderMinScore = Notification.PRIORITY_HIGH * 10;
+ private int mIntruderInImmersiveMinScore = Notification.PRIORITY_HIGH * 10 + 5;
+
private class ExpandedDialog extends Dialog {
ExpandedDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Translucent_NoTitleBar);
@@ -263,7 +270,7 @@ public class PhoneStatusBar extends StatusBar {
addNavigationBar();
- //addIntruderView();
+ if (ENABLE_INTRUDERS) addIntruderView();
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext);
@@ -390,6 +397,9 @@ public class PhoneStatusBar extends StatusBar {
(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
if (ActivityManager.isHighEndGfx(mDisplay)) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ } else {
+ lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+ lp.dimAmount = 0.7f;
}
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
@@ -540,6 +550,7 @@ public class PhoneStatusBar extends StatusBar {
}
public void addNotification(IBinder key, StatusBarNotification notification) {
+ /* if (DEBUG) */ Slog.d(TAG, "addNotification score=" + notification.score);
StatusBarIconView iconView = addNotificationViews(key, notification);
if (iconView == null) return;
@@ -551,31 +562,31 @@ public class PhoneStatusBar extends StatusBar {
}
} catch (RemoteException ex) {
}
- if (immersive) {
- if ((notification.notification.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
- Slog.d(TAG, "Presenting high-priority notification in immersive activity");
- // special new transient ticker mode
- // 1. Populate mIntruderAlertView
-
- ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon);
- TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText);
- alertIcon.setImageDrawable(StatusBarIconView.getIcon(
- alertIcon.getContext(),
- iconView.getStatusBarIcon()));
- alertText.setText(notification.notification.tickerText);
-
- View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
- button.setOnClickListener(
- new NotificationClicker(notification.notification.contentIntent,
- notification.pkg, notification.tag, notification.id));
-
- // 2. Animate mIntruderAlertView in
- mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
-
- // 3. Set alarm to age the notification off (TODO)
- mHandler.removeMessages(MSG_HIDE_INTRUDER);
- mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
- }
+ if (ENABLE_INTRUDERS && (
+ (notification.score >= mIntruderInImmersiveMinScore)
+ || (!immersive && (notification.score > mIntruderMinScore)))) {
+ Slog.d(TAG, "Presenting high-priority notification");
+ // special new transient ticker mode
+ // 1. Populate mIntruderAlertView
+
+ ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon);
+ TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText);
+ alertIcon.setImageDrawable(StatusBarIconView.getIcon(
+ alertIcon.getContext(),
+ iconView.getStatusBarIcon()));
+ alertText.setText(notification.notification.tickerText);
+
+ View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content);
+ button.setOnClickListener(
+ new NotificationClicker(notification.notification.contentIntent,
+ notification.pkg, notification.tag, notification.id));
+
+ // 2. Animate mIntruderAlertView in
+ mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER);
+
+ // 3. Set alarm to age the notification off (TODO)
+ mHandler.removeMessages(MSG_HIDE_INTRUDER);
+ mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
} else if (notification.notification.fullScreenIntent != null) {
// not immersive & a full-screen alert should be shown
Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
@@ -632,8 +643,8 @@ public class PhoneStatusBar extends StatusBar {
&& oldContentView.getLayoutId() == contentView.getLayoutId();
ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
- && notification.priority == oldNotification.priority;
- // priority now encompasses isOngoing()
+ && notification.score == oldNotification.score;
+ // score now encompasses/supersedes isOngoing()
boolean updateTicker = notification.notification.tickerText != null
&& !TextUtils.equals(notification.notification.tickerText,
@@ -725,69 +736,6 @@ public class PhoneStatusBar extends StatusBar {
}
- View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
- Notification n = notification.notification;
- RemoteViews remoteViews = n.contentView;
- if (remoteViews == null) {
- return null;
- }
-
- // create the row view
- LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
-
- // wire up the veto button
- View vetoButton = updateNotificationVetoButton(row, notification);
- vetoButton.setContentDescription(mContext.getString(
- R.string.accessibility_remove_notification));
-
- // the large icon
- ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
- if (notification.notification.largeIcon != null) {
- largeIcon.setImageBitmap(notification.notification.largeIcon);
- } else {
- largeIcon.getLayoutParams().width = 0;
- largeIcon.setVisibility(View.INVISIBLE);
- }
-
- // bind the click event to the content area
- ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
- content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
- content.setOnFocusChangeListener(mFocusChangeListener);
- PendingIntent contentIntent = n.contentIntent;
- if (contentIntent != null) {
- final View.OnClickListener listener = new NotificationClicker(contentIntent,
- notification.pkg, notification.tag, notification.id);
- largeIcon.setOnClickListener(listener);
- content.setOnClickListener(listener);
- } else {
- largeIcon.setOnClickListener(null);
- content.setOnClickListener(null);
- }
-
- View expanded = null;
- Exception exception = null;
- try {
- expanded = remoteViews.apply(mContext, content);
- }
- catch (RuntimeException e) {
- exception = e;
- }
- if (expanded == null) {
- String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id);
- Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
- return null;
- } else {
- content.addView(expanded);
- row.setDrawingCacheEnabled(true);
- }
-
- applyLegacyRowBackground(notification, content);
-
- return new View[] { row, content, expanded };
- }
-
StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) {
if (DEBUG) {
Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
@@ -850,7 +798,7 @@ public class PhoneStatusBar extends StatusBar {
for (int i=0; i<toShow.size(); i++) {
View v = toShow.get(i);
if (v.getParent() == null) {
- mPile.addView(v, 0); // the notification shade has newest at the top
+ mPile.addView(v, i);
}
}
}
@@ -1807,7 +1755,7 @@ public class PhoneStatusBar extends StatusBar {
NotificationData.Entry e = mNotificationData.get(i);
pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
StatusBarNotification n = e.notification;
- pw.println(" pkg=" + n.pkg + " id=" + n.id + " priority=" + n.priority);
+ pw.println(" pkg=" + n.pkg + " id=" + n.id + " score=" + n.score);
pw.println(" notification=" + n.notification);
pw.println(" tickerText=\"" + n.notification.tickerText + "\"");
}
@@ -2317,6 +2265,30 @@ public class PhoneStatusBar extends StatusBar {
vib.vibrate(250);
}
+ public int getScoreThreshold() {
+ return mDisplayMinScore;
+ }
+
+ public void setScoreThreshold(int score) {
+ // XXX HAX
+ if (mDisplayMinScore != score) {
+ this.mDisplayMinScore = score;
+ applyScoreThreshold();
+ }
+ }
+
+ private void applyScoreThreshold() {
+ int N = mNotificationData.size();
+ for (int i=0; i<N; i++) {
+ NotificationData.Entry entry = mNotificationData.get(i);
+ int vis = (entry.notification.score < mDisplayMinScore)
+ ? View.GONE
+ : View.VISIBLE;
+ entry.row.setVisibility(vis);
+ entry.icon.setVisibility(vis);
+ }
+ }
+
Runnable mStartTracing = new Runnable() {
public void run() {
vibrate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index bb326fef461f..a60bba7ce106 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -99,13 +99,14 @@ public class LocationController extends BroadcastReceiver {
// Notification.Builder will helpfully fill these out for you no matter what you do
n.tickerView = null;
n.tickerText = null;
+
+ n.priority = Notification.PRIORITY_HIGH;
int[] idOut = new int[1];
- mNotificationService.enqueueNotificationWithTagPriority(
+ mNotificationService.enqueueNotificationWithTag(
mContext.getPackageName(),
null,
GPS_NOTIFICATION_ID,
- StatusBarNotification.PRIORITY_SYSTEM, // !!!1!one!!!
n,
idOut);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 5151cade488d..6e56cd4089b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -859,8 +859,8 @@ public class TabletStatusBar extends StatusBar implements
&& oldContentView.getLayoutId() == contentView.getLayoutId();
ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
- && notification.priority == oldNotification.priority;
- // priority now encompasses isOngoing()
+ && notification.score == oldNotification.score;
+ // score now encompasses/supersedes isOngoing()
boolean updateTicker = notification.notification.tickerText != null
&& !TextUtils.equals(notification.notification.tickerText,
oldEntry.notification.notification.tickerText);
@@ -1688,7 +1688,7 @@ public class TabletStatusBar extends StatusBar implements
mNotificationDNDDummyEntry = new NotificationData.Entry(
null,
- new StatusBarNotification("", 0, "", 0, 0, dndNotification),
+ new StatusBarNotification("", 0, "", 0, 0, Notification.PRIORITY_MAX, dndNotification),
iconView);
mIconLayout.addView(iconView, params);
diff --git a/packages/VpnDialogs/res/layout/manage.xml b/packages/VpnDialogs/res/layout/manage.xml
index ec710ffe20e5..56332c3bebeb 100644
--- a/packages/VpnDialogs/res/layout/manage.xml
+++ b/packages/VpnDialogs/res/layout/manage.xml
@@ -32,12 +32,12 @@
<TextView android:id="@+id/duration" style="@style/value"/>
</TableRow>
- <TableRow>
+ <TableRow android:id="@+id/data_transmitted_row" android:visibility="gone">
<TextView android:text="@string/data_transmitted" style="@style/label"/>
<TextView android:id="@+id/data_transmitted" style="@style/value"/>
</TableRow>
- <TableRow>
+ <TableRow android:id="@+id/data_received_row" android:visibility="gone">
<TextView android:text="@string/data_received" style="@style/label"/>
<TextView android:id="@+id/data_received" style="@style/value"/>
</TableRow>
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
index 1352e9b93716..3ff767ac7f9f 100644
--- a/packages/VpnDialogs/res/values/strings.xml
+++ b/packages/VpnDialogs/res/values/strings.xml
@@ -48,8 +48,6 @@
<!-- Label for the network usage of data received over VPN. [CHAR LIMIT=20] -->
<string name="data_received">Received:</string>
- <!-- Dummy string for a blank value. [CHAR LIMIT=40] -->
- <string name="blank_value">--</string>
<!-- Formatted string for the network usage over VPN. [CHAR LIMIT=40] -->
<string name="data_value_format">
<xliff:g id="number">%1$s</xliff:g> bytes /
diff --git a/packages/VpnDialogs/res/values/styles.xml b/packages/VpnDialogs/res/values/styles.xml
index e3469ec4f67e..0dda67302c28 100644
--- a/packages/VpnDialogs/res/values/styles.xml
+++ b/packages/VpnDialogs/res/values/styles.xml
@@ -25,6 +25,5 @@
<item name="android:gravity">center_vertical|left</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
- <item name="android:text">@string/blank_value</item>
</style>
</resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 2de02511d681..9999adb18bfc 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -50,6 +50,7 @@ public class ManageDialog extends AlertActivity implements
private TextView mDuration;
private TextView mDataTransmitted;
private TextView mDataReceived;
+ private boolean mDataRowsHidden;
private Handler mHandler;
@@ -76,6 +77,7 @@ public class ManageDialog extends AlertActivity implements
mDuration = (TextView) view.findViewById(R.id.duration);
mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
mDataReceived = (TextView) view.findViewById(R.id.data_received);
+ mDataRowsHidden = true;
if (mConfig.user.equals(VpnConfig.LEGACY_VPN)) {
mAlertParams.mIconId = android.R.drawable.ic_dialog_info;
@@ -140,8 +142,15 @@ public class ManageDialog extends AlertActivity implements
seconds / 3600, seconds / 60 % 60, seconds % 60));
}
- String[] numbers = getStatistics();
+ String[] numbers = getNumbers();
if (numbers != null) {
+ // First unhide the related data rows.
+ if (mDataRowsHidden) {
+ findViewById(R.id.data_transmitted_row).setVisibility(View.VISIBLE);
+ findViewById(R.id.data_received_row).setVisibility(View.VISIBLE);
+ mDataRowsHidden = false;
+ }
+
// [1] and [2] are received data in bytes and packets.
mDataReceived.setText(getString(R.string.data_value_format,
numbers[1], numbers[2]));
@@ -155,7 +164,7 @@ public class ManageDialog extends AlertActivity implements
return true;
}
- private String[] getStatistics() {
+ private String[] getNumbers() {
DataInputStream in = null;
try {
// See dev_seq_printf_stats() in net/core/dev.c.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c12a4b7e5917..8f35afb8ea09 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2285,13 +2285,21 @@ public class PhoneWindowManager implements WindowManagerPolicy {
"Laying out navigation bar window: (%d,%d - %d,%d)",
pf.left, pf.top, pf.right, pf.bottom));
}
- } else if (attrs.type == TYPE_SECURE_SYSTEM_OVERLAY
+ } else if ((attrs.type == TYPE_SECURE_SYSTEM_OVERLAY
+ || attrs.type == TYPE_BOOT_PROGRESS)
&& ((fl & FLAG_FULLSCREEN) != 0)) {
// Fullscreen secure system overlays get what they ask for.
pf.left = df.left = mUnrestrictedScreenLeft;
pf.top = df.top = mUnrestrictedScreenTop;
pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+ } else if (attrs.type == TYPE_BOOT_PROGRESS) {
+ // Boot progress screen always covers entire display.
+ pf.left = df.left = cf.left = mUnrestrictedScreenLeft;
+ pf.top = df.top = cf.top = mUnrestrictedScreenTop;
+ pf.right = df.right = cf.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+ pf.bottom = df.bottom = cf.bottom
+ = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
} else {
pf.left = df.left = cf.left = mRestrictedScreenLeft;
pf.top = df.top = cf.top = mRestrictedScreenTop;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 22fa7520ee1a..86692e7e1fb9 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -7,7 +7,6 @@ LOCAL_SRC_FILES:= \
AudioMixer.cpp.arm \
AudioResampler.cpp.arm \
AudioPolicyService.cpp \
- AudioBufferProvider.cpp \
ServiceUtilities.cpp
# AudioResamplerSinc.cpp.arm
# AudioResamplerCubic.cpp.arm
diff --git a/services/audioflinger/AudioBufferProvider.h b/services/audioflinger/AudioBufferProvider.h
index 62ad6bd727b8..43e4de755c96 100644
--- a/services/audioflinger/AudioBufferProvider.h
+++ b/services/audioflinger/AudioBufferProvider.h
@@ -17,8 +17,6 @@
#ifndef ANDROID_AUDIO_BUFFER_PROVIDER_H
#define ANDROID_AUDIO_BUFFER_PROVIDER_H
-#include <stdint.h>
-#include <sys/types.h>
#include <utils/Errors.h>
namespace android {
@@ -29,6 +27,7 @@ class AudioBufferProvider
public:
struct Buffer {
+ Buffer() : raw(NULL), frameCount(0) { }
union {
void* raw;
short* i16;
@@ -40,12 +39,12 @@ public:
virtual ~AudioBufferProvider() {}
// value representing an invalid presentation timestamp
- static const int64_t kInvalidPTS;
+ static const int64_t kInvalidPTS = 0x7FFFFFFFFFFFFFFFLL; // <stdint.h> is too painful
// pts is the local time when the next sample yielded by getNextBuffer
// will be rendered.
// Pass kInvalidPTS if the PTS is unknown or not applicable.
- virtual status_t getNextBuffer(Buffer* buffer, int64_t pts) = 0;
+ virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0;
virtual void releaseBuffer(Buffer* buffer) = 0;
};
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2243e354ea25..462c2fa9b454 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -232,7 +232,7 @@ void AudioFlinger::onFirstRef()
(NO_ERROR != dev->set_master_volume(dev, initialVolume))) {
mMasterVolumeSupportLvl = MVS_NONE;
}
- mHardwareStatus = AUDIO_HW_INIT;
+ mHardwareStatus = AUDIO_HW_IDLE;
}
// Set the mode for each audio HAL, and try to set the initial volume (if
@@ -254,7 +254,7 @@ void AudioFlinger::onFirstRef()
dev->set_master_volume(dev, initialVolume);
}
- mHardwareStatus = AUDIO_HW_INIT;
+ mHardwareStatus = AUDIO_HW_IDLE;
}
}
@@ -432,6 +432,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
audio_format_t format,
uint32_t channelMask,
int frameCount,
+ // FIXME dead, remove from IAudioFlinger
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
@@ -822,8 +823,6 @@ bool AudioFlinger::streamMute(audio_stream_type_t stream) const
status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
{
- status_t result;
-
ALOGV("setParameters(): io %d, keyvalue %s, tid %d, calling pid %d",
ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
// check calling permissions
@@ -833,15 +832,17 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
// ioHandle == 0 means the parameters are global to the audio hardware interface
if (ioHandle == 0) {
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_SET_PARAMETER;
status_t final_result = NO_ERROR;
+ {
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_SET_PARAMETER;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
audio_hw_device_t *dev = mAudioHwDevs[i];
- result = dev->set_parameters(dev, keyValuePairs.string());
+ status_t result = dev->set_parameters(dev, keyValuePairs.string());
final_result = result ?: final_result;
}
mHardwareStatus = AUDIO_HW_IDLE;
+ }
// disable AEC and NS if the device is a BT SCO headset supporting those pre processings
AudioParameter param = AudioParameter(keyValuePairs);
String8 value;
@@ -904,8 +905,14 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k
String8 out_s8;
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ char *s;
+ {
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_GET_PARAMETER;
audio_hw_device_t *dev = mAudioHwDevs[i];
- char *s = dev->get_parameters(dev, keys.string());
+ s = dev->get_parameters(dev, keys.string());
+ mHardwareStatus = AUDIO_HW_IDLE;
+ }
out_s8 += String8(s ? s : "");
free(s);
}
@@ -967,7 +974,7 @@ status_t AudioFlinger::setVoiceVolume(float value)
}
AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
+ mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
mHardwareStatus = AUDIO_HW_IDLE;
@@ -1022,12 +1029,7 @@ void AudioFlinger::removeNotificationClient(pid_t pid)
{
Mutex::Autolock _l(mLock);
- ssize_t index = mNotificationClients.indexOfKey(pid);
- if (index >= 0) {
- sp <NotificationClient> client = mNotificationClients.valueFor(pid);
- ALOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
- mNotificationClients.removeItem(pid);
- }
+ mNotificationClients.removeItem(pid);
ALOGV("%d died, releasing its sessions", pid);
size_t num = mAudioSessionRefs.size();
@@ -1932,10 +1934,66 @@ AudioFlinger::MixerThread::~MixerThread()
delete mAudioMixer;
}
+class CpuStats {
+public:
+ void sample();
+#ifdef DEBUG_CPU_USAGE
+private:
+ ThreadCpuUsage mCpu;
+#endif
+};
+
+void CpuStats::sample() {
+#ifdef DEBUG_CPU_USAGE
+ const CentralTendencyStatistics& stats = mCpu.statistics();
+ mCpu.sampleAndEnable();
+ unsigned n = stats.n();
+ // mCpu.elapsed() is expensive, so don't call it every loop
+ if ((n & 127) == 1) {
+ long long elapsed = mCpu.elapsed();
+ if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
+ double perLoop = elapsed / (double) n;
+ double perLoop100 = perLoop * 0.01;
+ double mean = stats.mean();
+ double stddev = stats.stddev();
+ double minimum = stats.minimum();
+ double maximum = stats.maximum();
+ mCpu.resetStatistics();
+ ALOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f",
+ elapsed * .000000001, n, perLoop * .000001,
+ mean * .001,
+ stddev * .001,
+ minimum * .001,
+ maximum * .001,
+ mean / perLoop100,
+ stddev / perLoop100,
+ minimum / perLoop100,
+ maximum / perLoop100);
+ }
+ }
+#endif
+};
+
+void AudioFlinger::PlaybackThread::checkSilentMode_l()
+{
+ if (!mMasterMute) {
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("ro.audio.silent", value, "0") > 0) {
+ char *endptr;
+ unsigned long ul = strtoul(value, &endptr, 0);
+ if (*endptr == '\0' && ul != 0) {
+ ALOGD("Silence is golden");
+ // The setprop command will not allow a property to be changed after
+ // the first time it is set, so we don't have to worry about un-muting.
+ setMasterMute_l(true);
+ }
+ }
+ }
+}
+
bool AudioFlinger::MixerThread::threadLoop()
{
Vector< sp<Track> > tracksToRemove;
- mixer_state mixerStatus = MIXER_IDLE;
nsecs_t standbyTime = systemTime();
size_t mixBufferSize = mFrameCount * mFrameSize;
// FIXME: Relaxed timing because of a certain device that can't meet latency
@@ -1950,45 +2008,16 @@ bool AudioFlinger::MixerThread::threadLoop()
uint32_t sleepTime = idleSleepTime;
uint32_t sleepTimeShift = 0;
Vector< sp<EffectChain> > effectChains;
-#ifdef DEBUG_CPU_USAGE
- ThreadCpuUsage cpu;
- const CentralTendencyStatistics& stats = cpu.statistics();
-#endif
+ CpuStats cpuStats;
acquireWakeLock();
while (!exitPending())
{
-#ifdef DEBUG_CPU_USAGE
- cpu.sampleAndEnable();
- unsigned n = stats.n();
- // cpu.elapsed() is expensive, so don't call it every loop
- if ((n & 127) == 1) {
- long long elapsed = cpu.elapsed();
- if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
- double perLoop = elapsed / (double) n;
- double perLoop100 = perLoop * 0.01;
- double mean = stats.mean();
- double stddev = stats.stddev();
- double minimum = stats.minimum();
- double maximum = stats.maximum();
- cpu.resetStatistics();
- ALOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f",
- elapsed * .000000001, n, perLoop * .000001,
- mean * .001,
- stddev * .001,
- minimum * .001,
- maximum * .001,
- mean / perLoop100,
- stddev / perLoop100,
- minimum / perLoop100,
- maximum / perLoop100);
- }
- }
-#endif
+ cpuStats.sample();
processConfigEvents();
- mixerStatus = MIXER_IDLE;
+ mixer_state mixerStatus = MIXER_IDLE;
{ // scope for mLock
Mutex::Autolock _l(mLock);
@@ -2024,20 +2053,13 @@ bool AudioFlinger::MixerThread::threadLoop()
releaseWakeLock_l();
// wait until we have something to do...
- ALOGV("MixerThread %p TID %d going to sleep", this, gettid());
+ ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
mWaitWorkCV.wait(mLock);
- ALOGV("MixerThread %p TID %d waking up", this, gettid());
+ ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
acquireWakeLock_l();
mPrevMixerStatus = MIXER_IDLE;
- if (!mMasterMute) {
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.audio.silent", value, "0");
- if (atoi(value)) {
- ALOGD("Silence is golden");
- setMasterMute_l(true);
- }
- }
+ checkSilentMode_l();
standbyTime = systemTime() + mStandbyTimeInNsecs;
sleepTime = idleSleepTime;
@@ -2166,7 +2188,7 @@ bool AudioFlinger::MixerThread::threadLoop()
releaseWakeLock();
- ALOGV("MixerThread %p exiting", this);
+ ALOGV("Thread %p type %d exiting", this, mType);
return false;
}
@@ -2684,7 +2706,6 @@ void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t ri
bool AudioFlinger::DirectOutputThread::threadLoop()
{
- mixer_state mixerStatus = MIXER_IDLE;
sp<Track> trackToRemove;
sp<Track> activeTrack;
nsecs_t standbyTime = systemTime();
@@ -2707,8 +2728,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
processConfigEvents();
- mixerStatus = MIXER_IDLE;
-
+ mixer_state mixerStatus = MIXER_IDLE;
{ // scope for the mLock
Mutex::Autolock _l(mLock);
@@ -2725,7 +2745,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
mSuspended)) {
// wait until we have something to do...
if (!mStandby) {
- ALOGV("Audio hardware entering standby, mixer %p", this);
+ ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d", this, mSuspended);
mOutput->stream->common.standby(&mOutput->stream->common);
mStandby = true;
mBytesWritten = 0;
@@ -2738,19 +2758,12 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
if (exitPending()) break;
releaseWakeLock_l();
- ALOGV("DirectOutputThread %p TID %d going to sleep", this, gettid());
+ ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
mWaitWorkCV.wait(mLock);
- ALOGV("DirectOutputThread %p TID %d waking up in active mode", this, gettid());
+ ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
acquireWakeLock_l();
- if (!mMasterMute) {
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.audio.silent", value, "0");
- if (atoi(value)) {
- ALOGD("Silence is golden");
- setMasterMute_l(true);
- }
- }
+ checkSilentMode_l();
standbyTime = systemTime() + standbyDelay;
sleepTime = idleSleepTime;
@@ -2895,8 +2908,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
// output audio to hardware
while (frameCount) {
buffer.frameCount = frameCount;
- activeTrack->getNextBuffer(&buffer,
- AudioBufferProvider::kInvalidPTS);
+ activeTrack->getNextBuffer(&buffer);
if (CC_UNLIKELY(buffer.raw == NULL)) {
memset(curBuf, 0, frameCount * mFrameSize);
break;
@@ -2969,7 +2981,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop()
releaseWakeLock();
- ALOGV("DirectOutputThread %p exiting", this);
+ ALOGV("Thread %p type %d exiting", this, mType);
return false;
}
@@ -3086,7 +3098,6 @@ AudioFlinger::DuplicatingThread::~DuplicatingThread()
bool AudioFlinger::DuplicatingThread::threadLoop()
{
Vector< sp<Track> > tracksToRemove;
- mixer_state mixerStatus = MIXER_IDLE;
nsecs_t standbyTime = systemTime();
size_t mixBufferSize = mFrameCount*mFrameSize;
SortedVector< sp<OutputTrack> > outputTracks;
@@ -3102,7 +3113,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
{
processConfigEvents();
- mixerStatus = MIXER_IDLE;
+ mixer_state mixerStatus = MIXER_IDLE;
{ // scope for the mLock
Mutex::Autolock _l(mLock);
@@ -3139,20 +3150,13 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
if (exitPending()) break;
releaseWakeLock_l();
- ALOGV("DuplicatingThread %p TID %d going to sleep", this, gettid());
+ // wait until we have something to do...
+ ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
mWaitWorkCV.wait(mLock);
- ALOGV("DuplicatingThread %p TID %d waking up", this, gettid());
+ ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
acquireWakeLock_l();
- mPrevMixerStatus = MIXER_IDLE;
- if (!mMasterMute) {
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.audio.silent", value, "0");
- if (atoi(value)) {
- ALOGD("Silence is golden");
- setMasterMute_l(true);
- }
- }
+ checkSilentMode_l();
standbyTime = systemTime() + mStandbyTimeInNsecs;
sleepTime = idleSleepTime;
@@ -3236,11 +3240,13 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
releaseWakeLock();
+ ALOGV("Thread %p type %d exiting", this, mType);
return false;
}
void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
{
+ Mutex::Autolock _l(mLock);
// FIXME explain this formula
int frameCount = (3 * mFrameCount * mSampleRate) / thread->sampleRate();
OutputTrack *outputTrack = new OutputTrack(thread,
@@ -3286,7 +3292,7 @@ void AudioFlinger::DuplicatingThread::updateWaitTime()
}
-bool AudioFlinger::DuplicatingThread::outputsReady(SortedVector< sp<OutputTrack> > &outputTracks)
+bool AudioFlinger::DuplicatingThread::outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks)
{
for (size_t i = 0; i < outputTracks.size(); i++) {
sp <ThreadBase> thread = outputTracks[i]->thread().promote();
@@ -3318,7 +3324,6 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
const sp<IMemory>& sharedBuffer,
int sessionId)
: RefBase(),
@@ -3330,7 +3335,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mFrameCount(0),
mState(IDLE),
mFormat(format),
- mFlags(flags & ~SYSTEM_FLAGS_MASK),
+ mStepServerFailed(false),
mSessionId(sessionId)
// mChannelCount
// mChannelMask
@@ -3410,11 +3415,14 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase()
}
}
+// AudioBufferProvider interface
+// getNextBuffer() = 0;
+// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack
void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
buffer->raw = NULL;
mFrameCount = buffer->frameCount;
- step();
+ (void) step(); // ignore return value of step()
buffer->frameCount = 0;
}
@@ -3425,7 +3433,7 @@ bool AudioFlinger::ThreadBase::TrackBase::step() {
result = cblk->stepServer(mFrameCount);
if (!result) {
ALOGV("stepServer failed acquiring cblk mutex");
- mFlags |= STEPSERVER_FAILED;
+ mStepServerFailed = true;
}
return result;
}
@@ -3437,7 +3445,7 @@ void AudioFlinger::ThreadBase::TrackBase::reset() {
cblk->server = 0;
cblk->userBase = 0;
cblk->serverBase = 0;
- mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
+ mStepServerFailed = false;
ALOGV("TrackBase::reset");
}
@@ -3477,7 +3485,7 @@ AudioFlinger::PlaybackThread::Track::Track(
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId)
- : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, 0, sharedBuffer, sessionId),
+ : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId),
mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL),
mAuxEffectId(0), mHasVolumeController(false)
{
@@ -3560,6 +3568,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
(int)mAuxBuffer);
}
+// AudioBufferProvider interface
status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
AudioBufferProvider::Buffer* buffer, int64_t pts)
{
@@ -3568,10 +3577,10 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
uint32_t framesReq = buffer->frameCount;
// Check if last stepServer failed, try to step now
- if (mFlags & TrackBase::STEPSERVER_FAILED) {
+ if (mStepServerFailed) {
if (!step()) goto getNextBuffer_exit;
ALOGV("stepServer recovered");
- mFlags &= ~TrackBase::STEPSERVER_FAILED;
+ mStepServerFailed = false;
}
framesReady = cblk->framesReady();
@@ -4108,6 +4117,7 @@ void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence(
mTimedAudioOutputOnTime = false;
}
+// AudioBufferProvider interface
void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
AudioBufferProvider::Buffer* buffer) {
@@ -4167,10 +4177,9 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack(
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
int sessionId)
: TrackBase(thread, client, sampleRate, format,
- channelMask, frameCount, flags, 0, sessionId),
+ channelMask, frameCount, 0 /*sharedBuffer*/, sessionId),
mOverflow(false)
{
if (mCblk != NULL) {
@@ -4193,6 +4202,7 @@ AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
}
}
+// AudioBufferProvider interface
status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
{
audio_track_cblk_t* cblk = this->cblk();
@@ -4200,10 +4210,10 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi
uint32_t framesReq = buffer->frameCount;
// Check if last stepServer failed, try to step now
- if (mFlags & TrackBase::STEPSERVER_FAILED) {
+ if (mStepServerFailed) {
if (!step()) goto getNextBuffer_exit;
ALOGV("stepServer recovered");
- mFlags &= ~TrackBase::STEPSERVER_FAILED;
+ mStepServerFailed = false;
}
framesAvail = cblk->framesAvailable_l();
@@ -4666,6 +4676,7 @@ sp<IAudioRecord> AudioFlinger::openRecord(
audio_format_t format,
uint32_t channelMask,
int frameCount,
+ // FIXME dead, remove from IAudioFlinger
uint32_t flags,
int *sessionId,
status_t *status)
@@ -4710,7 +4721,6 @@ sp<IAudioRecord> AudioFlinger::openRecord(
format,
channelMask,
frameCount,
- flags,
lSessionId,
&lStatus);
}
@@ -4880,8 +4890,7 @@ bool AudioFlinger::RecordThread::threadLoop()
}
buffer.frameCount = mFrameCount;
- if (CC_LIKELY(mActiveTrack->getNextBuffer(
- &buffer, AudioBufferProvider::kInvalidPTS) == NO_ERROR)) {
+ if (CC_LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
size_t framesOut = buffer.frameCount;
if (mResampler == NULL) {
// no resampling
@@ -5004,7 +5013,6 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
audio_format_t format,
int channelMask,
int frameCount,
- uint32_t flags,
int sessionId,
status_t *status)
{
@@ -5021,7 +5029,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
Mutex::Autolock _l(mLock);
track = new RecordTrack(this, client, sampleRate,
- format, channelMask, frameCount, flags, sessionId);
+ format, channelMask, frameCount, sessionId);
if (track->getCblk() == 0) {
lStatus = NO_MEMORY;
@@ -5159,6 +5167,7 @@ status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
return NO_ERROR;
}
+// AudioBufferProvider interface
status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
{
size_t framesReq = buffer->frameCount;
@@ -5197,6 +5206,7 @@ status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer*
return NO_ERROR;
}
+// AudioBufferProvider interface
void AudioFlinger::RecordThread::releaseBuffer(AudioBufferProvider::Buffer* buffer)
{
mRsmpInIndex += buffer->frameCount;
@@ -5441,7 +5451,6 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
{
status_t status;
PlaybackThread *thread = NULL;
- mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
uint32_t channels = pChannels ? *pChannels : 0;
@@ -5466,8 +5475,10 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
if (outHwDev == NULL)
return 0;
+ mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
status = outHwDev->open_output_stream(outHwDev, *pDevices, &format,
&channels, &samplingRate, &outStream);
+ mHardwareStatus = AUDIO_HW_IDLE;
ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
outStream,
samplingRate,
@@ -5475,7 +5486,6 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices,
channels,
status);
- mHardwareStatus = AUDIO_HW_IDLE;
if (outStream != NULL) {
AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
audio_io_handle_t id = nextUniqueId();
@@ -5867,7 +5877,7 @@ uint32_t AudioFlinger::nextUniqueId()
return android_atomic_inc(&mNextUniqueId);
}
-AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l()
+AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
{
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
@@ -5879,7 +5889,7 @@ AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l()
return NULL;
}
-uint32_t AudioFlinger::primaryOutputDevice_l()
+uint32_t AudioFlinger::primaryOutputDevice_l() const
{
PlaybackThread *thread = primaryPlaybackThread_l();
@@ -6374,7 +6384,7 @@ void AudioFlinger::ThreadBase::lockEffectChains_l(
}
void AudioFlinger::ThreadBase::unlockEffectChains(
- Vector<sp <AudioFlinger::EffectChain> >& effectChains)
+ const Vector<sp <AudioFlinger::EffectChain> >& effectChains)
{
for (size_t i = 0; i < effectChains.size(); i++) {
effectChains[i]->unlock();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1a52de5b67d7..e908d3f2d2ee 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -312,19 +312,12 @@ private:
PAUSED
};
- enum track_flags {
- STEPSERVER_FAILED = 0x01, // StepServer could not acquire cblk->lock mutex
- SYSTEM_FLAGS_MASK = 0x0000ffffUL,
- // The upper 16 bits are used for track-specific flags.
- };
-
TrackBase(ThreadBase *thread,
const sp<Client>& client,
uint32_t sampleRate,
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
const sp<IMemory>& sharedBuffer,
int sessionId);
virtual ~TrackBase();
@@ -346,9 +339,8 @@ private:
TrackBase(const TrackBase&);
TrackBase& operator = (const TrackBase&);
- virtual status_t getNextBuffer(
- AudioBufferProvider::Buffer* buffer,
- int64_t pts) = 0;
+ // AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts) = 0;
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
audio_format_t format() const {
@@ -384,7 +376,7 @@ private:
// we don't really need a lock for these
track_state mState;
const audio_format_t mFormat;
- uint32_t mFlags;
+ bool mStepServerFailed;
const int mSessionId;
uint8_t mChannelCount;
uint32_t mChannelMask;
@@ -431,8 +423,8 @@ private:
void sendConfigEvent_l(int event, int param = 0);
void processConfigEvents();
audio_io_handle_t id() const { return mId;}
- bool standby() { return mStandby; }
- uint32_t device() { return mDevice; }
+ bool standby() const { return mStandby; }
+ uint32_t device() const { return mDevice; }
virtual audio_stream_t* stream() = 0;
sp<EffectHandle> createEffect_l(
@@ -468,7 +460,7 @@ private:
// integrity of the chains during the process.
void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
// unlock effect chains after process
- void unlockEffectChains(Vector<sp <EffectChain> >& effectChains);
+ void unlockEffectChains(const Vector<sp<EffectChain> >& effectChains);
// set audio mode to all effect chains
void setMode(audio_mode_t mode);
// get effect module with corresponding ID on specified audio session
@@ -634,9 +626,10 @@ private:
Track(const Track&);
Track& operator = (const Track&);
- virtual status_t getNextBuffer(
- AudioBufferProvider::Buffer* buffer,
- int64_t pts);
+ // AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS);
+ // releaseBuffer() not overridden
+
virtual uint32_t framesReady() const;
bool isMuted() const { return mMute; }
@@ -703,9 +696,10 @@ private:
virtual uint32_t framesReady() const;
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
- int64_t pts);
+ // AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
void timedYieldSamples(AudioBufferProvider::Buffer* buffer);
void timedYieldSilence(uint32_t numFrames,
AudioBufferProvider::Buffer* buffer);
@@ -866,6 +860,9 @@ private:
virtual uint32_t idleSleepTimeUs() = 0;
virtual uint32_t suspendSleepTimeUs() = 0;
+ // Code snippets that are temporarily lifted up out of threadLoop() until the merge
+ void checkSilentMode_l();
+
private:
friend class AudioFlinger;
@@ -972,7 +969,7 @@ private:
virtual uint32_t activeSleepTimeUs();
private:
- bool outputsReady(SortedVector< sp<OutputTrack> > &outputTracks);
+ bool outputsReady(const SortedVector<sp<OutputTrack> > &outputTracks);
void updateWaitTime();
SortedVector < sp<OutputTrack> > mOutputTracks;
@@ -997,8 +994,9 @@ private:
PlaybackThread *srcThread,
PlaybackThread *dstThread,
bool reRegister);
- PlaybackThread *primaryPlaybackThread_l();
- uint32_t primaryOutputDevice_l();
+ // return thread associated with primary hardware device, or NULL
+ PlaybackThread *primaryPlaybackThread_l() const;
+ uint32_t primaryOutputDevice_l() const;
friend class AudioBuffer;
@@ -1048,7 +1046,6 @@ private:
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
int sessionId);
virtual ~RecordTrack();
@@ -1067,9 +1064,9 @@ private:
RecordTrack(const RecordTrack&);
RecordTrack& operator = (const RecordTrack&);
- virtual status_t getNextBuffer(
- AudioBufferProvider::Buffer* buffer,
- int64_t pts);
+ // AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS);
+ // releaseBuffer() not overridden
bool mOverflow;
};
@@ -1094,7 +1091,6 @@ private:
audio_format_t format,
int channelMask,
int frameCount,
- uint32_t flags,
int sessionId,
status_t *status);
@@ -1106,9 +1102,10 @@ private:
AudioStreamIn* clearInput();
virtual audio_stream_t* stream();
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
- int64_t pts);
+ // AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
virtual bool checkForNewParameters_l();
virtual String8 getParameters(const String8& keys);
virtual void audioConfigChanged_l(int event, int param = 0);
@@ -1537,25 +1534,27 @@ mutable Mutex mLock; // mutex for process, commands and handl
audio_hw_device_t* mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL
Vector<audio_hw_device_t*> mAudioHwDevs;
+ // for dump, indicates which hardware operation is currently in progress (but not stream ops)
enum hardware_call_state {
- AUDIO_HW_IDLE = 0,
- AUDIO_HW_INIT,
- AUDIO_HW_OUTPUT_OPEN,
- AUDIO_HW_OUTPUT_CLOSE,
- AUDIO_HW_INPUT_OPEN,
- AUDIO_HW_INPUT_CLOSE,
- AUDIO_HW_STANDBY,
- AUDIO_HW_SET_MASTER_VOLUME,
- AUDIO_HW_GET_ROUTING,
- AUDIO_HW_SET_ROUTING,
- AUDIO_HW_GET_MODE,
- AUDIO_HW_SET_MODE,
- AUDIO_HW_GET_MIC_MUTE,
- AUDIO_HW_SET_MIC_MUTE,
- AUDIO_SET_VOICE_VOLUME,
- AUDIO_SET_PARAMETER,
- AUDIO_HW_GET_INPUT_BUFFER_SIZE,
- AUDIO_HW_GET_MASTER_VOLUME,
+ AUDIO_HW_IDLE = 0, // no operation in progress
+ AUDIO_HW_INIT, // init_check
+ AUDIO_HW_OUTPUT_OPEN, // open_output_stream
+ AUDIO_HW_OUTPUT_CLOSE, // unused
+ AUDIO_HW_INPUT_OPEN, // unused
+ AUDIO_HW_INPUT_CLOSE, // unused
+ AUDIO_HW_STANDBY, // unused
+ AUDIO_HW_SET_MASTER_VOLUME, // set_master_volume
+ AUDIO_HW_GET_ROUTING, // unused
+ AUDIO_HW_SET_ROUTING, // unused
+ AUDIO_HW_GET_MODE, // unused
+ AUDIO_HW_SET_MODE, // set_mode
+ AUDIO_HW_GET_MIC_MUTE, // get_mic_mute
+ AUDIO_HW_SET_MIC_MUTE, // set_mic_mute
+ AUDIO_HW_SET_VOICE_VOLUME, // set_voice_volume
+ AUDIO_HW_SET_PARAMETER, // set_parameters
+ AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size
+ AUDIO_HW_GET_MASTER_VOLUME, // get_master_volume
+ AUDIO_HW_GET_PARAMETER, // get_parameters
};
mutable hardware_call_state mHardwareStatus; // for dump only
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 020d62afd99b..2cec525f19b5 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -332,11 +332,11 @@ size_t AudioMixer::getUnreleasedFrames(int name) const
return 0;
}
-void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
+void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
{
name -= TRACK0;
assert(uint32_t(name) < MAX_NUM_TRACKS);
- mState.tracks[name].bufferProvider = buffer;
+ mState.tracks[name].bufferProvider = bufferProvider;
}
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 2ac69f78eeec..87a08020b5be 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -21,8 +21,6 @@
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <utils/RefBase.h>
-#include <surfaceflinger/ISurface.h>
-#include <ui/android_native_buffer.h>
#include <ui/GraphicBuffer.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 06fc708e053d..adf1d4913af7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -29,10 +29,10 @@
#include <cutils/atomic.h>
#include <cutils/properties.h>
#include <gui/SurfaceTextureClient.h>
+#include <gui/Surface.h>
#include <hardware/hardware.h>
#include <media/AudioSystem.h>
#include <media/mediaplayer.h>
-#include <surfaceflinger/ISurface.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/String16.h>
diff --git a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
index 1055538c0030..e417b790d600 100644
--- a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -22,7 +22,6 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
-#include <surfaceflinger/ISurface.h>
#include <camera/Camera.h>
#include <camera/CameraParameters.h>
#include <ui/GraphicBuffer.h>
diff --git a/services/input/SpriteController.h b/services/input/SpriteController.h
index 50ae8a538869..75e4843d38dc 100644
--- a/services/input/SpriteController.h
+++ b/services/input/SpriteController.h
@@ -20,9 +20,7 @@
#include <utils/RefBase.h>
#include <utils/Looper.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
#include <SkBitmap.h>
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index 6665614244a0..da654387f435 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -39,8 +39,10 @@ import java.io.IOException;
public class BootReceiver extends BroadcastReceiver {
private static final String TAG = "BootReceiver";
- // Maximum size of a logged event (files get truncated if they're longer)
- private static final int LOG_SIZE = 65536;
+ // Maximum size of a logged event (files get truncated if they're longer).
+ // Give userdebug builds a larger max to capture extra debug, esp. for last_kmsg.
+ private static final int LOG_SIZE =
+ SystemProperties.getInt("ro.debuggable", 0) == 1 ? 98304 : 65536;
private static final File TOMBSTONE_DIR = new File("/data/tombstones");
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 86669f8df6e0..c70564658576 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -786,7 +786,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return flags;
}
- InputBindResult attachNewInputLocked(boolean initial, boolean needResult) {
+ InputBindResult attachNewInputLocked(boolean initial) {
if (!mBoundToMethod) {
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_BIND_INPUT, mCurMethod, mCurClient.binding));
@@ -804,14 +804,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
showCurrentInputLocked(getAppShowFlags(), null);
}
- return needResult
- ? new InputBindResult(session.session, mCurId, mCurSeq)
- : null;
+ return new InputBindResult(session.session, mCurId, mCurSeq);
}
InputBindResult startInputLocked(IInputMethodClient client,
- IInputContext inputContext, EditorInfo attribute,
- boolean initial, boolean needResult) {
+ IInputContext inputContext, EditorInfo attribute, int controlFlags) {
// If no method is currently selected, do nothing.
if (mCurMethodId == null) {
return mNoBinding;
@@ -837,6 +834,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} catch (RemoteException e) {
}
+ return startInputUncheckedLocked(cs, inputContext, attribute, controlFlags);
+ }
+
+ InputBindResult startInputUncheckedLocked(ClientState cs,
+ IInputContext inputContext, EditorInfo attribute, int controlFlags) {
+ // If no method is currently selected, do nothing.
+ if (mCurMethodId == null) {
+ return mNoBinding;
+ }
+
if (mCurClient != cs) {
// If the client is changing, we need to switch over to the new
// one.
@@ -867,7 +874,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (cs.curSession != null) {
// Fast case: if we are already connected to the input method,
// then just return it.
- return attachNewInputLocked(initial, needResult);
+ return attachNewInputLocked(
+ (controlFlags&InputMethodManager.CONTROL_START_INITIAL) != 0);
}
if (mHaveConnection) {
if (mCurMethod != null) {
@@ -948,13 +956,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@Override
public InputBindResult startInput(IInputMethodClient client,
- IInputContext inputContext, EditorInfo attribute,
- boolean initial, boolean needResult) {
+ IInputContext inputContext, EditorInfo attribute, int controlFlags) {
synchronized (mMethodMap) {
final long ident = Binder.clearCallingIdentity();
try {
- return startInputLocked(client, inputContext, attribute,
- initial, needResult);
+ return startInputLocked(client, inputContext, attribute, controlFlags);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -997,7 +1003,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mCurClient.curSession = new SessionState(mCurClient,
method, session);
mCurClient.sessionRequested = false;
- InputBindResult res = attachNewInputLocked(true, true);
+ InputBindResult res = attachNewInputLocked(true);
if (res.method != null) {
executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
MSG_BIND_METHOD, mCurClient.client, res));
@@ -1482,36 +1488,45 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
@Override
- public void windowGainedFocus(IInputMethodClient client, IBinder windowToken,
- boolean viewHasFocus, boolean isTextEditor, int softInputMode,
- boolean first, int windowFlags) {
+ public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
+ int controlFlags, int softInputMode, int windowFlags,
+ EditorInfo attribute, IInputContext inputContext) {
+ InputBindResult res = null;
long ident = Binder.clearCallingIdentity();
try {
synchronized (mMethodMap) {
if (DEBUG) Slog.v(TAG, "windowGainedFocus: " + client.asBinder()
- + " viewHasFocus=" + viewHasFocus
- + " isTextEditor=" + isTextEditor
+ + " controlFlags=#" + Integer.toHexString(controlFlags)
+ " softInputMode=#" + Integer.toHexString(softInputMode)
- + " first=" + first + " flags=#"
- + Integer.toHexString(windowFlags));
+ + " windowFlags=#" + Integer.toHexString(windowFlags));
- if (mCurClient == null || client == null
- || mCurClient.client.asBinder() != client.asBinder()) {
- try {
- // We need to check if this is the current client with
- // focus in the window manager, to allow this call to
- // be made before input is started in it.
- if (!mIWindowManager.inputMethodClientHasFocus(client)) {
- Slog.w(TAG, "Client not active, ignoring focus gain of: " + client);
- return;
- }
- } catch (RemoteException e) {
+ ClientState cs = mClients.get(client.asBinder());
+ if (cs == null) {
+ throw new IllegalArgumentException("unknown client "
+ + client.asBinder());
+ }
+
+ try {
+ if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) {
+ // Check with the window manager to make sure this client actually
+ // has a window with focus. If not, reject. This is thread safe
+ // because if the focus changes some time before or after, the
+ // next client receiving focus that has any interest in input will
+ // be calling through here after that change happens.
+ Slog.w(TAG, "Focus gain on non-focused client " + cs.client
+ + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+ return null;
}
+ } catch (RemoteException e) {
}
if (mCurFocusedWindow == windowToken) {
Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client);
- return;
+ if (attribute != null) {
+ return startInputUncheckedLocked(cs, inputContext, attribute,
+ controlFlags);
+ }
+ return null;
}
mCurFocusedWindow = windowToken;
@@ -1527,6 +1542,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
== WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
|| mRes.getConfiguration().isLayoutSizeAtLeast(
Configuration.SCREENLAYOUT_SIZE_LARGE);
+ final boolean isTextEditor =
+ (controlFlags&InputMethodManager.CONTROL_WINDOW_IS_TEXT_EDITOR) != 0;
+
+ // We want to start input before showing the IME, but after closing
+ // it. We want to do this after closing it to help the IME disappear
+ // more quickly (not get stuck behind it initializing itself for the
+ // new focused input, even if its window wants to hide the IME).
+ boolean didStart = false;
switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
@@ -1542,12 +1565,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
// There is a focus view, and we are navigating forward
// into the window, so show the input window for the user.
- // We only do this automatically if the window an resize
- // to accomodate the IME (so what the user sees will give
+ // We only do this automatically if the window can resize
+ // to accommodate the IME (so what the user sees will give
// them good context without input information being obscured
// by the IME) or if running on a large screen where there
// is more room for the target window + IME.
if (DEBUG) Slog.v(TAG, "Unspecified window will show input");
+ if (attribute != null) {
+ res = startInputUncheckedLocked(cs, inputContext, attribute,
+ controlFlags);
+ didStart = true;
+ }
showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
}
break;
@@ -1569,18 +1597,35 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if ((softInputMode &
WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
if (DEBUG) Slog.v(TAG, "Window asks to show input going forward");
+ if (attribute != null) {
+ res = startInputUncheckedLocked(cs, inputContext, attribute,
+ controlFlags);
+ didStart = true;
+ }
showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
}
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
if (DEBUG) Slog.v(TAG, "Window asks to always show input");
+ if (attribute != null) {
+ res = startInputUncheckedLocked(cs, inputContext, attribute,
+ controlFlags);
+ didStart = true;
+ }
showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
break;
}
+
+ if (!didStart && attribute != null) {
+ res = startInputUncheckedLocked(cs, inputContext, attribute,
+ controlFlags);
+ }
}
} finally {
Binder.restoreCallingIdentity(ident);
}
+
+ return res;
}
@Override
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index b3eceb10864c..624ee98a9c8c 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -146,19 +146,18 @@ public class NotificationManagerService extends INotificationManager.Stub
final int id;
final int uid;
final int initialPid;
- final int priority;
final Notification notification;
+ final int score;
IBinder statusBarKey;
- NotificationRecord(String pkg, String tag, int id, int uid, int initialPid, int priority,
- Notification notification)
+ NotificationRecord(String pkg, String tag, int id, int uid, int initialPid, int score, Notification notification)
{
this.pkg = pkg;
this.tag = tag;
this.id = id;
this.uid = uid;
this.initialPid = initialPid;
- this.priority = priority;
+ this.score = score;
this.notification = notification;
}
@@ -166,6 +165,8 @@ public class NotificationManagerService extends INotificationManager.Stub
pw.println(prefix + this);
pw.println(prefix + " icon=0x" + Integer.toHexString(notification.icon)
+ " / " + idDebugString(baseContext, this.pkg, notification.icon));
+ pw.println(prefix + " pri=" + notification.priority);
+ pw.println(prefix + " score=" + this.score);
pw.println(prefix + " contentIntent=" + notification.contentIntent);
pw.println(prefix + " deleteIntent=" + notification.deleteIntent);
pw.println(prefix + " tickerText=" + notification.tickerText);
@@ -187,7 +188,7 @@ public class NotificationManagerService extends INotificationManager.Stub
+ " pkg=" + pkg
+ " id=" + Integer.toHexString(id)
+ " tag=" + tag
- + " pri=" + priority
+ + " score=" + score
+ "}";
}
}
@@ -660,28 +661,17 @@ public class NotificationManagerService extends INotificationManager.Stub
enqueueNotificationInternal(pkg, Binder.getCallingUid(), Binder.getCallingPid(),
tag, id, notification, idOut);
}
-
- public void enqueueNotificationWithTagPriority(String pkg, String tag, int id, int priority,
- Notification notification, int[] idOut)
- {
- enqueueNotificationInternal(pkg, Binder.getCallingUid(), Binder.getCallingPid(),
- tag, id, priority, notification, idOut);
+
+ private final static int clamp(int x, int low, int high) {
+ return (x < low) ? low : ((x > high) ? high : x);
}
+
// Not exposed via Binder; for system use only (otherwise malicious apps could spoof the
// uid/pid of another application)
public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,
String tag, int id, Notification notification, int[] idOut)
{
- enqueueNotificationInternal(pkg, callingUid, callingPid, tag, id,
- ((notification.flags & Notification.FLAG_ONGOING_EVENT) != 0)
- ? StatusBarNotification.PRIORITY_ONGOING
- : StatusBarNotification.PRIORITY_NORMAL,
- notification, idOut);
- }
- public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,
- String tag, int id, int priority, Notification notification, int[] idOut)
- {
checkIncomingCall(pkg);
// Limit the number of notifications that any given package except the android
@@ -723,10 +713,35 @@ public class NotificationManagerService extends INotificationManager.Stub
}
}
+ // === Scoring ===
+
+ // 0. Sanitize inputs
+ notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN, Notification.PRIORITY_MAX);
+ // Migrate notification flags to scores
+ if (0 != (notification.flags & Notification.FLAG_HIGH_PRIORITY)) {
+ if (notification.priority < Notification.PRIORITY_MAX) notification.priority = Notification.PRIORITY_MAX;
+ } else if (0 != (notification.flags & Notification.FLAG_ONGOING_EVENT)) {
+ if (notification.priority < Notification.PRIORITY_HIGH) notification.priority = Notification.PRIORITY_HIGH;
+ }
+
+ // 1. initial score: buckets of 10, around the app
+ int score = notification.priority * 10; //[-20..20]
+
+ // 2. Consult oracles (external heuristics)
+ // TODO(dsandler): oracles
+
+ // 3. Apply local heuristics & overrides
+
+ // blocked apps
+ // TODO(dsandler): add block db
+ if (pkg.startsWith("com.test.spammer.")) {
+ score = -1000;
+ }
+
synchronized (mNotificationList) {
NotificationRecord r = new NotificationRecord(pkg, tag, id,
callingUid, callingPid,
- priority,
+ score,
notification);
NotificationRecord old = null;
@@ -752,9 +767,7 @@ public class NotificationManagerService extends INotificationManager.Stub
if (notification.icon != 0) {
StatusBarNotification n = new StatusBarNotification(pkg, id, tag,
- r.uid, r.initialPid, notification);
- n.priority = r.priority;
-
+ r.uid, r.initialPid, score, notification);
if (old != null && old.statusBarKey != null) {
r.statusBarKey = old.statusBarKey;
long identity = Binder.clearCallingIdentity();
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 455325af5156..c99aa026cf52 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1129,7 +1129,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
public float findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
long accessibilityNodeId, int interactionId,
- IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
+ IAccessibilityInteractionConnectionCallback callback, long interrogatingTid,
+ int prefetchFlags)
throws RemoteException {
final int resolvedWindowId = resolveAccessibilityWindowId(accessibilityWindowId);
IAccessibilityInteractionConnection connection = null;
@@ -1150,7 +1151,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
final long identityToken = Binder.clearCallingIdentity();
try {
connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
- interactionId, callback, interrogatingPid, interrogatingTid);
+ interactionId, callback, prefetchFlags, interrogatingPid, interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 71690157d40c..e471a3fa76b2 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1127,7 +1127,10 @@ public class PackageManagerService extends IPackageManager.Stub {
+ "; regranting permissions for internal storage");
mSettings.mInternalSdkPlatform = mSdkVersion;
- updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
+ updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
+ | (regrantPermissions
+ ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
+ : 0));
// can downgrade to reader
mSettings.writeLPr();
@@ -1473,7 +1476,7 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageInfo generatePackageInfo(PackageParser.Package p, int flags) {
if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
// The package has been uninstalled but has retained data and resources.
- return PackageParser.generatePackageInfo(p, null, flags, 0, 0);
+ return PackageParser.generatePackageInfo(p, null, flags, 0, 0, null);
}
final PackageSetting ps = (PackageSetting)p.mExtras;
if (ps == null) {
@@ -1481,7 +1484,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
return PackageParser.generatePackageInfo(p, gp.gids, flags,
- ps.firstInstallTime, ps.lastUpdateTime);
+ ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions);
}
public PackageInfo getPackageInfo(String packageName, int flags) {
@@ -1934,6 +1937,7 @@ public class PackageManagerService extends IPackageManager.Stub {
BasePermission bp = mSettings.mPermissions.get(info.name);
boolean added = bp == null;
boolean changed = true;
+ int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
if (added) {
bp = new BasePermission(info.name, tree.sourcePackage,
BasePermission.TYPE_DYNAMIC);
@@ -1942,16 +1946,17 @@ public class PackageManagerService extends IPackageManager.Stub {
"Not allowed to modify non-dynamic permission "
+ info.name);
} else {
- if (bp.protectionLevel == info.protectionLevel
+ if (bp.protectionLevel == fixedLevel
&& bp.perm.owner.equals(tree.perm.owner)
&& bp.uid == tree.uid
&& comparePermissionInfos(bp.perm.info, info)) {
changed = false;
}
}
- bp.protectionLevel = info.protectionLevel;
- bp.perm = new PackageParser.Permission(tree.perm.owner,
- new PermissionInfo(info));
+ bp.protectionLevel = fixedLevel;
+ info = new PermissionInfo(info);
+ info.protectionLevel = fixedLevel;
+ bp.perm = new PackageParser.Permission(tree.perm.owner, info);
bp.perm.info.packageName = tree.perm.info.packageName;
bp.uid = tree.uid;
if (added) {
@@ -1995,6 +2000,77 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ public void grantPermission(String packageName, String permissionName) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
+ synchronized (mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ final BasePermission bp = mSettings.mPermissions.get(permissionName);
+ if (bp == null) {
+ throw new IllegalArgumentException("Unknown permission: " + packageName);
+ }
+ if (!pkg.requestedPermissions.contains(permissionName)) {
+ throw new SecurityException("Package " + packageName
+ + " has not requested permission " + permissionName);
+ }
+ if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
+ throw new SecurityException("Permission " + permissionName
+ + " is not a development permission");
+ }
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null) {
+ return;
+ }
+ final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+ if (gp.grantedPermissions.add(permissionName)) {
+ if (ps.haveGids) {
+ gp.gids = appendInts(gp.gids, bp.gids);
+ }
+ mSettings.writeLPr();
+ }
+ }
+ }
+
+ public void revokePermission(String packageName, String permissionName) {
+ synchronized (mPackages) {
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
+ }
+ final BasePermission bp = mSettings.mPermissions.get(permissionName);
+ if (bp == null) {
+ throw new IllegalArgumentException("Unknown permission: " + packageName);
+ }
+ if (!pkg.requestedPermissions.contains(permissionName)) {
+ throw new SecurityException("Package " + packageName
+ + " has not requested permission " + permissionName);
+ }
+ if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
+ throw new SecurityException("Permission " + permissionName
+ + " is not a development permission");
+ }
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null) {
+ return;
+ }
+ final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+ if (gp.grantedPermissions.remove(permissionName)) {
+ gp.grantedPermissions.remove(permissionName);
+ if (ps.haveGids) {
+ gp.gids = removeInts(gp.gids, bp.gids);
+ }
+ mSettings.writeLPr();
+ }
+ }
+ }
+
public boolean isProtectedBroadcast(String actionName) {
synchronized (mPackages) {
return mProtectedBroadcasts.contains(actionName);
@@ -4117,10 +4193,13 @@ public class PackageManagerService extends IPackageManager.Stub {
}
return false;
}
-
+
+ static final int UPDATE_PERMISSIONS_ALL = 1<<0;
+ static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
+ static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
+
private void updatePermissionsLPw(String changingPkg,
- PackageParser.Package pkgInfo, boolean grantPermissions,
- boolean replace, boolean replaceAll) {
+ PackageParser.Package pkgInfo, int flags) {
// Make sure there are no dangling permission trees.
Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
while (it.hasNext()) {
@@ -4138,7 +4217,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
Slog.i(TAG, "Removing old permission tree: " + bp.name
+ " from package " + bp.sourcePackage);
- grantPermissions = true;
+ flags |= UPDATE_PERMISSIONS_ALL;
it.remove();
}
}
@@ -4178,7 +4257,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
Slog.i(TAG, "Removing old permission: " + bp.name
+ " from package " + bp.sourcePackage);
- grantPermissions = true;
+ flags |= UPDATE_PERMISSIONS_ALL;
it.remove();
}
}
@@ -4186,16 +4265,16 @@ public class PackageManagerService extends IPackageManager.Stub {
// Now update the permissions for all packages, in particular
// replace the granted permissions of the system packages.
- if (grantPermissions) {
+ if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
for (PackageParser.Package pkg : mPackages.values()) {
if (pkg != pkgInfo) {
- grantPermissionsLPw(pkg, replaceAll);
+ grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
}
}
}
if (pkgInfo != null) {
- grantPermissionsLPw(pkgInfo, replace);
+ grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
}
}
@@ -4205,11 +4284,13 @@ public class PackageManagerService extends IPackageManager.Stub {
return;
}
final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+ HashSet<String> origPermissions = gp.grantedPermissions;
boolean changedPermission = false;
if (replace) {
ps.permissionsFixed = false;
if (gp == ps) {
+ origPermissions = new HashSet<String>(gp.grantedPermissions);
gp.grantedPermissions.clear();
gp.gids = mGlobalGids;
}
@@ -4222,6 +4303,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final int N = pkg.requestedPermissions.size();
for (int i=0; i<N; i++) {
final String name = pkg.requestedPermissions.get(i);
+ //final boolean required = pkg.requestedPermssionsRequired.get(i);
final BasePermission bp = mSettings.mPermissions.get(name);
if (DEBUG_INSTALL) {
if (gp != ps) {
@@ -4232,23 +4314,23 @@ public class PackageManagerService extends IPackageManager.Stub {
final String perm = bp.name;
boolean allowed;
boolean allowedSig = false;
- if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL
- || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
+ final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+ if (level == PermissionInfo.PROTECTION_NORMAL
+ || level == PermissionInfo.PROTECTION_DANGEROUS) {
allowed = true;
} else if (bp.packageSetting == null) {
// This permission is invalid; skip it.
allowed = false;
- } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
- || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
+ } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
allowed = (compareSignatures(
bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH)
|| (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
== PackageManager.SIGNATURE_MATCH);
- if (!allowed && bp.protectionLevel
- == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
+ if (!allowed && (bp.protectionLevel
+ & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
if (isSystemApp(pkg)) {
- // For updated system applications, the signatureOrSystem permission
+ // For updated system applications, a system permission
// is granted only if it had been defined by the original application.
if (isUpdatedSystemApp(pkg)) {
final PackageSetting sysPs = mSettings
@@ -4265,6 +4347,16 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
+ if (!allowed && (bp.protectionLevel
+ & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
+ // For development permissions, a development permission
+ // is granted only if it was already granted.
+ if (origPermissions.contains(perm)) {
+ allowed = true;
+ } else {
+ allowed = false;
+ }
+ }
if (allowed) {
allowedSig = true;
}
@@ -4883,7 +4975,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
updatePermissionsLPw(p.packageName, p,
- p.permissions.size() > 0, false, false);
+ p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
}
addedPackage = p.applicationInfo.packageName;
addedUid = p.applicationInfo.uid;
@@ -6447,7 +6539,7 @@ public class PackageManagerService extends IPackageManager.Stub {
// writer
synchronized (mPackages) {
updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
- true, false, false);
+ UPDATE_PERMISSIONS_ALL);
// can downgrade to reader
mSettings.writeLPr();
}
@@ -6591,7 +6683,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
synchronized (mPackages) {
updatePermissionsLPw(newPackage.packageName, newPackage,
- newPackage.permissions.size() > 0, true, false);
+ UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
+ ? UPDATE_PERMISSIONS_ALL : 0));
res.name = pkgName;
res.uid = newPackage.applicationInfo.uid;
res.pkg = newPackage;
@@ -7019,7 +7112,7 @@ public class PackageManagerService extends IPackageManager.Stub {
outInfo.removedUid = mSettings.removePackageLPw(packageName);
}
if (deletedPs != null) {
- updatePermissionsLPw(deletedPs.name, null, false, false, false);
+ updatePermissionsLPw(deletedPs.name, null, 0);
if (deletedPs.sharedUser != null) {
// remove permissions associated with package
mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
@@ -7102,7 +7195,8 @@ public class PackageManagerService extends IPackageManager.Stub {
}
// writer
synchronized (mPackages) {
- updatePermissionsLPw(newPkg.packageName, newPkg, true, true, false);
+ updatePermissionsLPw(newPkg.packageName, newPkg,
+ UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
// can downgrade to reader here
if (writeSettings) {
mSettings.writeLPr();
@@ -8320,7 +8414,10 @@ public class PackageManagerService extends IPackageManager.Stub {
// Make sure group IDs have been assigned, and any permission
// changes in other apps are accounted for
- updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
+ updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
+ | (regrantPermissions
+ ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
+ : 0));
// can downgrade to reader
// Persist settings
mSettings.writeLPr();
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index ebf954bf398f..5da6ac9ec6ef 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1398,6 +1398,7 @@ final class Settings {
dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
bp.protectionLevel = readInt(parser, null, "protection",
PermissionInfo.PROTECTION_NORMAL);
+ bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
if (dynamic) {
PermissionInfo pi = new PermissionInfo();
pi.packageName = sourcePackage.intern();
@@ -2244,7 +2245,8 @@ final class Settings {
pw.print(" uid="); pw.print(p.uid);
pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
pw.print(" type="); pw.print(p.type);
- pw.print(" prot="); pw.println(p.protectionLevel);
+ pw.print(" prot=");
+ pw.println(PermissionInfo.protectionToString(p.protectionLevel));
if (p.packageSetting != null) {
pw.print(" packageSetting="); pw.println(p.packageSetting);
}
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
index a3293e8bbe87..a9d4e01aedb1 100644
--- a/services/java/com/android/server/wm/DimAnimator.java
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -180,7 +180,9 @@ class DimAnimator {
public void printTo(String prefix, PrintWriter pw) {
pw.print(prefix);
- pw.print("mDimSurface="); pw.println(mDimSurface);
+ pw.print("mDimSurface="); pw.print(mDimSurface);
+ pw.print(" "); pw.print(mLastDimWidth); pw.print(" x ");
+ pw.println(mLastDimHeight);
pw.print(prefix);
pw.print("mDimShown="); pw.print(mDimShown);
pw.print(" current="); pw.print(mDimCurrentAlpha);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index dafc6135229d..96142a1bb29e 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -7685,7 +7685,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- final boolean wasAnimating = w.mAnimating;
+ final boolean wasAnimating = w.mWasAnimating;
// If the window has moved due to its containing
// content frame changing, then we'd like to animate
@@ -8570,6 +8570,11 @@ public class WindowManagerService extends IWindowManager.Stub
if (mDimAnimator == null) {
mDimAnimator = new DimAnimator(mFxSession);
}
+ if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
+ mDimAnimator.show(mCurDisplayWidth, mCurDisplayHeight);
+ } else {
+ mDimAnimator.show(innerDw, innerDh);
+ }
mDimAnimator.show(innerDw, innerDh);
mDimAnimator.updateParameters(mContext.getResources(),
w, currentTime);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index d7a7cb0d34a3..fc435f71b482 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -91,6 +91,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mAttachedHidden; // is our parent window hidden?
boolean mLastHidden; // was this window last hidden?
boolean mWallpaperVisible; // for wallpaper, what was last vis report?
+ boolean mWasAnimating; // Were we animating going into the most recent animation step?
/**
* The window size that was requested by the application. These are in
@@ -979,6 +980,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// This must be called while inside a transaction. Returns true if
// there is more animation to run.
boolean stepAnimationLocked(long currentTime) {
+ // Save the animation state as it was before this step so WindowManagerService can tell if
+ // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
+ mWasAnimating = isAnimating();
if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
// We will run animations as long as the display isn't frozen.
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
index d2b3118d09a6..ce80c1f37066 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -25,8 +25,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Timers.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 986aec576a0f..9baae800ed96 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -26,14 +26,11 @@
#include <ui/PixelFormat.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
#include <GLES/gl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <pixelflinger/pixelflinger.h>
-
#include "DisplayHardware/DisplayHardware.h"
#include <hardware/gralloc.h>
@@ -60,6 +57,29 @@ void checkGLErrors()
static __attribute__((noinline))
void checkEGLErrors(const char* token)
{
+ struct EGLUtils {
+ static const char *strerror(EGLint err) {
+ switch (err){
+ case EGL_SUCCESS: return "EGL_SUCCESS";
+ case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
+ case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
+ case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
+ case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
+ case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
+ case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
+ case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+ case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
+ case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
+ case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+ case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+ case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
+ case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
+ case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
+ default: return "UNKNOWN";
+ }
+ }
+ };
+
EGLint error = eglGetError();
if (error && error != EGL_SUCCESS) {
ALOGE("%s: EGL error 0x%04x (%s)",
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 02be4dcba7fd..0a828b3dcfb0 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -27,8 +27,6 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <pixelflinger/pixelflinger.h>
-
#include "GLExtensions.h"
#include "DisplayHardware/DisplayHardwareBase.h"
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3e6b8725248d..df7fe5c49ecf 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
+#include <math.h>
#include <cutils/compiler.h>
#include <cutils/native_handle.h>
@@ -25,11 +28,12 @@
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/StopWatch.h>
+#include <utils/Trace.h>
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
#include "clz.h"
#include "DisplayHardware/DisplayHardware.h"
@@ -38,11 +42,9 @@
#include "Layer.h"
#include "SurfaceFlinger.h"
#include "SurfaceTextureLayer.h"
-#include <math.h>
#define DEBUG_RESIZE 0
-
namespace android {
// ---------------------------------------------------------------------------
@@ -55,7 +57,7 @@ Layer::Layer(SurfaceFlinger* flinger,
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
- mRefreshPending(0),
+ mRefreshPending(false),
mFrameLatencyNeeded(false),
mFrameLatencyOffset(0),
mFormat(PIXEL_FORMAT_NONE),
@@ -161,7 +163,10 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
// this surfaces pixel format
PixelFormatInfo info;
status_t err = getPixelFormatInfo(format, &info);
- if (err) return err;
+ if (err) {
+ ALOGE("unsupported pixelformat %d", format);
+ return err;
+ }
// the display's pixel format
const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -171,6 +176,7 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
// never allow a surface larger than what our underlying GL implementation
// can handle.
if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
+ ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
return BAD_VALUE;
}
@@ -264,6 +270,8 @@ void Layer::setPerFrameData(hwc_layer_t* hwcl) {
void Layer::onDraw(const Region& clip) const
{
+ ATRACE_CALL();
+
if (CC_UNLIKELY(mActiveBuffer == 0)) {
// the texture has not been created yet, this Layer has
// in fact never been drawn into. This happens frequently with
@@ -362,6 +370,8 @@ bool Layer::isProtected() const
uint32_t Layer::doTransaction(uint32_t flags)
{
+ ATRACE_CALL();
+
const Layer::State& front(drawingState());
const Layer::State& temp(currentState());
@@ -408,19 +418,15 @@ bool Layer::isCropped() const {
// pageflip handling...
// ----------------------------------------------------------------------------
-bool Layer::onPreComposition()
-{
- // if there was more than one pending update, request a refresh
- if (mRefreshPending >= 2) {
- mRefreshPending = 0;
- return true;
- }
- mRefreshPending = 0;
- return false;
+bool Layer::onPreComposition() {
+ mRefreshPending = false;
+ return mQueuedFrames > 0;
}
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
+ ATRACE_CALL();
+
if (mQueuedFrames > 0) {
// if we've already called updateTexImage() without going through
@@ -428,9 +434,11 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
// because we cannot call updateTeximage() without a corresponding
// compositionComplete() call.
// we'll trigger an update in onPreComposition().
- if (mRefreshPending++) {
+ if (mRefreshPending) {
+ mPostedDirtyRegion.clear();
return;
}
+ mRefreshPending = true;
// Capture the old state of the layer for comparisons later
const bool oldOpacity = isOpaque();
@@ -451,6 +459,12 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
mFrameLatencyNeeded = true;
+ if (oldActiveBuffer == NULL && mActiveBuffer != NULL) {
+ // the first time we receive a buffer, we need to trigger a
+ // geometry invalidation.
+ mFlinger->invalidateHwcGeometry();
+ }
+
const Rect crop(mSurfaceTexture->getCurrentCrop());
const uint32_t transform(mSurfaceTexture->getCurrentTransform());
const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
@@ -541,25 +555,25 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
void Layer::unlockPageFlip(
const Transform& planeTransform, Region& outDirtyRegion)
{
- if (mRefreshPending >= 2) {
- return;
- }
+ ATRACE_CALL();
- Region dirtyRegion(mPostedDirtyRegion);
- if (!dirtyRegion.isEmpty()) {
+ Region postedRegion(mPostedDirtyRegion);
+ if (!postedRegion.isEmpty()) {
mPostedDirtyRegion.clear();
- // The dirty region is given in the layer's coordinate space
- // transform the dirty region by the surface's transformation
- // and the global transformation.
- const Layer::State& s(drawingState());
- const Transform tr(planeTransform * s.transform);
- dirtyRegion = tr.transform(dirtyRegion);
-
- // At this point, the dirty region is in screen space.
- // Make sure it's constrained by the visible region (which
- // is in screen space as well).
- dirtyRegion.andSelf(visibleRegionScreen);
- outDirtyRegion.orSelf(dirtyRegion);
+ if (!visibleRegionScreen.isEmpty()) {
+ // The dirty region is given in the layer's coordinate space
+ // transform the dirty region by the surface's transformation
+ // and the global transformation.
+ const Layer::State& s(drawingState());
+ const Transform tr(planeTransform * s.transform);
+ postedRegion = tr.transform(postedRegion);
+
+ // At this point, the dirty region is in screen space.
+ // Make sure it's constrained by the visible region (which
+ // is in screen space as well).
+ postedRegion.andSelf(visibleRegionScreen);
+ outDirtyRegion.orSelf(postedRegion);
+ }
}
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index bf30608c9713..8d508c2eb64a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -22,10 +22,13 @@
#include <gui/SurfaceTexture.h>
-#include <pixelflinger/pixelflinger.h>
+#include <utils/Timers.h>
+
#include <ui/GraphicBuffer.h>
#include <ui/PixelFormat.h>
+#include <gui/ISurfaceComposerClient.h>
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
@@ -34,7 +37,6 @@
#include "LayerBase.h"
#include "SurfaceTextureLayer.h"
#include "Transform.h"
-#include <utils/Timers.h>
namespace android {
@@ -116,7 +118,7 @@ private:
uint32_t mCurrentTransform;
uint32_t mCurrentScalingMode;
bool mCurrentOpacity;
- size_t mRefreshPending;
+ bool mRefreshPending;
bool mFrameLatencyNeeded;
int mFrameLatencyOffset;
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index b8f7680b2b25..cd6efdd1fc8b 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -28,10 +28,9 @@
#include <ui/Region.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <private/surfaceflinger/LayerState.h>
+#include <gui/ISurfaceComposerClient.h>
-#include <pixelflinger/pixelflinger.h>
+#include <private/gui/LayerState.h>
#include <hardware/hwcomposer.h>
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9e3f54839574..42ed4fa91b66 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
@@ -39,18 +41,18 @@
#include <utils/String8.h>
#include <utils/String16.h>
#include <utils/StopWatch.h>
+#include <utils/Trace.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
-#include <pixelflinger/pixelflinger.h>
#include <GLES/gl.h>
#include "clz.h"
+#include "DdmConnection.h"
#include "DisplayEventConnection.h"
#include "EventThread.h"
#include "GLExtensions.h"
-#include "DdmConnection.h"
#include "Layer.h"
#include "LayerDim.h"
#include "LayerScreenshot.h"
@@ -60,7 +62,7 @@
#include "DisplayHardware/HWComposer.h"
#include <private/android_filesystem_config.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
+#include <private/gui/SharedBufferStack.h>
#define EGL_VERSION_HW_ANDROID 0x3143
@@ -403,6 +405,7 @@ bool SurfaceFlinger::threadLoop()
void SurfaceFlinger::onMessageReceived(int32_t what)
{
+ ATRACE_CALL();
switch (what) {
case MessageQueue::REFRESH: {
// case MessageQueue::INVALIDATE: {
@@ -738,6 +741,7 @@ void SurfaceFlinger::commitTransaction()
void SurfaceFlinger::handlePageFlip()
{
+ ATRACE_CALL();
const DisplayHardware& hw = graphicPlane(0).displayHardware();
const Region screenRegion(hw.bounds());
@@ -1000,6 +1004,12 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
drawWormhole();
}
+ // FIXME: workaroud for b/6020860
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ // end-workaround
+
/*
* and then, render the layers targeted at the framebuffer
*/
@@ -1279,7 +1289,7 @@ sp<ISurface> SurfaceFlinger::createSurface(
return surfaceHandle;
}
- //ALOGD("createSurface for pid %d (%d x %d)", pid, w, h);
+ //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
sp<Layer> normalLayer;
switch (flags & eFXSurfaceMask) {
case eFXSurfaceNormal:
@@ -1776,6 +1786,10 @@ status_t SurfaceFlinger::onTransact(
setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
return NO_ERROR;
}
+ case 1006:{ // send empty update
+ signalRefresh();
+ return NO_ERROR;
+ }
case 1008: // toggle use of hw composer
n = data.readInt32();
mDebugDisableHWC = n ? 1 : 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index fcd93615ff1a..b50787758612 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -33,9 +33,9 @@
#include <binder/IMemory.h>
#include <ui/PixelFormat.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceComposerClient.h>
#include "Barrier.h"
#include "Layer.h"
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 396a3fdf2b22..84ae0d957f33 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -17,9 +17,12 @@
#include <gtest/gtest.h>
#include <binder/IMemory.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <private/gui/ComposerService.h>
+
#include <utils/String8.h>
namespace android {
diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
index 7f3f0644c73a..c143b3d68c4c 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -22,9 +22,8 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
using namespace android;
diff --git a/services/surfaceflinger/tests/screencap/screencap.cpp b/services/surfaceflinger/tests/screencap/screencap.cpp
index 6cf150417314..53566e0ff76d 100644
--- a/services/surfaceflinger/tests/screencap/screencap.cpp
+++ b/services/surfaceflinger/tests/screencap/screencap.cpp
@@ -21,7 +21,7 @@
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>
-#include <surfaceflinger/ISurfaceComposer.h>
+#include <gui/ISurfaceComposer.h>
#include <SkImageEncoder.h>
#include <SkBitmap.h>
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index 9c15f9bb751a..a8878f7db1cb 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -22,9 +22,8 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
using namespace android;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 32a6975ed1cb..a9a5e905fb8c 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -64,44 +64,47 @@ public class ServiceState implements Parcelable {
/**
* Available radio technologies for GSM, UMTS and CDMA.
+ * Duplicates the constants from hardware/radio/include/ril.h
+ * This should only be used by agents working with the ril. Others
+ * should use the equivalent TelephonyManager.NETWORK_TYPE_*
*/
/** @hide */
- public static final int RADIO_TECHNOLOGY_UNKNOWN = 0;
+ public static final int RIL_RADIO_TECHNOLOGY_UNKNOWN = 0;
/** @hide */
- public static final int RADIO_TECHNOLOGY_GPRS = 1;
+ public static final int RIL_RADIO_TECHNOLOGY_GPRS = 1;
/** @hide */
- public static final int RADIO_TECHNOLOGY_EDGE = 2;
+ public static final int RIL_RADIO_TECHNOLOGY_EDGE = 2;
/** @hide */
- public static final int RADIO_TECHNOLOGY_UMTS = 3;
+ public static final int RIL_RADIO_TECHNOLOGY_UMTS = 3;
/** @hide */
- public static final int RADIO_TECHNOLOGY_IS95A = 4;
+ public static final int RIL_RADIO_TECHNOLOGY_IS95A = 4;
/** @hide */
- public static final int RADIO_TECHNOLOGY_IS95B = 5;
+ public static final int RIL_RADIO_TECHNOLOGY_IS95B = 5;
/** @hide */
- public static final int RADIO_TECHNOLOGY_1xRTT = 6;
+ public static final int RIL_RADIO_TECHNOLOGY_1xRTT = 6;
/** @hide */
- public static final int RADIO_TECHNOLOGY_EVDO_0 = 7;
+ public static final int RIL_RADIO_TECHNOLOGY_EVDO_0 = 7;
/** @hide */
- public static final int RADIO_TECHNOLOGY_EVDO_A = 8;
+ public static final int RIL_RADIO_TECHNOLOGY_EVDO_A = 8;
/** @hide */
- public static final int RADIO_TECHNOLOGY_HSDPA = 9;
+ public static final int RIL_RADIO_TECHNOLOGY_HSDPA = 9;
/** @hide */
- public static final int RADIO_TECHNOLOGY_HSUPA = 10;
+ public static final int RIL_RADIO_TECHNOLOGY_HSUPA = 10;
/** @hide */
- public static final int RADIO_TECHNOLOGY_HSPA = 11;
+ public static final int RIL_RADIO_TECHNOLOGY_HSPA = 11;
/** @hide */
- public static final int RADIO_TECHNOLOGY_EVDO_B = 12;
+ public static final int RIL_RADIO_TECHNOLOGY_EVDO_B = 12;
/** @hide */
- public static final int RADIO_TECHNOLOGY_EHRPD = 13;
+ public static final int RIL_RADIO_TECHNOLOGY_EHRPD = 13;
/** @hide */
- public static final int RADIO_TECHNOLOGY_LTE = 14;
+ public static final int RIL_RADIO_TECHNOLOGY_LTE = 14;
/** @hide */
- public static final int RADIO_TECHNOLOGY_HSPAP = 15;
+ public static final int RIL_RADIO_TECHNOLOGY_HSPAP = 15;
/**
* GSM radio technology only supports voice. It does not support data.
* @hide
*/
- public static final int RADIO_TECHNOLOGY_GSM = 16;
+ public static final int RIL_RADIO_TECHNOLOGY_GSM = 16;
/**
* Available registration states for GSM, UMTS and CDMA.
@@ -400,59 +403,59 @@ public class ServiceState implements Parcelable {
*
* @hide
*/
- public static String radioTechnologyToString(int rt) {
+ public static String rilRadioTechnologyToString(int rt) {
String rtString;
switch(rt) {
- case 0:
+ case RIL_RADIO_TECHNOLOGY_UNKNOWN:
rtString = "Unknown";
break;
- case 1:
+ case RIL_RADIO_TECHNOLOGY_GPRS:
rtString = "GPRS";
break;
- case 2:
+ case RIL_RADIO_TECHNOLOGY_EDGE:
rtString = "EDGE";
break;
- case 3:
+ case RIL_RADIO_TECHNOLOGY_UMTS:
rtString = "UMTS";
break;
- case 4:
+ case RIL_RADIO_TECHNOLOGY_IS95A:
rtString = "CDMA-IS95A";
break;
- case 5:
+ case RIL_RADIO_TECHNOLOGY_IS95B:
rtString = "CDMA-IS95B";
break;
- case 6:
+ case RIL_RADIO_TECHNOLOGY_1xRTT:
rtString = "1xRTT";
break;
- case 7:
+ case RIL_RADIO_TECHNOLOGY_EVDO_0:
rtString = "EvDo-rev.0";
break;
- case 8:
+ case RIL_RADIO_TECHNOLOGY_EVDO_A:
rtString = "EvDo-rev.A";
break;
- case 9:
+ case RIL_RADIO_TECHNOLOGY_HSDPA:
rtString = "HSDPA";
break;
- case 10:
+ case RIL_RADIO_TECHNOLOGY_HSUPA:
rtString = "HSUPA";
break;
- case 11:
+ case RIL_RADIO_TECHNOLOGY_HSPA:
rtString = "HSPA";
break;
- case 12:
+ case RIL_RADIO_TECHNOLOGY_EVDO_B:
rtString = "EvDo-rev.B";
break;
- case 13:
+ case RIL_RADIO_TECHNOLOGY_EHRPD:
rtString = "eHRPD";
break;
- case 14:
+ case RIL_RADIO_TECHNOLOGY_LTE:
rtString = "LTE";
break;
- case 15:
+ case RIL_RADIO_TECHNOLOGY_HSPAP:
rtString = "HSPAP";
break;
- case 16:
+ case RIL_RADIO_TECHNOLOGY_GSM:
rtString = "GSM";
break;
default:
@@ -460,12 +463,12 @@ public class ServiceState implements Parcelable {
Log.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
break;
}
- return rtString + ":" + rt;
+ return rtString;
}
@Override
public String toString() {
- String radioTechnology = radioTechnologyToString(mRadioTechnology);
+ String radioTechnology = rilRadioTechnologyToString(mRadioTechnology);
return (mState + " " + (mRoaming ? "roaming" : "home")
+ " " + mOperatorAlphaLong
@@ -644,9 +647,50 @@ public class ServiceState implements Parcelable {
}
/** @hide */
- public int getRadioTechnology() {
+ public int getRilRadioTechnology() {
return this.mRadioTechnology;
}
+ /** @hide */
+ public int getRadioTechnology() {
+ return getRilRadioTechnology();
+ }
+
+ /** @hide */
+ public int getNetworkType() {
+ switch(mRadioTechnology) {
+ case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
+ return TelephonyManager.NETWORK_TYPE_GPRS;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
+ return TelephonyManager.NETWORK_TYPE_EDGE;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
+ return TelephonyManager.NETWORK_TYPE_UMTS;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
+ return TelephonyManager.NETWORK_TYPE_HSDPA;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
+ return TelephonyManager.NETWORK_TYPE_HSUPA;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
+ return TelephonyManager.NETWORK_TYPE_HSPA;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A:
+ case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B:
+ return TelephonyManager.NETWORK_TYPE_CDMA;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
+ return TelephonyManager.NETWORK_TYPE_1xRTT;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
+ return TelephonyManager.NETWORK_TYPE_EVDO_0;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
+ return TelephonyManager.NETWORK_TYPE_EVDO_A;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
+ return TelephonyManager.NETWORK_TYPE_EVDO_B;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
+ return TelephonyManager.NETWORK_TYPE_EHRPD;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
+ return TelephonyManager.NETWORK_TYPE_LTE;
+ case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
+ return TelephonyManager.NETWORK_TYPE_HSPAP;
+ default:
+ return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+ }
+ }
/** @hide */
public int getCssIndicator() {
@@ -665,25 +709,25 @@ public class ServiceState implements Parcelable {
/** @hide */
public static boolean isGsm(int radioTechnology) {
- return radioTechnology == RADIO_TECHNOLOGY_GPRS
- || radioTechnology == RADIO_TECHNOLOGY_EDGE
- || radioTechnology == RADIO_TECHNOLOGY_UMTS
- || radioTechnology == RADIO_TECHNOLOGY_HSDPA
- || radioTechnology == RADIO_TECHNOLOGY_HSUPA
- || radioTechnology == RADIO_TECHNOLOGY_HSPA
- || radioTechnology == RADIO_TECHNOLOGY_LTE
- || radioTechnology == RADIO_TECHNOLOGY_HSPAP
- || radioTechnology == RADIO_TECHNOLOGY_GSM;
+ return radioTechnology == RIL_RADIO_TECHNOLOGY_GPRS
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_EDGE
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_UMTS
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_HSDPA
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_HSUPA
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM;
}
/** @hide */
public static boolean isCdma(int radioTechnology) {
- return radioTechnology == RADIO_TECHNOLOGY_IS95A
- || radioTechnology == RADIO_TECHNOLOGY_IS95B
- || radioTechnology == RADIO_TECHNOLOGY_1xRTT
- || radioTechnology == RADIO_TECHNOLOGY_EVDO_0
- || radioTechnology == RADIO_TECHNOLOGY_EVDO_A
- || radioTechnology == RADIO_TECHNOLOGY_EVDO_B
- || radioTechnology == RADIO_TECHNOLOGY_EHRPD;
+ return radioTechnology == RIL_RADIO_TECHNOLOGY_IS95A
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_IS95B
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_1xRTT
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B
+ || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD;
}
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index d0e304fc1a79..238afbed320f 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -355,14 +355,14 @@ public abstract class DataConnection extends StateMachine {
if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
}
- protected int getRadioTechnology(int defaultRadioTechnology) {
- int radioTechnology;
+ protected int getRilRadioTechnology(int defaultRilRadioTechnology) {
+ int rilRadioTechnology;
if (mRilVersion < 6) {
- radioTechnology = defaultRadioTechnology;
+ rilRadioTechnology = defaultRilRadioTechnology;
} else {
- radioTechnology = phone.getServiceState().getRadioTechnology() + 2;
+ rilRadioTechnology = phone.getServiceState().getRilRadioTechnology() + 2;
}
- return radioTechnology;
+ return rilRadioTechnology;
}
/*
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 2b9fb913241c..fa90f1c3a4c8 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -40,6 +40,7 @@ import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -1167,15 +1168,14 @@ public abstract class DataConnectionTracker extends Handler {
}
protected String getReryConfig(boolean forDefault) {
- int rt = mPhone.getServiceState().getRadioTechnology();
-
- if ((rt == ServiceState.RADIO_TECHNOLOGY_IS95A) ||
- (rt == ServiceState.RADIO_TECHNOLOGY_IS95B) ||
- (rt == ServiceState.RADIO_TECHNOLOGY_1xRTT) ||
- (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_0) ||
- (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_A) ||
- (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_B) ||
- (rt == ServiceState.RADIO_TECHNOLOGY_EHRPD)) {
+ int nt = mPhone.getServiceState().getNetworkType();
+
+ if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) ||
+ (nt == TelephonyManager.NETWORK_TYPE_1xRTT) ||
+ (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) ||
+ (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
+ (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) ||
+ (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) {
// CDMA variant
return SystemProperties.get("ro.cdma.data_retry_config");
} else {
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 2931a0297657..1a8b3ca01ca2 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -149,7 +149,7 @@ public class PhoneProxy extends Handler implements Phone {
logd("LTE ON CDMA property is set. Switch to CDMALTEPhone" +
" newVoiceRadioTech = " + newVoiceRadioTech +
" Active Phone = " + mActivePhone.getPhoneName());
- newVoiceRadioTech = ServiceState.RADIO_TECHNOLOGY_1xRTT;
+ newVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT;
}
} else {
if ((ServiceState.isCdma(newVoiceRadioTech) &&
@@ -165,7 +165,7 @@ public class PhoneProxy extends Handler implements Phone {
}
}
- if (newVoiceRadioTech == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
+ if (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
// We need some voice phone object to be active always, so never
// delete the phone without anything to replace it with!
logd("Ignoring voice radio technology changed message. newVoiceRadioTech = Unknown."
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 9c80de7553b3..fd39e04ff34a 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -54,10 +54,10 @@ public abstract class ServiceStateTracker extends Handler {
protected boolean mDesiredPowerState;
/**
- * Values correspond to ServiceState.RADIO_TECHNOLOGY_ definitions.
+ * Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions.
*/
- protected int mRadioTechnology = 0;
- protected int mNewRadioTechnology = 0;
+ protected int mRilRadioTechnology = 0;
+ protected int mNewRilRadioTechnology = 0;
/**
* By default, strength polling is enabled. However, if we're
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index a93d94fbc284..64d018e2edba 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -86,7 +86,7 @@ public class CdmaDataConnection extends DataConnection {
Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
msg.obj = cp;
phone.mCM.setupDataCall(
- Integer.toString(getRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)),
+ Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)),
Integer.toString(dataProfile),
null, null, null,
Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP),
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 7da23d05e3d9..cad2e2258c3e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -185,19 +185,21 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
@Override
protected void pollStateDone() {
- // determine data NetworkType from both LET and CDMA SS
+ // determine data RadioTechnology from both LET and CDMA SS
if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
//in LTE service
- newNetworkType = mLteSS.getRadioTechnology();
+ mNewRilRadioTechnology = mLteSS.getRilRadioTechnology();
mNewDataConnectionState = mLteSS.getState();
- newSS.setRadioTechnology(newNetworkType);
- log("pollStateDone LTE/eHRPD STATE_IN_SERVICE newNetworkType = " + newNetworkType);
+ newSS.setRadioTechnology(mNewRilRadioTechnology);
+ log("pollStateDone LTE/eHRPD STATE_IN_SERVICE mNewRilRadioTechnology = " +
+ mNewRilRadioTechnology);
} else {
// LTE out of service, get CDMA Service State
- newNetworkType = newSS.getRadioTechnology();
- mNewDataConnectionState = radioTechnologyToDataServiceState(newNetworkType);
- log("pollStateDone CDMA STATE_IN_SERVICE newNetworkType = " + newNetworkType +
- " mNewDataConnectionState = " + mNewDataConnectionState);
+ mNewRilRadioTechnology = newSS.getRilRadioTechnology();
+ mNewDataConnectionState = radioTechnologyToDataServiceState(mNewRilRadioTechnology);
+ log("pollStateDone CDMA STATE_IN_SERVICE mNewRilRadioTechnology = " +
+ mNewRilRadioTechnology + " mNewDataConnectionState = " +
+ mNewDataConnectionState);
}
// TODO: Add proper support for LTE Only, we should be looking at
@@ -239,7 +241,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
boolean hasCdmaDataConnectionChanged =
mDataConnectionState != mNewDataConnectionState;
- boolean hasNetworkTypeChanged = networkType != newNetworkType;
+ boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
boolean hasChanged = !newSS.equals(ss);
@@ -251,20 +253,20 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
boolean has4gHandoff =
mNewDataConnectionState == ServiceState.STATE_IN_SERVICE &&
- (((networkType == ServiceState.RADIO_TECHNOLOGY_LTE) &&
- (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) ||
- ((networkType == ServiceState.RADIO_TECHNOLOGY_EHRPD) &&
- (newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE)));
+ (((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
+ (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
+ ((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
+ (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
boolean hasMultiApnSupport =
- (((newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE) ||
- (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) &&
- ((networkType != ServiceState.RADIO_TECHNOLOGY_LTE) &&
- (networkType != ServiceState.RADIO_TECHNOLOGY_EHRPD)));
+ (((mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
+ (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
+ ((mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
+ (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
boolean hasLostMultiApnSupport =
- ((newNetworkType >= ServiceState.RADIO_TECHNOLOGY_IS95A) &&
- (newNetworkType <= ServiceState.RADIO_TECHNOLOGY_EVDO_A));
+ ((mNewRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
+ (mNewRilRadioTechnology <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
if (DBG) {
log("pollStateDone:"
@@ -273,7 +275,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
+ " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
+ " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
+ " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
- + " hasNetworkTypeChanged = " + hasNetworkTypeChanged
+ + " hasRadioTechnologyChanged = " + hasRadioTechnologyChanged
+ " hasChanged=" + hasChanged
+ " hasRoamingOn=" + hasRoamingOn
+ " hasRoamingOff=" + hasRoamingOff
@@ -316,13 +318,14 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
newCellLoc = tcl;
mDataConnectionState = mNewDataConnectionState;
- networkType = newNetworkType;
+ mRilRadioTechnology = mNewRilRadioTechnology;
+ mNewRilRadioTechnology = 0;
newSS.setStateOutOfService(); // clean slate for next time
- if (hasNetworkTypeChanged) {
+ if (hasRadioTechnologyChanged) {
phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.radioTechnologyToString(networkType));
+ ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
}
if (hasRegistered) {
@@ -404,7 +407,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
mDetachedRegistrants.notifyRegistrants();
}
- if ((hasCdmaDataConnectionChanged || hasNetworkTypeChanged)) {
+ if ((hasCdmaDataConnectionChanged || hasRadioTechnologyChanged)) {
phone.notifyDataConnection(null);
}
@@ -446,7 +449,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4]
: -1;
- if (networkType == ServiceState.RADIO_TECHNOLOGY_LTE) {
+ if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
lteRssi = ints[offset+5];
lteRsrp = ints[offset+6];
lteRsrq = ints[offset+7];
@@ -454,7 +457,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
lteCqi = ints[offset+9];
}
- if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) {
+ if (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
evdoSnr, false);
} else {
@@ -476,7 +479,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
// Note: it needs to be confirmed which CDMA network types
// can support voice and data calls concurrently.
// For the time-being, the return value will be false.
- return (networkType == ServiceState.RADIO_TECHNOLOGY_LTE);
+ return (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 5115d76462a5..75f5d478e3af 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -86,12 +86,6 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
private int mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff",
NITZ_UPDATE_DIFF_DEFAULT);
- /**
- * Values correspond to ServiceState.RADIO_TECHNOLOGY_ definitions.
- */
- protected int networkType = 0;
- protected int newNetworkType = 0;
-
private boolean mCdmaRoaming = false;
private int mRoamingIndicator;
private boolean mIsInPrl;
@@ -556,10 +550,10 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
/**
* Determine data network type based on radio technology.
*/
- protected void setCdmaTechnology(int radioTechnology){
- mNewDataConnectionState = radioTechnologyToDataServiceState(radioTechnology);
- newSS.setRadioTechnology(radioTechnology);
- newNetworkType = radioTechnology;
+ protected void setCdmaTechnology(int radioTech){
+ mNewDataConnectionState = radioTechnologyToDataServiceState(radioTech);
+ newSS.setRadioTechnology(radioTech);
+ mNewRilRadioTechnology = radioTech;
}
/**
@@ -925,7 +919,7 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
boolean hasCdmaDataConnectionChanged =
mDataConnectionState != mNewDataConnectionState;
- boolean hasNetworkTypeChanged = networkType != newNetworkType;
+ boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
boolean hasChanged = !newSS.equals(ss);
@@ -955,15 +949,15 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
newCellLoc = tcl;
mDataConnectionState = mNewDataConnectionState;
- networkType = newNetworkType;
+ mRilRadioTechnology = mNewRilRadioTechnology;
// this new state has been applied - forget it until we get a new new state
- newNetworkType = 0;
+ mNewRilRadioTechnology = 0;
newSS.setStateOutOfService(); // clean slate for next time
- if (hasNetworkTypeChanged) {
+ if (hasRadioTechnologyChanged) {
phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.radioTechnologyToString(networkType));
+ ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
}
if (hasRegistered) {
@@ -1030,7 +1024,7 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
mDetachedRegistrants.notifyRegistrants();
}
- if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
+ if (hasCdmaDataConnectionChanged || hasRadioTechnologyChanged) {
phone.notifyDataConnection(null);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
index 425afe652758..b4e0775b5189 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
@@ -167,7 +167,7 @@ public final class GsmCallTracker extends CallTracker {
/**
* clirMode is one of the CLIR_ constants
*/
- Connection
+ synchronized Connection
dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
// note that this triggers call state changed notif
clearDisconnected();
@@ -406,7 +406,7 @@ public final class GsmCallTracker extends CallTracker {
}
}
- protected void
+ protected synchronized void
handlePollCalls(AsyncResult ar) {
List polledCalls;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 1f28280685c6..4956ef41ff8f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -100,7 +100,7 @@ public class GsmDataConnection extends DataConnection {
}
phone.mCM.setupDataCall(
- Integer.toString(getRadioTechnology(RILConstants.SETUP_DATA_TECH_GSM)),
+ Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_GSM)),
Integer.toString(mProfileId),
mApn.apn, mApn.user, mApn.password,
Integer.toString(authType),
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 66e948793a8c..d1873ebbf2c9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -2318,7 +2318,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
String operator = mPhone.mIccRecords.getOperatorNumeric();
- int radioTech = mPhone.getServiceState().getRadioTechnology();
+ int networkType = mPhone.getServiceState().getNetworkType();
if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
if (canSetPreferApn && mPreferredApn != null) {
@@ -2327,7 +2327,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
+ mPreferredApn.numeric + ":" + mPreferredApn);
}
if (mPreferredApn.numeric.equals(operator)) {
- if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
+ if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) {
apnList.add(mPreferredApn);
if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
return apnList;
@@ -2346,7 +2346,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (mAllApns != null) {
for (ApnSetting apn : mAllApns) {
if (apn.canHandleType(requestedApnType)) {
- if (apn.bearer == 0 || apn.bearer == radioTech) {
+ if (apn.bearer == 0 || apn.bearer == networkType) {
if (DBG) log("apn info : " +apn.toString());
apnList.add(apn);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 0ebeabedacfc..a4fb1d89e63c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -629,7 +629,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
newGPRSState = regCodeToServiceState(regState);
mDataRoaming = regCodeIsRoaming(regState);
- mNewRadioTechnology = type;
+ mNewRilRadioTechnology = type;
newSS.setRadioTechnology(type);
break;
@@ -746,8 +746,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
" mNewMaxDataCalls=" + mNewMaxDataCalls +
" oldReasonDataDenied=" + mReasonDataDenied +
" mNewReasonDataDenied=" + mNewReasonDataDenied +
- " oldType=" + ServiceState.radioTechnologyToString(mRadioTechnology) +
- " newType=" + ServiceState.radioTechnologyToString(mNewRadioTechnology));
+ " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
+ " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology));
}
boolean hasRegistered =
@@ -766,7 +766,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
gprsState == ServiceState.STATE_IN_SERVICE
&& newGPRSState != ServiceState.STATE_IN_SERVICE;
- boolean hasRadioTechnologyChanged = mRadioTechnology != mNewRadioTechnology;
+ boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
boolean hasChanged = !newSS.equals(ss);
@@ -800,11 +800,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
int cid = -1;
GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
if (loc != null) cid = loc.getCid();
- EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRadioTechnology,
- mNewRadioTechnology);
+ EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology,
+ mNewRilRadioTechnology);
if (DBG) {
- log("RAT switched " + ServiceState.radioTechnologyToString(mRadioTechnology) +
- " -> " + ServiceState.radioTechnologyToString(mNewRadioTechnology) +
+ log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
+ " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) +
" at cell " + cid);
}
}
@@ -812,16 +812,16 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
gprsState = newGPRSState;
mReasonDataDenied = mNewReasonDataDenied;
mMaxDataCalls = mNewMaxDataCalls;
- mRadioTechnology = mNewRadioTechnology;
+ mRilRadioTechnology = mNewRilRadioTechnology;
// this new state has been applied - forget it until we get a new new state
- mNewRadioTechnology = 0;
+ mNewRilRadioTechnology = 0;
newSS.setStateOutOfService(); // clean slate for next time
if (hasRadioTechnologyChanged) {
phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
- ServiceState.radioTechnologyToString(mRadioTechnology));
+ ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
}
if (hasRegistered) {
@@ -1246,7 +1246,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
* that could support voice and data simultaneously.
*/
public boolean isConcurrentVoiceAndDataAllowed() {
- return (mRadioTechnology >= ServiceState.RADIO_TECHNOLOGY_UMTS);
+ return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
}
/**
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 58680ea5dd49..351c771ca1d9 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -159,6 +159,18 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public void grantPermission(String packageName, String permissionName) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** @hide */
+ @Override
+ public void revokePermission(String packageName, String permissionName) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public int checkSignatures(String pkg1, String pkg2) {
throw new UnsupportedOperationException();
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index ed78daa3651e..b310d93d97de 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -568,6 +568,15 @@
</activity>
<activity
+ android:name="TextOnPathActivity"
+ android:label="_TextOnPath">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="PathsCacheActivity"
android:label="_PathsCache">
<intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
index b8ad823bf73a..9ab2a860f7cc 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
@@ -92,19 +92,24 @@ public class PathsCacheActivity extends Activity {
canvas.restore();
-// Path path = makePath();
-// int r = mRandom.nextInt(10);
-// if (r == 5 || r == 3) {
-// mPathList.add(path);
-// } else if (r == 9) {
-// mPathList.clear();
-// }
-//
-// canvas.save();
-// canvas.translate(550.0f + mRandom.nextInt(50), 60.0f + mRandom.nextInt(50));
-// canvas.drawPath(path, mMediumPaint);
-// canvas.restore();
-//
+ for (int i = 0; i < mRandom.nextInt(20); i++) {
+ Path path = makePath();
+ int r = mRandom.nextInt(10);
+ if (r == 5 || r == 3) {
+ mPathList.add(path);
+ }
+
+ canvas.save();
+ canvas.translate(450.0f + mRandom.nextInt(200), mRandom.nextInt(200));
+ canvas.drawPath(path, mMediumPaint);
+ canvas.restore();
+ }
+
+ int r = mRandom.nextInt(100);
+ if (r == 50) {
+ mPathList.clear();
+ }
+
invalidate();
}
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java
new file mode 100644
index 000000000000..b798ee702dfc
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class TextOnPathActivity extends Activity {
+ private Path mPath;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mPath = makePath();
+
+ final TextOnPathView view = new TextOnPathView(this);
+ setContentView(view);
+ }
+
+ private Path makePath() {
+ Path path = new Path();
+ buildPath(path);
+ return path;
+ }
+
+ private void buildPath(Path path) {
+ path.moveTo(0.0f, 0.0f);
+ path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f);
+ path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f);
+ path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f);
+ }
+
+ public class TextOnPathView extends View {
+ private static final String TEST_STRING = "Hello OpenGL renderer, text on path! ";
+
+ private final Paint mPaint;
+ private final String mText;
+
+ public TextOnPathView(Context c) {
+ super(c);
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(0xff000000);
+
+ StringBuilder builder = new StringBuilder(TEST_STRING.length() * 2);
+ for (int i = 0; i < 2; i++) {
+ builder.append(TEST_STRING);
+ }
+ mText = builder.toString();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.drawARGB(255, 255, 255, 255);
+
+ canvas.save();
+ canvas.translate(400.0f, 350.0f);
+ mPaint.setTextAlign(Paint.Align.LEFT);
+ canvas.drawTextOnPath(mText + mText, mPath, 0.0f, 0.0f, mPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(150.0f, 60.0f);
+ canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint);
+
+ canvas.translate(250.0f, 0.0f);
+ mPaint.setTextAlign(Paint.Align.CENTER);
+ canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint);
+
+ canvas.translate(250.0f, 0.0f);
+ mPaint.setTextAlign(Paint.Align.RIGHT);
+ canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png
new file mode 100644
index 000000000000..ff34a7ffcc4f
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
index fa468cc3620c..c34adc9e334d 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
@@ -3,13 +3,13 @@ varying vec2 varTex0;
void main() {
vec2 blurCoord = varTex0;
blurCoord.x = varTex0.x + UNI_blurOffset0;
- vec3 col = texture2D(UNI_Tex0, blurCoord).rgb;
+ vec3 col = texture2D(UNI_color, blurCoord).rgb;
blurCoord.x = varTex0.x + UNI_blurOffset1;
- col += texture2D(UNI_Tex0, blurCoord).rgb;
+ col += texture2D(UNI_color, blurCoord).rgb;
blurCoord.x = varTex0.x + UNI_blurOffset2;
- col += texture2D(UNI_Tex0, blurCoord).rgb;
+ col += texture2D(UNI_color, blurCoord).rgb;
blurCoord.x = varTex0.x + UNI_blurOffset3;
- col += texture2D(UNI_Tex0, blurCoord).rgb;
+ col += texture2D(UNI_color, blurCoord).rgb;
- gl_FragColor = vec4(col * 0.25, 0.0); //texture2D(UNI_Tex0, varTex0);
+ gl_FragColor = vec4(col * 0.25, 0.0);
}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
index a644a3e6b8fb..ade05a27920d 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
@@ -3,15 +3,15 @@ varying vec2 varTex0;
void main() {
vec2 blurCoord = varTex0;
blurCoord.y = varTex0.y + UNI_blurOffset0;
- vec3 col = texture2D(UNI_Tex0, blurCoord).rgb;
+ vec3 col = texture2D(UNI_color, blurCoord).rgb;
blurCoord.y = varTex0.y + UNI_blurOffset1;
- col += texture2D(UNI_Tex0, blurCoord).rgb;
+ col += texture2D(UNI_color, blurCoord).rgb;
blurCoord.y = varTex0.y + UNI_blurOffset2;
- col += texture2D(UNI_Tex0, blurCoord).rgb;
+ col += texture2D(UNI_color, blurCoord).rgb;
blurCoord.y = varTex0.y + UNI_blurOffset3;
- col += texture2D(UNI_Tex0, blurCoord).rgb;
+ col += texture2D(UNI_color, blurCoord).rgb;
col = col * 0.25;
- gl_FragColor = vec4(col, 0.0); //texture2D(UNI_Tex0, varTex0);
+ gl_FragColor = vec4(col, 0.0);
}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
index 5d8938bc5a4e..2eb102872afd 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
@@ -12,8 +12,8 @@ void main() {
float light0_Diffuse = dot(worldNorm, light0Vec);
vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ lowp vec4 col = texture2D(UNI_diffuse, t0).rgba;
col.xyz = col.xyz * light0_Diffuse * 1.2;
- gl_FragColor = col; //vec4(0.0, 1.0, 0.0, 0.0);
+ gl_FragColor = col;
}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
index 51f06124d759..b90a7b27354c 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
@@ -14,8 +14,8 @@ void main() {
float light0_Specular = pow(light0Spec, 15.0) * 0.5;
vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
- col.xyz = col.xyz * (textureCube(UNI_Tex1, worldNorm).rgb * 0.5 + vec3(light0_Diffuse));
+ lowp vec4 col = texture2D(UNI_diffuse, t0).rgba;
+ col.xyz = col.xyz * (textureCube(UNI_reflection, worldNorm).rgb * 0.5 + vec3(light0_Diffuse));
col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
gl_FragColor = col;
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
index 893d55399003..f3b89ede5369 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
@@ -14,12 +14,12 @@ void main() {
float light0_Specular = pow(light0Spec, 150.0) * 0.5;
vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ lowp vec4 col = texture2D(UNI_diffuse, t0).rgba;
col.xyz = col.xyz * light0_Diffuse * 1.1;
col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
float fresnel = mix(pow(1.0 - light0_Diffuse, 15.0), 1.0, 0.1);
- col.xyz = mix(col.xyz, textureCube(UNI_Tex1, -light0R).rgb * 2.4, fresnel);
+ col.xyz = mix(col.xyz, textureCube(UNI_reflection, -light0R).rgb * 2.4, fresnel);
col.w = 0.8;
gl_FragColor = col;
}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
index ceb53bd232d2..56f7151f22af 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
@@ -14,7 +14,7 @@ void main() {
float light0_Specular = pow(light0Spec, 10.0) * 0.5;
vec2 t0 = varTex0.xy;
- lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ lowp vec4 col = texture2D(UNI_diffuse, t0).rgba;
col.xyz = col.xyz * light0_Diffuse * 1.2;
col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
gl_FragColor = col;
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
index 42b231aa8657..1a927cab6236 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
@@ -1,7 +1,7 @@
varying vec2 varTex0;
void main() {
- vec3 col = texture2D(UNI_Tex0, varTex0).rgb;
+ vec3 col = texture2D(UNI_color, varTex0).rgb;
vec3 desat = vec3(0.299, 0.587, 0.114);
float lum = dot(desat, col);
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
index dd709cf01f9d..662ecd852af2 100644
--- a/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
@@ -1,7 +1,7 @@
varying vec2 varTex0;
void main() {
- lowp vec4 col = texture2D(UNI_Tex0, varTex0).rgba;
+ lowp vec4 col = texture2D(UNI_color, varTex0).rgba;
gl_FragColor = col;
}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d
new file mode 100644
index 000000000000..56eff046c696
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java
index c8e25feb8db7..8a468db9a1cf 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java
@@ -83,10 +83,12 @@ public class FragmentShader extends Shader {
mBuilder.addConstant(mShader.mPerObjConstants);
}
for (int i = 0; i < mShader.mTextureTypes.size(); i ++) {
- mBuilder.addTexture(mShader.mTextureTypes.get(i));
+ mBuilder.addTexture(mShader.mTextureTypes.get(i),
+ mShader.mTextureNames.get(i));
}
for (int i = 0; i < mShader.mShaderTextureTypes.size(); i ++) {
- mBuilder.addTexture(mShader.mShaderTextureTypes.get(i));
+ mBuilder.addTexture(mShader.mShaderTextureTypes.get(i),
+ mShader.mShaderTextureNames.get(i));
}
mShader.mProgram = mBuilder.create();
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
index 3476e35ba9ab..9266f3058cf7 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Iterator;
import com.android.scenegraph.Float4Param;
+import com.android.scenegraph.MatrixTransform;
import com.android.scenegraph.SceneManager;
import com.android.scenegraph.ShaderParam;
import com.android.scenegraph.TransformParam;
@@ -89,6 +90,10 @@ public class Renderable extends RenderableBase {
mMaterialName = name;
}
+ public Transform getTransform() {
+ return mTransform;
+ }
+
public void setTransform(Transform t) {
mTransform = t;
if (mField != null) {
@@ -199,12 +204,14 @@ public class Renderable extends RenderableBase {
if (mRenderState == null) {
mRenderState = SceneManager.getDefaultState();
}
+ if (mTransform == null) {
+ mTransform = SceneManager.getDefaultTransform();
+ }
updateVertexConstants(rs);
updateFragmentConstants(rs);
- if (mTransform != null) {
- mData.transformMatrix = mTransform.getRSData().getAllocation();
- }
+ mData.transformMatrix = mTransform.getRSData().getAllocation();
+
mData.name = getNameAlloc(rs);
mData.render_state = mRenderState.getRSData().getAllocation();
mData.bVolInitialized = 0;
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
index 9bd3bf9ad7c5..27336abd5849 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
@@ -22,6 +22,10 @@ import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.android.scenegraph.Camera;
+import com.android.scenegraph.CompoundTransform;
+import com.android.scenegraph.RenderPass;
+import com.android.scenegraph.Renderable;
import com.android.scenegraph.SceneManager;
import com.android.scenegraph.TextureBase;
@@ -81,6 +85,18 @@ public class Scene extends SceneGraphBase {
mRootTransforms.appendChild(t);
}
+ public CompoundTransform appendNewCompoundTransform() {
+ CompoundTransform t = new CompoundTransform();
+ appendTransform(t);
+ return t;
+ }
+
+ public MatrixTransform appendNewMatrixTransform() {
+ MatrixTransform t = new MatrixTransform();
+ appendTransform(t);
+ return t;
+ }
+
// temporary
public void addToTransformMap(Transform t) {
mTransformMap.put(t.getName(), t);
@@ -97,6 +113,12 @@ public class Scene extends SceneGraphBase {
mRenderPasses.add(p);
}
+ public RenderPass appendNewRenderPass() {
+ RenderPass p = new RenderPass();
+ appendRenderPass(p);
+ return p;
+ }
+
public void clearRenderPasses() {
mRenderPasses.clear();
}
@@ -115,6 +137,12 @@ public class Scene extends SceneGraphBase {
mCameras.add(c);
}
+ public Camera appendNewCamera() {
+ Camera c = new Camera();
+ appendCamera(c);
+ return c;
+ }
+
public void appendShader(FragmentShader f) {
if (f == null) {
throw new RuntimeException("Adding null object");
@@ -142,7 +170,15 @@ public class Scene extends SceneGraphBase {
throw new RuntimeException("Adding null object");
}
mRenderables.add(d);
- mRenderableMap.put(d.getName(), d);
+ if (d.getName() != null) {
+ mRenderableMap.put(d.getName(), d);
+ }
+ }
+
+ public Renderable appendNewRenderable() {
+ Renderable r = new Renderable();
+ appendRenderable(r);
+ return r;
}
public ArrayList<RenderableBase> getRenderables() {
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
index 3d1019ea10db..4ff2c8b09371 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
@@ -80,6 +80,7 @@ public class SceneManager extends SceneGraphBase {
private VertexShader mDefaultVertex;
private RenderState mDefaultState;
+ private Transform mDefaultTransform;
private static Allocation getDefault(boolean isCube) {
final int dimension = 4;
@@ -161,24 +162,32 @@ public class SceneManager extends SceneGraphBase {
return b;
}
- public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) {
- Bitmap b = loadBitmap(name, res);
+ static Allocation createFromBitmap(Bitmap b, RenderScriptGL rs, boolean isCube) {
if (b == null) {
return null;
}
- return Allocation.createCubemapFromBitmap(rs, b,
- MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
- Allocation.USAGE_GRAPHICS_TEXTURE);
+ MipmapControl mip = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE;
+ int usage = Allocation.USAGE_GRAPHICS_TEXTURE;
+ if (isCube) {
+ return Allocation.createCubemapFromBitmap(rs, b, mip, usage);
+ }
+ return Allocation.createFromBitmap(rs, b, mip, usage);
+ }
+
+ public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) {
+ return createFromBitmap(loadBitmap(name, res), rs, true);
+ }
+
+ public static Allocation loadCubemap(int id, RenderScriptGL rs, Resources res) {
+ return createFromBitmap(BitmapFactory.decodeResource(res, id), rs, true);
}
public static Allocation loadTexture2D(String name, RenderScriptGL rs, Resources res) {
- Bitmap b = loadBitmap(name, res);
- if (b == null) {
- return null;
- }
- return Allocation.createFromBitmap(rs, b,
- Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
- Allocation.USAGE_GRAPHICS_TEXTURE);
+ return createFromBitmap(loadBitmap(name, res), rs, false);
+ }
+
+ public static Allocation loadTexture2D(int id, RenderScriptGL rs, Resources res) {
+ return createFromBitmap(BitmapFactory.decodeResource(res, id), rs, false);
}
public static ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
@@ -261,6 +270,7 @@ public class SceneManager extends SceneGraphBase {
}
mActiveScene.appendShader(getDefaultVS());
+ mActiveScene.appendTransform(getDefaultTransform());
}
static RenderScriptGL getRS() {
@@ -364,14 +374,15 @@ public class SceneManager extends SceneGraphBase {
final String code = "\n" +
"varying vec2 varTex0;\n" +
"void main() {\n" +
- " lowp vec4 col = texture2D(UNI_Tex0, varTex0).rgba;\n" +
+ " lowp vec4 col = texture2D(UNI_color, varTex0).rgba;\n" +
" gl_FragColor = col;\n" +
"}\n";
FragmentShader.Builder fb = new FragmentShader.Builder(rs);
fb.setShader(code);
- fb.addTexture(Program.TextureType.TEXTURE_2D, "Tex0");
+ fb.addTexture(Program.TextureType.TEXTURE_2D, "color");
sSceneManager.mTexture = fb.create();
+ sSceneManager.mTexture.mProgram.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(rs), 0);
}
return sSceneManager.mTexture;
@@ -383,10 +394,22 @@ public class SceneManager extends SceneGraphBase {
}
if (sSceneManager.mDefaultState == null) {
sSceneManager.mDefaultState = new RenderState(getDefaultVS(), getColorFS(), null, null);
+ sSceneManager.mDefaultState.setName("__DefaultState");
}
return sSceneManager.mDefaultState;
}
+ static Transform getDefaultTransform() {
+ if (sSceneManager == null) {
+ return null;
+ }
+ if (sSceneManager.mDefaultTransform == null) {
+ sSceneManager.mDefaultTransform = new MatrixTransform();
+ sSceneManager.mDefaultTransform.setName("__DefaultTransform");
+ }
+ return sSceneManager.mDefaultTransform;
+ }
+
public static SceneManager getInstance() {
if (sSceneManager == null) {
sSceneManager = new SceneManager();
@@ -444,6 +467,7 @@ public class SceneManager extends SceneGraphBase {
mColor = null;
mTexture = null;
mDefaultState = null;
+ mDefaultTransform = null;
mExportScript = new ScriptC_export(rs, res, R.raw.export);
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
index 8fae9d931700..b53ab883708e 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
@@ -30,6 +30,7 @@ import android.util.Log;
public class Texture2D extends TextureBase {
String mFileName;
String mFileDir;
+ int mResourceID;
public Texture2D() {
super(ScriptC_export.const_TextureType_TEXTURE_2D);
@@ -40,6 +41,17 @@ public class Texture2D extends TextureBase {
setTexture(tex);
}
+ public Texture2D(String dir, String file) {
+ super(ScriptC_export.const_TextureType_TEXTURE_CUBE);
+ setFileDir(dir);
+ setFileName(file);
+ }
+
+ public Texture2D(int resourceID) {
+ super(ScriptC_export.const_TextureType_TEXTURE_2D);
+ mResourceID = resourceID;
+ }
+
public void setFileDir(String dir) {
mFileDir = dir;
}
@@ -62,8 +74,12 @@ public class Texture2D extends TextureBase {
void load() {
RenderScriptGL rs = SceneManager.getRS();
Resources res = SceneManager.getRes();
- String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
- setTexture(SceneManager.loadTexture2D(mFileDir + shortName, rs, res));
+ if (mFileName != null && mFileName.length() > 0) {
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ setTexture(SceneManager.loadTexture2D(mFileDir + shortName, rs, res));
+ } else if (mResourceID != 0) {
+ setTexture(SceneManager.loadTexture2D(mResourceID, rs, res));
+ }
}
ScriptField_Texture_s getRsData(boolean loadNow) {
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
index 12c81c20dd11..1269e3caa06a 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
@@ -31,6 +31,7 @@ import android.util.Log;
public class TextureCube extends TextureBase {
String mFileName;
String mFileDir;
+ int mResourceID;
public TextureCube() {
super(ScriptC_export.const_TextureType_TEXTURE_CUBE);
@@ -47,6 +48,11 @@ public class TextureCube extends TextureBase {
setFileName(file);
}
+ public TextureCube(int resourceID) {
+ super(ScriptC_export.const_TextureType_TEXTURE_2D);
+ mResourceID = resourceID;
+ }
+
public void setFileDir(String dir) {
mFileDir = dir;
}
@@ -69,8 +75,12 @@ public class TextureCube extends TextureBase {
void load() {
RenderScriptGL rs = SceneManager.getRS();
Resources res = SceneManager.getRes();
- String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
- setTexture(SceneManager.loadCubemap(mFileDir + shortName, rs, res));
+ if (mFileName != null && mFileName.length() > 0) {
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ setTexture(SceneManager.loadCubemap(mFileDir + shortName, rs, res));
+ } else if (mResourceID != 0) {
+ setTexture(SceneManager.loadCubemap(mResourceID , rs, res));
+ }
}
ScriptField_Texture_s getRsData(boolean loadNow) {
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java
index 938883865db1..fff6f3407a92 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java
@@ -34,16 +34,16 @@ import android.util.Log;
// This is where the scenegraph and the rendered objects are initialized and used
public class SimpleAppRS {
-
- private static String TAG = "SimpleAppRS";
-
SceneManager mSceneManager;
- ArrayList<Renderable> geometry = new ArrayList<Renderable>();
- Scene mScene;
RenderScriptGL mRS;
Resources mRes;
+ Scene mScene;
+ Mesh mSimpleMesh;
+ Mesh mSphereMesh;
+ Mesh mCubeMesh;
+
public void init(RenderScriptGL rs, Resources res, int width, int height) {
mRS = rs;
mRes = res;
@@ -53,9 +53,11 @@ public class SimpleAppRS {
mScene = new Scene();
setupGeometry();
+ setupColoredQuad();
+ setupTexturedQuad();
+ setupShadedGeometry();
setupCamera();
setupRenderPass();
- setupShaders();
mSceneManager.setActiveScene(mScene);
@@ -63,17 +65,11 @@ public class SimpleAppRS {
mRS.bindRootScript(mSceneManager.getRenderLoop());
}
- private void setupShaders() {
- // Built-in shader that provides position, texcoord and normal
- VertexShader genericV = SceneManager.getDefaultVS();
- // Built-in shader that displays a color
- FragmentShader colorF = SceneManager.getColorFS();
- mScene.assignRenderState(new RenderState(genericV, colorF, null, null));
- }
private void setupGeometry() {
- Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
- 3, Mesh.TriangleMeshBuilder.TEXTURE_0);
+ Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 3,
+ Mesh.TriangleMeshBuilder.TEXTURE_0);
+ // Create four vertices with texture coordinates
tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 0.0f);
tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 0.0f);
tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 0.0f);
@@ -81,40 +77,131 @@ public class SimpleAppRS {
tmb.addTriangle(0, 1, 2);
tmb.addTriangle(2, 3, 0);
+ mSimpleMesh = tmb.create(true);
+
+ // Load a file that constains two pieces of geometry, a sphere and a cube
+ FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.unit_obj);
+ for (int i = 0; i < model.getIndexEntryCount(); i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getName().equals("CubeMesh")) {
+ mCubeMesh = entry.getMesh();
+ } else if (entry != null && entry.getName().equals("SphereMesh")) {
+ mSphereMesh = entry.getMesh();
+ }
+ }
+ }
- Mesh mesh = tmb.create(true);
+ private void setupColoredQuad() {
+ // Built-in shader that provides position, texcoord and normal
+ VertexShader genericV = SceneManager.getDefaultVS();
+ // Built-in shader that displays a color
+ FragmentShader colorF = SceneManager.getColorFS();
+ RenderState colorRS = new RenderState(genericV, colorF, null, null);
- Renderable quad = new Renderable();
- quad.setMesh(mesh);
- quad.setTransform(new CompoundTransform());
+ // Draw a simple colored quad
+ Renderable quad = mScene.appendNewRenderable();
+ quad.setMesh(mSimpleMesh);
+ // Our shader has a constant input called "color"
+ // This tells the scenegraph to assign the following float3 to that input
quad.appendSourceParams(new Float4Param("color", 0.2f, 0.3f, 0.4f));
+ quad.setRenderState(colorRS);
+ }
+
+ private void setupTexturedQuad() {
+ // Built-in shader that provides position, texcoord and normal
+ VertexShader genericV = SceneManager.getDefaultVS();
+ // Built-in shader that displays a texture
+ FragmentShader textureF = SceneManager.getTextureFS();
+ // We want to use transparency based on the alpha channel of the texture
+ ProgramStore alphaBlend = ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS);
+ RenderState texRS = new RenderState(genericV, textureF, alphaBlend, null);
+
+ // Draw a textured quad
+ Renderable quad = mScene.appendNewRenderable();
+ quad.setMesh(mSimpleMesh);
+ // Make a transform to position the quad
+ CompoundTransform t = mScene.appendNewCompoundTransform();
+ t.addTranslate("position", new Float3(2, 2, 0));
+ quad.setTransform(t);
+ // Our fragment shader has a constant texture input called "color"
+ // This will assign an icon from drawables to that input
+ quad.appendSourceParams(new TextureParam("color", new Texture2D(R.drawable.icon)));
+ quad.setRenderState(texRS);
+ }
+
+ private FragmentShader createLambertShader() {
+ // Describe what constant inputs our shader wants
+ Element.Builder b = new Element.Builder(mRS);
+ b.add(Element.F32_4(mRS), "cameraPos");
+
+ // Create a shader from a text file in resources
+ FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
+ // Tell the shader what constants we want
+ fb.setShaderConst(new Type.Builder(mRS, b.create()).setX(1).create());
+ // Shader code location
+ fb.setShader(mRes, R.raw.diffuse);
+ // We want a texture called diffuse on our shader
+ fb.addTexture(TextureType.TEXTURE_2D, "diffuse");
+ FragmentShader shader = fb.create();
+ mScene.appendShader(shader);
+ return shader;
+ }
- mScene.appendRenderable(quad);
- geometry.add(quad);
+ private void setupShadedGeometry() {
+ // Built-in shader that provides position, texcoord and normal
+ VertexShader genericV = SceneManager.getDefaultVS();
+ // Custom shader
+ FragmentShader diffuseF = createLambertShader();
+ RenderState diffuseRS = new RenderState(genericV, diffuseF, null, null);
+
+ // Draw a sphere
+ Renderable sphere = mScene.appendNewRenderable();
+ // Use the sphere geometry loaded earlier
+ sphere.setMesh(mSphereMesh);
+ // Make a transform to position the sphere
+ CompoundTransform t = mScene.appendNewCompoundTransform();
+ t.addTranslate("position", new Float3(-1, 2, 3));
+ t.addScale("scale", new Float3(1.4f, 1.4f, 1.4f));
+ sphere.setTransform(t);
+ // Tell the renderable which texture to use when we draw
+ // This will mean a texture param in the shader called "diffuse"
+ // will be assigned a texture called red.jpg
+ sphere.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "red.jpg")));
+ sphere.setRenderState(diffuseRS);
+
+ // Draw a cube
+ Renderable cube = mScene.appendNewRenderable();
+ cube.setMesh(mCubeMesh);
+ t = mScene.appendNewCompoundTransform();
+ t.addTranslate("position", new Float3(-2, -2.1f, 0));
+ t.addRotate("rotateX", new Float3(1, 0, 0), 30);
+ t.addRotate("rotateY", new Float3(0, 1, 0), 30);
+ t.addScale("scale", new Float3(2, 2, 2));
+ cube.setTransform(t);
+ cube.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "orange.jpg")));
+ cube.setRenderState(diffuseRS);
}
private void setupCamera() {
- Camera camera = new Camera();
+ Camera camera = mScene.appendNewCamera();
camera.setFar(200);
camera.setNear(0.1f);
camera.setFOV(60);
- CompoundTransform cameraTransform = new CompoundTransform();
+ CompoundTransform cameraTransform = mScene.appendNewCompoundTransform();
cameraTransform.addTranslate("camera", new Float3(0, 0, 10));
- mScene.appendTransform(cameraTransform);
camera.setTransform(cameraTransform);
- mScene.appendCamera(camera);
}
private void setupRenderPass() {
- RenderPass mainPass = new RenderPass();
+ RenderPass mainPass = mScene.appendNewRenderPass();
mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
mainPass.setShouldClearColor(true);
mainPass.setClearDepth(1.0f);
mainPass.setShouldClearDepth(true);
mainPass.setCamera(mScene.getCameras().get(0));
- for (Renderable renderable : geometry) {
- mainPass.appendRenderable(renderable);
+ ArrayList<RenderableBase> allRender = mScene.getRenderables();
+ for (RenderableBase renderable : allRender) {
+ mainPass.appendRenderable((Renderable)renderable);
}
- mScene.appendRenderPass(mainPass);
}
}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
index c182c2941e7f..e272cc58cd6f 100644
--- a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
@@ -48,7 +48,7 @@ public class TouchHandler {
mPosValue = new Float3(0, 4, 0);
// Make a camera transform we can manipulate
- mCameraRig = new CompoundTransform();
+ mCameraRig = scene.appendNewCompoundTransform();
mCameraRig.setName("CameraRig");
mPosition = mCameraRig.addTranslate("Position", mPosValue);
@@ -56,10 +56,8 @@ public class TouchHandler {
mRotateX = mCameraRig.addRotate("RotateX", new Float3(1, 0, 0), mRotateXValue);
mDist = mCameraRig.addTranslate("Distance", mDistValue);
- scene.appendTransform(mCameraRig);
- mCamera = new Camera();
+ mCamera = scene.appendNewCamera();
mCamera.setTransform(mCameraRig);
- scene.appendCamera(mCamera);
}
public Camera getCamera() {
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index c7bd80994603..6f5622363de8 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -64,11 +64,6 @@ public class RSTestCore {
unitTests = new ArrayList<UnitTest>();
- unitTests.add(new UT_mesh(this, mRes, mCtx));
- unitTests.add(new UT_element(this, mRes, mCtx));
- unitTests.add(new UT_sampler(this, mRes, mCtx));
- unitTests.add(new UT_program_store(this, mRes, mCtx));
- unitTests.add(new UT_program_raster(this, mRes, mCtx));
unitTests.add(new UT_primitives(this, mRes, mCtx));
unitTests.add(new UT_constant(this, mRes, mCtx));
unitTests.add(new UT_vector(this, mRes, mCtx));
@@ -79,10 +74,17 @@ public class RSTestCore {
unitTests.add(new UT_alloc(this, mRes, mCtx));
unitTests.add(new UT_refcount(this, mRes, mCtx));
unitTests.add(new UT_foreach(this, mRes, mCtx));
+ unitTests.add(new UT_noroot(this, mRes, mCtx));
unitTests.add(new UT_atomic(this, mRes, mCtx));
unitTests.add(new UT_struct(this, mRes, mCtx));
unitTests.add(new UT_math(this, mRes, mCtx));
+ unitTests.add(new UT_mesh(this, mRes, mCtx));
+ unitTests.add(new UT_element(this, mRes, mCtx));
+ unitTests.add(new UT_sampler(this, mRes, mCtx));
+ unitTests.add(new UT_program_store(this, mRes, mCtx));
+ unitTests.add(new UT_program_raster(this, mRes, mCtx));
unitTests.add(new UT_fp_mad(this, mRes, mCtx));
+
/*
unitTests.add(new UnitTest(null, "<Pass>", 1));
unitTests.add(new UnitTest());
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java
index 1d2555ec4b07..04e92700f5de 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-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.
@@ -48,6 +48,9 @@ public class UT_foreach extends UnitTest {
pRS.setMessageHandler(mRsMessage);
initializeGlobals(pRS, s);
s.forEach_root(A);
+ s.invoke_verify_root();
+ s.forEach_foo(A, A);
+ s.invoke_verify_foo();
s.invoke_foreach_test();
pRS.finish();
waitForMessage();
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java
new file mode 100644
index 000000000000..c660fc53fbcc
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_noroot extends UnitTest {
+ private Resources mRes;
+ private Allocation A;
+
+ protected UT_noroot(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ForEach (no root)", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_noroot s) {
+ Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+ int X = 5;
+ int Y = 7;
+ s.set_dimX(X);
+ s.set_dimY(Y);
+ typeBuilder.setX(X).setY(Y);
+ A = Allocation.createTyped(RS, typeBuilder.create());
+ s.bind_a(A);
+
+ return;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_noroot s = new ScriptC_noroot(pRS, mRes, R.raw.noroot);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.forEach_foo(A, A);
+ s.invoke_verify_foo();
+ s.invoke_noroot_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs
index 3ba3eef1bbc8..ac527b597432 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs
@@ -3,12 +3,19 @@
int *a;
int dimX;
int dimY;
+static bool failed = false;
void root(int *out, uint32_t x, uint32_t y) {
*out = x + y * dimX;
}
-static bool test_foreach_output() {
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+ _RS_ASSERT(*in == (x + y * dimX));
+ *out = 99 + x + y * dimX;
+ _RS_ASSERT(*out == (99 + x + y * dimX));
+}
+
+static bool test_root_output() {
bool failed = false;
int i, j;
@@ -19,19 +26,44 @@ static bool test_foreach_output() {
}
if (failed) {
- rsDebug("test_foreach_output FAILED", 0);
+ rsDebug("test_root_output FAILED", 0);
}
else {
- rsDebug("test_foreach_output PASSED", 0);
+ rsDebug("test_root_output PASSED", 0);
}
return failed;
}
-void foreach_test() {
+static bool test_foo_output() {
bool failed = false;
- failed |= test_foreach_output();
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_foo_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_foo_output PASSED", 0);
+ }
+
+ return failed;
+}
+void verify_root() {
+ failed |= test_root_output();
+}
+
+void verify_foo() {
+ failed |= test_foo_output();
+}
+
+void foreach_test() {
if (failed) {
rsSendToClientBlocking(RS_MSG_TEST_FAILED);
}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs
new file mode 100644
index 000000000000..33944aa15510
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs
@@ -0,0 +1,44 @@
+#include "shared.rsh"
+
+int *a;
+int dimX;
+int dimY;
+static bool failed = false;
+
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+ *out = 99 + x + y * dimX;
+}
+
+static bool test_foo_output() {
+ bool failed = false;
+ int i, j;
+
+ for (j = 0; j < dimY; j++) {
+ for (i = 0; i < dimX; i++) {
+ _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX));
+ }
+ }
+
+ if (failed) {
+ rsDebug("test_foo_output FAILED", 0);
+ }
+ else {
+ rsDebug("test_foo_output PASSED", 0);
+ }
+
+ return failed;
+}
+
+void verify_foo() {
+ failed |= test_foo_output();
+}
+
+void noroot_test() {
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index f463a194070e..ae01c750847f 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -765,22 +765,70 @@ public class NotificationTestList extends TestActivity
}
},
- new Test("System priority notification") {
+ new Test("PRIORITY_HIGH") {
public void run() {
Notification n = new Notification.Builder(NotificationTestList.this)
- .setSmallIcon(R.drawable.notification1)
- .setContentTitle("System priority")
+ .setSmallIcon(R.drawable.notification5)
+ .setContentTitle("High priority")
.setContentText("This should appear before all others")
+ .setPriority(Notification.PRIORITY_HIGH)
.getNotification();
int[] idOut = new int[1];
try {
INotificationManager directLine = mNM.getService();
- directLine.enqueueNotificationWithTagPriority(
+ directLine.enqueueNotificationWithTag(
+ getPackageName(),
+ null,
+ 100,
+ n,
+ idOut);
+ } catch (android.os.RemoteException ex) {
+ // oh well
+ }
+ }
+ },
+
+ new Test("PRIORITY_MAX") {
+ public void run() {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.notification9)
+ .setContentTitle("MAX priority")
+ .setContentText("This might appear as an intruder alert")
+ .setPriority(Notification.PRIORITY_MAX)
+ .getNotification();
+
+ int[] idOut = new int[1];
+ try {
+ INotificationManager directLine = mNM.getService();
+ directLine.enqueueNotificationWithTag(
+ getPackageName(),
+ null,
+ 200,
+ n,
+ idOut);
+ } catch (android.os.RemoteException ex) {
+ // oh well
+ }
+ }
+ },
+
+ new Test("PRIORITY_MIN") {
+ public void run() {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.notification0)
+ .setContentTitle("MIN priority")
+ .setContentText("You should not see this")
+ .setPriority(Notification.PRIORITY_MIN)
+ .getNotification();
+
+ int[] idOut = new int[1];
+ try {
+ INotificationManager directLine = mNM.getService();
+ directLine.enqueueNotificationWithTag(
getPackageName(),
null,
1,
- StatusBarNotification.PRIORITY_SYSTEM,
n,
idOut);
} catch (android.os.RemoteException ex) {
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 95a68d174580..8d7acee54461 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -21,6 +21,7 @@
const char* const RESOURCES_ROOT_NAMESPACE = "http://schemas.android.com/apk/res/";
const char* const RESOURCES_ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android";
+const char* const RESOURCES_AUTO_PACKAGE_NAMESPACE = "http://schemas.android.com/apk/res-auto";
const char* const RESOURCES_ROOT_PRV_NAMESPACE = "http://schemas.android.com/apk/prv/res/";
const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
@@ -44,16 +45,21 @@ bool isWhitespace(const char16_t* str)
}
static const String16 RESOURCES_PREFIX(RESOURCES_ROOT_NAMESPACE);
+static const String16 RESOURCES_PREFIX_AUTO_PACKAGE(RESOURCES_AUTO_PACKAGE_NAMESPACE);
static const String16 RESOURCES_PRV_PREFIX(RESOURCES_ROOT_PRV_NAMESPACE);
static const String16 RESOURCES_TOOLS_NAMESPACE("http://schemas.android.com/tools");
-String16 getNamespaceResourcePackage(String16 namespaceUri, bool* outIsPublic)
+String16 getNamespaceResourcePackage(String16 appPackage, String16 namespaceUri, bool* outIsPublic)
{
//printf("%s starts with %s?\n", String8(namespaceUri).string(),
// String8(RESOURCES_PREFIX).string());
size_t prefixSize;
bool isPublic = true;
- if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
+ if(namespaceUri.startsWith(RESOURCES_PREFIX_AUTO_PACKAGE)) {
+ NOISY(printf("Using default application package: %s -> %s\n", String8(namespaceUri).string(), String8(appPackage).string()));
+ isPublic = true;
+ return appPackage;
+ } else if (namespaceUri.startsWith(RESOURCES_PREFIX)) {
prefixSize = RESOURCES_PREFIX.size();
} else if (namespaceUri.startsWith(RESOURCES_PRV_PREFIX)) {
isPublic = false;
@@ -926,7 +932,7 @@ status_t XMLNode::assignResourceIds(const sp<AaptAssets>& assets,
const attribute_entry& e = mAttributes.itemAt(i);
if (e.ns.size() <= 0) continue;
bool nsIsPublic;
- String16 pkg(getNamespaceResourcePackage(e.ns, &nsIsPublic));
+ String16 pkg(getNamespaceResourcePackage(String16(assets->getPackage()), e.ns, &nsIsPublic));
NOISY(printf("Elem %s %s=\"%s\": namespace(%s) %s ===> %s\n",
String8(getElementName()).string(),
String8(e.name).string(),
diff --git a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
index 0a3cdc66f032..6ac5b02916ae 100644
--- a/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/android/util/BridgeXmlPullAttributes.java
@@ -18,6 +18,7 @@ package android.util;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
import com.android.layoutlib.bridge.android.BridgeContext;
@@ -25,9 +26,6 @@ import com.android.resources.ResourceType;
import org.xmlpull.v1.XmlPullParser;
-import android.util.AttributeSet;
-import android.util.XmlPullAttributes;
-
/**
* A correct implementation of the {@link AttributeSet} interface on top of a XmlPullParser
*/
@@ -80,21 +78,40 @@ public class BridgeXmlPullAttributes extends XmlPullAttributes {
return 0;
}
- /*
- * (non-Javadoc)
- * @see android.util.XmlPullAttributes#getAttributeResourceValue(int, int)
- */
@Override
- public int getAttributeResourceValue(int index, int defaultValue) {
- String value = getAttributeValue(index);
+ public int getAttributeListValue(String namespace, String attribute,
+ String[] options, int defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
- return resolveResourceValue(value, defaultValue);
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToList(value, options, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public boolean getAttributeBooleanValue(String namespace, String attribute,
+ boolean defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToBoolean(value, defaultValue);
+ }
+
+ return defaultValue;
}
- /*
- * (non-Javadoc)
- * @see android.util.XmlPullAttributes#getAttributeResourceValue(java.lang.String, java.lang.String, int)
- */
@Override
public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) {
String value = getAttributeValue(namespace, attribute);
@@ -102,12 +119,151 @@ public class BridgeXmlPullAttributes extends XmlPullAttributes {
return resolveResourceValue(value, defaultValue);
}
- private int resolveResourceValue(String value, int defaultValue) {
+ @Override
+ public int getAttributeIntValue(String namespace, String attribute,
+ int defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeUnsignedIntValue(String namespace, String attribute,
+ int defaultValue) {
+ String value = getAttributeValue(namespace, attribute);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public float getAttributeFloatValue(String namespace, String attribute,
+ float defaultValue) {
+ String s = getAttributeValue(namespace, attribute);
+ if (s != null) {
+ ResourceValue r = getResourceValue(s);
+
+ if (r != null) {
+ s = r.getValue();
+ }
+
+ return Float.parseFloat(s);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeListValue(int index,
+ String[] options, int defaultValue) {
+ return XmlUtils.convertValueToList(
+ getAttributeValue(index), options, defaultValue);
+ }
+
+ @Override
+ public boolean getAttributeBooleanValue(int index, boolean defaultValue) {
+ String value = getAttributeValue(index);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToBoolean(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeResourceValue(int index, int defaultValue) {
+ String value = getAttributeValue(index);
+
+ return resolveResourceValue(value, defaultValue);
+ }
+
+ @Override
+ public int getAttributeIntValue(int index, int defaultValue) {
+ String value = getAttributeValue(index);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public int getAttributeUnsignedIntValue(int index, int defaultValue) {
+ String value = getAttributeValue(index);
+ if (value != null) {
+ ResourceValue r = getResourceValue(value);
+
+ if (r != null) {
+ value = r.getValue();
+ }
+
+ return XmlUtils.convertValueToUnsignedInt(value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ @Override
+ public float getAttributeFloatValue(int index, float defaultValue) {
+ String s = getAttributeValue(index);
+ if (s != null) {
+ ResourceValue r = getResourceValue(s);
+
+ if (r != null) {
+ s = r.getValue();
+ }
+
+ return Float.parseFloat(s);
+ }
+
+ return defaultValue;
+ }
+
+ // -- private helper methods
+
+ /**
+ * Returns a resolved {@link ResourceValue} from a given value.
+ */
+ private ResourceValue getResourceValue(String value) {
// now look for this particular value
RenderResources resources = mContext.getRenderResources();
- ResourceValue resource = resources.resolveResValue(
- resources.findResValue(value, mPlatformFile));
+ return resources.resolveResValue(resources.findResValue(value, mPlatformFile));
+ }
+ /**
+ * Resolves and return a value to its associated integer.
+ */
+ private int resolveResourceValue(String value, int defaultValue) {
+ ResourceValue resource = getResourceValue(value);
if (resource != null) {
Integer id = null;
if (mPlatformFile || resource.isFramework()) {
@@ -124,5 +280,4 @@ public class BridgeXmlPullAttributes extends XmlPullAttributes {
return defaultValue;
}
-
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 33bf7bc785e3..ff882099b177 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -24,8 +24,8 @@ import com.android.ide.common.rendering.api.DrawableParams;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.Result.Status;
+import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.impl.FontLoader;
import com.android.layoutlib.bridge.impl.RenderDrawable;
import com.android.layoutlib.bridge.impl.RenderSessionImpl;
@@ -242,6 +242,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
if (fontLoader != null) {
Typeface_Delegate.init(fontLoader);
} else {
+ log.error(LayoutLog.TAG_BROKEN,
+ "Failed create FontLoader in layout lib.", null);
return false;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
index 112af1ea35d2..eb9e7f1dafb3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
@@ -39,6 +39,9 @@ public class BridgeConstants {
/** Namespace for the resource XML */
public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
+ /** App auto namespace */
+ public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
+
public final static String R = "com.android.internal.R";
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index cd085fc2b4f6..58dc2d4984e6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -49,8 +49,8 @@ import android.content.res.BridgeResources;
import android.content.res.BridgeTypedArray;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -78,8 +78,8 @@ import java.io.InputStream;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
-import java.util.TreeMap;
import java.util.Map.Entry;
+import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -615,7 +615,8 @@ public final class BridgeContext extends Context {
}
String namespace = BridgeConstants.NS_RESOURCES;
- if (frameworkAttributes.get() == false) {
+ boolean useFrameworkNS = frameworkAttributes.get();
+ if (useFrameworkNS == false) {
// need to use the application namespace
namespace = mProjectCallback.getNamespace();
}
@@ -628,6 +629,12 @@ public final class BridgeContext extends Context {
String value = null;
if (set != null) {
value = set.getAttributeValue(namespace, name);
+
+ // if this is an app attribute, and the first get fails, try with the
+ // new res-auto namespace as well
+ if (useFrameworkNS == false && value == null) {
+ value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, name);
+ }
}
// if there's no direct value for this attribute in the XML, we look for default
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
index 6afdfbe31b05..d6abbaa6189a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -184,8 +184,8 @@ public class BridgeIInputMethodManager implements IInputMethodManager {
}
@Override
- public InputBindResult startInput(IInputMethodClient arg0, IInputContext arg1, EditorInfo arg2,
- boolean arg3, boolean arg4) throws RemoteException {
+ public InputBindResult startInput(IInputMethodClient client, IInputContext inputContext,
+ EditorInfo attribute, int controlFlags) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
@@ -209,10 +209,11 @@ public class BridgeIInputMethodManager implements IInputMethodManager {
}
@Override
- public void windowGainedFocus(IInputMethodClient arg0, IBinder arg1, boolean arg2,
- boolean arg3, int arg4, boolean arg5, int arg6) throws RemoteException {
+ public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
+ int controlFlags, int softInputMode, int windowFlags, EditorInfo attribute,
+ IInputContext inputContext) throws RemoteException {
// TODO Auto-generated method stub
-
+ return null;
}
@Override