summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk3
-rw-r--r--api/current.txt64
-rw-r--r--cmds/dumpstate/dumpstate.c4
-rw-r--r--cmds/servicemanager/Android.mk3
-rw-r--r--cmds/servicemanager/service_manager.c3
-rw-r--r--cmds/stagefright/record.cpp4
-rw-r--r--core/java/android/animation/LayoutTransition.java80
-rw-r--r--core/java/android/annotation/SuppressLint.java38
-rw-r--r--core/java/android/annotation/TargetApi.java35
-rw-r--r--core/java/android/app/ActivityManager.java26
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--core/java/android/app/SearchDialog.java1
-rw-r--r--core/java/android/content/AsyncTaskLoader.java20
-rw-r--r--core/java/android/content/CancelationSignal.java164
-rw-r--r--core/java/android/content/ContentProvider.java93
-rw-r--r--core/java/android/content/ContentProviderClient.java15
-rw-r--r--core/java/android/content/ContentProviderNative.java41
-rw-r--r--core/java/android/content/ContentResolver.java52
-rw-r--r--core/java/android/content/CursorLoader.java39
-rw-r--r--core/java/android/content/ICancelationSignal.aidl24
-rw-r--r--core/java/android/content/IContentProvider.java5
-rw-r--r--core/java/android/content/Intent.java174
-rw-r--r--core/java/android/content/OperationCanceledException.java32
-rw-r--r--core/java/android/content/res/Configuration.java1
-rw-r--r--core/java/android/database/Cursor.java1
-rw-r--r--core/java/android/database/sqlite/SQLiteConnection.java168
-rw-r--r--core/java/android/database/sqlite/SQLiteConnectionPool.java86
-rw-r--r--core/java/android/database/sqlite/SQLiteCursor.java6
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java146
-rw-r--r--core/java/android/database/sqlite/SQLiteDirectCursorDriver.java8
-rw-r--r--core/java/android/database/sqlite/SQLiteProgram.java7
-rw-r--r--core/java/android/database/sqlite/SQLiteQuery.java16
-rw-r--r--core/java/android/database/sqlite/SQLiteQueryBuilder.java62
-rw-r--r--core/java/android/database/sqlite/SQLiteSession.java183
-rw-r--r--core/java/android/database/sqlite/SQLiteStatement.java14
-rw-r--r--core/java/android/net/NetworkStats.java39
-rw-r--r--core/java/android/net/NetworkStatsHistory.java78
-rw-r--r--core/java/android/net/NetworkTemplate.java10
-rw-r--r--core/java/android/net/TrafficStats.java2
-rw-r--r--core/java/android/net/Uri.java33
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl3
-rw-r--r--core/java/android/nfc/NdefMessage.java46
-rw-r--r--core/java/android/nfc/NdefRecord.java307
-rw-r--r--core/java/android/nfc/NfcAdapter.java36
-rw-r--r--core/java/android/nfc/Tag.java16
-rw-r--r--core/java/android/nfc/tech/BasicTagTechnology.java12
-rw-r--r--core/java/android/os/AsyncTask.java2
-rw-r--r--core/java/android/os/Build.java65
-rw-r--r--core/java/android/provider/MediaStore.java8
-rw-r--r--core/java/android/provider/Settings.java33
-rw-r--r--core/java/android/text/MeasuredText.java3
-rw-r--r--core/java/android/text/format/Time.java3
-rw-r--r--core/java/android/text/style/SuggestionSpan.java10
-rw-r--r--core/java/android/util/DisplayMetrics.java7
-rw-r--r--core/java/android/view/ActionMode.java12
-rw-r--r--core/java/android/view/GLES20Canvas.java27
-rw-r--r--core/java/android/view/GLES20DisplayList.java8
-rw-r--r--core/java/android/view/HardwareRenderer.java23
-rw-r--r--core/java/android/view/View.java29
-rw-r--r--core/java/android/view/ViewGroup.java42
-rw-r--r--core/java/android/view/ViewPropertyAnimator.java142
-rw-r--r--core/java/android/view/ViewRootImpl.java35
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java16
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java16
-rw-r--r--core/java/android/view/inputmethod/InputConnectionWrapper.java4
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java44
-rw-r--r--core/java/android/webkit/Network.java4
-rw-r--r--core/java/android/webkit/WebCoreThreadWatchdog.java39
-rw-r--r--core/java/android/webkit/WebView.java584
-rw-r--r--core/java/android/webkit/WebViewCore.java64
-rw-r--r--core/java/android/widget/ActivityChooserView.java8
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java4
-rw-r--r--core/java/android/widget/GridLayout.java8
-rw-r--r--core/java/android/widget/NumberPicker.java32
-rw-r--r--core/java/android/widget/ShareActionProvider.java1
-rw-r--r--core/java/android/widget/SpellChecker.java54
-rw-r--r--core/java/android/widget/TextView.java144
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java8
-rw-r--r--core/java/com/android/internal/util/FastMath.java6
-rw-r--r--core/java/com/android/internal/util/FileRotator.java121
-rw-r--r--core/java/com/android/internal/util/IndentingPrintWriter.java63
-rw-r--r--core/java/com/android/internal/view/InputConnectionWrapper.java4
-rw-r--r--core/java/com/android/internal/widget/DigitalClock.java2
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java54
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java2
-rw-r--r--core/jni/android/graphics/Canvas.cpp15
-rw-r--r--core/jni/android/graphics/Paint.cpp38
-rw-r--r--core/jni/android/graphics/TextLayout.cpp44
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp100
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h148
-rw-r--r--core/jni/android_database_SQLiteCommon.cpp63
-rw-r--r--core/jni/android_database_SQLiteConnection.cpp32
-rw-r--r--core/jni/android_media_AudioRecord.cpp4
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp64
-rw-r--r--core/jni/android_view_HardwareRenderer.cpp10
-rw-r--r--core/res/res/values-af/strings.xml1
-rw-r--r--core/res/res/values-am/strings.xml1
-rw-r--r--core/res/res/values-ar/strings.xml1
-rw-r--r--core/res/res/values-be/strings.xml765
-rw-r--r--core/res/res/values-bg/strings.xml1
-rw-r--r--core/res/res/values-ca/strings.xml1
-rw-r--r--core/res/res/values-cs/strings.xml1
-rw-r--r--core/res/res/values-da/strings.xml5
-rw-r--r--core/res/res/values-de/strings.xml3
-rw-r--r--core/res/res/values-el/strings.xml1
-rw-r--r--core/res/res/values-en-rGB/strings.xml1
-rw-r--r--core/res/res/values-es-rUS/strings.xml151
-rw-r--r--core/res/res/values-es/strings.xml1
-rw-r--r--core/res/res/values-et/strings.xml235
-rw-r--r--core/res/res/values-fa/strings.xml1
-rw-r--r--core/res/res/values-fi/strings.xml1
-rw-r--r--core/res/res/values-fr/strings.xml1
-rw-r--r--core/res/res/values-hi/strings.xml1
-rw-r--r--core/res/res/values-hr/strings.xml1
-rw-r--r--core/res/res/values-hu/strings.xml1
-rw-r--r--core/res/res/values-in/strings.xml1
-rw-r--r--core/res/res/values-it/strings.xml1
-rw-r--r--core/res/res/values-iw/strings.xml1
-rw-r--r--core/res/res/values-ja/strings.xml1
-rw-r--r--core/res/res/values-ko/strings.xml1
-rw-r--r--core/res/res/values-lt/strings.xml1
-rw-r--r--core/res/res/values-lv/strings.xml1
-rw-r--r--core/res/res/values-ms/strings.xml1
-rw-r--r--core/res/res/values-nb/strings.xml1
-rw-r--r--core/res/res/values-nl/strings.xml1
-rw-r--r--core/res/res/values-pl/strings.xml9
-rw-r--r--core/res/res/values-pt-rPT/strings.xml1
-rw-r--r--core/res/res/values-pt/strings.xml1
-rw-r--r--core/res/res/values-rm/strings.xml1060
-rw-r--r--core/res/res/values-ro/strings.xml1
-rw-r--r--core/res/res/values-ru/strings.xml1
-rw-r--r--core/res/res/values-sk/strings.xml1
-rw-r--r--core/res/res/values-sl/strings.xml1
-rw-r--r--core/res/res/values-sr/strings.xml3
-rw-r--r--core/res/res/values-sv/strings.xml1
-rw-r--r--core/res/res/values-sw/strings.xml1
-rw-r--r--core/res/res/values-th/strings.xml1
-rw-r--r--core/res/res/values-tl/strings.xml1
-rw-r--r--core/res/res/values-tr/strings.xml1
-rw-r--r--core/res/res/values-uk/strings.xml1
-rw-r--r--core/res/res/values-vi/strings.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml1
-rw-r--r--core/res/res/values-zh-rTW/strings.xml3
-rw-r--r--core/res/res/values-zu/strings.xml1
-rw-r--r--core/res/res/values/arrays.xml117
-rwxr-xr-xcore/res/res/values/attrs.xml6
-rwxr-xr-xcore/res/res/values/config.xml30
-rw-r--r--core/res/res/values/styles.xml2
-rw-r--r--core/res/res/values/themes.xml141
-rw-r--r--core/res/res/values/themes_device_defaults.xml64
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java4
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java2
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java27
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java55
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java18
-rw-r--r--core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java8
-rw-r--r--core/tests/coretests/src/android/util/InternalSelectionView.java28
-rw-r--r--core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java6
-rw-r--r--core/tests/coretests/src/android/widget/focus/RequestFocus.java2
-rw-r--r--core/tests/coretests/src/android/widget/focus/RequestFocusTest.java163
-rw-r--r--core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java27
-rw-r--r--docs/html/design/get-started/ui-overview.html15
-rw-r--r--docs/html/design/patterns/actionbar.html18
-rw-r--r--docs/html/design/patterns/app-structure.html6
-rw-r--r--docs/html/design/patterns/navigation.html13
-rw-r--r--docs/html/design/patterns/notifications.html2
-rw-r--r--docs/html/design/static/download/action_bar_icons-v4.0.zipbin0 -> 1104707 bytes
-rw-r--r--docs/html/design/style/iconography.html22
-rw-r--r--docs/html/guide/appendix/market-filters.jd8
-rw-r--r--docs/html/guide/developing/device.jd8
-rw-r--r--docs/html/guide/guide_toc.cs132
-rw-r--r--docs/html/guide/practices/ui_guidelines/icon_design.jd2
-rw-r--r--docs/html/guide/topics/providers/content-provider-basics.jd1215
-rw-r--r--docs/html/guide/topics/providers/content-provider-creating.jd1215
-rw-r--r--docs/html/guide/topics/providers/content-providers.jd994
-rw-r--r--docs/html/guide/topics/ui/actionbar.jd30
-rw-r--r--docs/html/guide/topics/ui/how-android-draws.jd2
-rw-r--r--docs/html/guide/topics/ui/menus.jd1008
-rw-r--r--docs/html/guide/topics/ui/notifiers/notifications.jd24
-rw-r--r--docs/html/images/ui/menu-context.pngbin0 -> 45304 bytes
-rw-r--r--docs/html/images/ui/popupmenu.pngbin0 -> 8186 bytes
-rw-r--r--docs/html/index.jd28
-rw-r--r--docs/html/resources/community-more.jd21
-rw-r--r--docs/html/resources/dashboard/opengl.jd12
-rw-r--r--docs/html/resources/dashboard/platform-versions.jd24
-rw-r--r--docs/html/resources/dashboard/screens.jd22
-rw-r--r--docs/html/resources/resources_toc.cs40
-rw-r--r--docs/html/sdk/android-2.3.3.jd2
-rw-r--r--docs/html/sdk/android-2.3.4.jd2
-rw-r--r--docs/html/sdk/android-2.3.jd2
-rw-r--r--docs/html/sdk/android-3.0.jd2
-rw-r--r--docs/html/sdk/android-3.1.jd2
-rw-r--r--docs/html/sdk/android-4.0.3.jd2
-rw-r--r--docs/html/sdk/android-4.0.jd2
-rw-r--r--docs/html/sdk/eclipse-adt.jd4
-rw-r--r--docs/html/sdk/index.jd1
-rw-r--r--docs/html/sdk/sdk_toc.cs27
-rw-r--r--docs/html/shareables/adl/2010Q2_Business_Overview.pdfbin3693971 -> 0 bytes
-rw-r--r--docs/html/shareables/adl/2010Q2_Market_Overview.pdfbin3875077 -> 0 bytes
-rw-r--r--docs/html/shareables/adl/2010Q2_SDK_Overview.pdfbin3529142 -> 0 bytes
-rw-r--r--docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdfbin3175989 -> 0 bytes
-rw-r--r--docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdfbin5417659 -> 0 bytes
-rwxr-xr-xdocs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdfbin6363157 -> 0 bytes
-rw-r--r--docs/html/shareables/icon_templates-v1.0.zipbin4001936 -> 0 bytes
-rw-r--r--docs/html/sitemap.txt27
-rw-r--r--docs/html/training/design-navigation/ancestral-temporal.jd8
-rw-r--r--docs/html/training/design-navigation/descendant-lateral.jd42
-rw-r--r--docs/html/training/design-navigation/index.jd2
-rw-r--r--docs/html/training/design-navigation/multiple-sizes.jd11
-rw-r--r--docs/html/training/design-navigation/wireframing.jd2
-rw-r--r--graphics/java/android/graphics/LinearGradient.java8
-rw-r--r--graphics/java/android/graphics/Rect.java22
-rw-r--r--graphics/java/android/graphics/RectF.java18
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java209
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp4
-rw-r--r--include/gui/DisplayEventReceiver.h4
-rw-r--r--include/media/AudioRecord.h9
-rw-r--r--include/media/AudioSystem.h2
-rw-r--r--include/media/IAudioPolicyService.h2
-rw-r--r--include/media/IOMX.h4
-rw-r--r--include/media/stagefright/AudioSource.h2
-rw-r--r--include/media/stagefright/OMXCodec.h1
-rw-r--r--include/utils/ResourceTypes.h605
-rw-r--r--libs/gui/Android.mk7
-rw-r--r--libs/hwui/Caches.cpp10
-rw-r--r--libs/hwui/Caches.h8
-rw-r--r--libs/hwui/DisplayListRenderer.cpp13
-rw-r--r--libs/hwui/DisplayListRenderer.h10
-rw-r--r--libs/hwui/Extensions.h3
-rw-r--r--libs/hwui/OpenGLRenderer.cpp16
-rw-r--r--libs/hwui/OpenGLRenderer.h5
-rw-r--r--libs/hwui/Properties.h5
-rw-r--r--libs/rs/driver/rsdGL.cpp4
-rw-r--r--libs/rs/driver/rsdGL.h4
-rw-r--r--libs/rs/driver/rsdRuntimeMath.cpp24
-rw-r--r--libs/rs/driver/rsdShader.cpp4
-rw-r--r--libs/rs/rs.spec4
-rw-r--r--libs/rs/rsAllocation.cpp36
-rw-r--r--libs/rs/rsAllocation.h14
-rw-r--r--libs/rs/rsThreadIO.cpp9
-rw-r--r--libs/rs/scriptc/rs_atomic.rsh2
-rw-r--r--libs/utils/ResourceTypes.cpp1145
-rw-r--r--media/java/android/media/AmrInputStream.java2
-rw-r--r--media/java/android/media/AsyncPlayer.java2
-rw-r--r--media/java/android/media/AudioManager.java47
-rw-r--r--media/java/android/media/AudioRecord.java2
-rw-r--r--media/java/android/media/AudioService.java61
-rw-r--r--media/java/android/media/AudioTrack.java7
-rw-r--r--media/java/android/media/ExifInterface.java2
-rw-r--r--media/java/android/media/MediaFile.java10
-rw-r--r--media/java/android/media/MediaInserter.java2
-rw-r--r--media/java/android/media/MediaRecorder.java5
-rw-r--r--media/java/android/media/MediaScanner.java34
-rw-r--r--media/java/android/media/MediaScannerConnection.java2
-rw-r--r--media/java/android/media/MiniThumbFile.java2
-rw-r--r--media/java/android/media/RemoteControlClient.java3
-rw-r--r--media/java/android/media/RingtoneManager.java2
-rwxr-xr-xmedia/java/android/mtp/MtpDatabase.java46
-rw-r--r--media/java/android/mtp/MtpPropertyGroup.java10
-rw-r--r--media/jni/Android.mk6
-rw-r--r--media/libmedia/AudioRecord.cpp10
-rw-r--r--media/libmedia/AudioSystem.cpp2
-rw-r--r--media/libmedia/IAudioPolicyService.cpp6
-rw-r--r--media/libmedia/IOMX.cpp7
-rw-r--r--media/libstagefright/Android.mk5
-rw-r--r--media/libstagefright/AudioSource.cpp2
-rw-r--r--media/libstagefright/AwesomePlayer.cpp34
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp2
-rw-r--r--media/libstagefright/OMXClient.cpp295
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp24
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC.cpp12
-rw-r--r--media/libstagefright/codecs/aacenc/Android.mk26
-rw-r--r--media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp560
-rw-r--r--media/libstagefright/codecs/aacenc/SoftAACEncoder.h82
-rw-r--r--media/libstagefright/codecs/aacenc/basic_op/oper_32b.c2
-rw-r--r--media/libstagefright/codecs/aacenc/basic_op/typedefs.h6
-rw-r--r--media/libstagefright/codecs/aacenc/inc/config.h2
-rw-r--r--media/libstagefright/codecs/aacenc/inc/sf_estim.h2
-rw-r--r--media/libstagefright/codecs/aacenc/inc/transform.h2
-rw-r--r--media/libstagefright/codecs/aacenc/src/aac_rom.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/aacenc.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/adj_thr.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s2
-rw-r--r--media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s2
-rw-r--r--media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s2
-rw-r--r--media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s13
-rw-r--r--media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s13
-rw-r--r--media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s7
-rw-r--r--media/libstagefright/codecs/aacenc/src/band_nrg.c2
-rw-r--r--media/libstagefright/codecs/amrnb/enc/Android.mk27
-rw-r--r--media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp404
-rw-r--r--media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h72
-rw-r--r--media/libstagefright/codecs/amrwbenc/Android.mk22
-rw-r--r--media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp459
-rw-r--r--media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h76
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/mem_align.c9
-rw-r--r--media/libstagefright/include/AwesomePlayer.h5
-rw-r--r--media/libstagefright/include/OMX.h2
-rw-r--r--media/libstagefright/omx/OMX.cpp2
-rw-r--r--media/libstagefright/omx/SoftOMXPlugin.cpp3
-rw-r--r--media/libstagefright/omx/tests/Android.mk6
-rw-r--r--media/libstagefright/timedtext/Android.mk5
-rw-r--r--media/libstagefright/timedtext/TimedTextDriver.cpp223
-rw-r--r--media/libstagefright/timedtext/TimedTextDriver.h81
-rw-r--r--media/libstagefright/timedtext/TimedTextInBandSource.cpp118
-rw-r--r--media/libstagefright/timedtext/TimedTextInBandSource.h55
-rw-r--r--media/libstagefright/timedtext/TimedTextParser.h75
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.cpp467
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.h100
-rw-r--r--media/libstagefright/timedtext/TimedTextSRTSource.cpp (renamed from media/libstagefright/timedtext/TimedTextParser.cpp)235
-rw-r--r--media/libstagefright/timedtext/TimedTextSRTSource.h75
-rw-r--r--media/libstagefright/timedtext/TimedTextSource.cpp53
-rw-r--r--media/libstagefright/timedtext/TimedTextSource.h61
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java177
-rw-r--r--native/include/android/configuration.h2
-rw-r--r--opengl/include/GLES/glext.h197
-rw-r--r--opengl/include/GLES2/gl2ext.h682
-rw-r--r--opengl/libs/EGL/Loader.cpp13
-rw-r--r--opengl/libs/EGL/egl.cpp23
-rw-r--r--opengl/libs/EGL/eglApi.cpp64
-rw-r--r--opengl/libs/EGL/egl_display.cpp41
-rw-r--r--opengl/libs/EGL/egl_display.h7
-rw-r--r--opengl/libs/EGL/egl_object.cpp36
-rw-r--r--opengl/libs/EGL/egl_object.h12
-rw-r--r--opengl/libs/EGL/egldefs.h1
-rw-r--r--opengl/libs/EGL/getProcAddress.cpp50
-rw-r--r--opengl/libs/GLES2/gl2.cpp14
-rw-r--r--opengl/libs/GLES2/gl2_api.in2
-rw-r--r--opengl/libs/GLES2/gl2ext_api.in191
-rwxr-xr-xopengl/libs/GLES2_dbg/generate_api_cpp.py219
-rwxr-xr-xopengl/libs/GLES2_dbg/generate_caller_cpp.py199
-rwxr-xr-xopengl/libs/GLES2_dbg/generate_debug_in.py80
-rwxr-xr-xopengl/libs/GLES2_dbg/generate_debugger_message_proto.py155
-rw-r--r--opengl/libs/GLES2_dbg/gl2_api_annotated.in426
-rw-r--r--opengl/libs/GLES2_dbg/src/api.cpp3540
-rw-r--r--opengl/libs/GLES2_dbg/src/api.h58
-rw-r--r--opengl/libs/GLES2_dbg/src/caller.cpp778
-rw-r--r--opengl/libs/GLES2_dbg/src/caller.h330
-rw-r--r--opengl/libs/GLES2_dbg/src/dbgcontext.cpp427
-rw-r--r--opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp1455
-rw-r--r--opengl/libs/GLES2_dbg/src/debugger_message.pb.h1187
-rw-r--r--opengl/libs/GLES2_dbg/src/egl.cpp54
-rw-r--r--opengl/libs/GLES2_dbg/src/header.h178
-rw-r--r--opengl/libs/GLES2_dbg/src/server.cpp312
-rw-r--r--opengl/libs/GLES2_dbg/src/vertex.cpp214
-rw-r--r--opengl/libs/GLES2_dbg/test/Android.mk37
-rw-r--r--opengl/libs/GLES2_dbg/test/test_main.cpp234
-rw-r--r--opengl/libs/GLES2_dbg/test/test_server.cpp245
-rw-r--r--opengl/libs/GLES2_dbg/test/test_socket.cpp468
-rw-r--r--opengl/libs/GLES_CM/gl.cpp14
-rw-r--r--opengl/libs/GLES_CM/gl_api.in2
-rw-r--r--opengl/libs/GLES_CM/glext_api.in42
-rw-r--r--opengl/libs/GLES_trace/gltrace.proto62
-rw-r--r--opengl/libs/GLES_trace/src/gltrace.pb.cpp121
-rw-r--r--opengl/libs/GLES_trace/src/gltrace.pb.h122
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_api.cpp2299
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_api.h65
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_eglapi.cpp8
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_fixup.cpp8
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_transport.cpp25
-rw-r--r--opengl/libs/GLES_trace/src/gltrace_transport.h7
-rwxr-xr-xopengl/libs/GLES_trace/tools/genapi.py4
-rw-r--r--opengl/libs/GLES_trace/tools/testgenapi.py6
-rw-r--r--opengl/libs/egl_impl.h1
-rw-r--r--opengl/libs/entries.in61
-rw-r--r--opengl/libs/enums.in114
-rw-r--r--opengl/libs/hooks.h7
-rwxr-xr-xopengl/libs/tools/glapigen3
-rw-r--r--opengl/libs/trace.in61
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml4
-rw-r--r--packages/SystemUI/res/values-be/strings.xml8
-rw-r--r--packages/SystemUI/res/values-de/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es-rUS-large/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml10
-rw-r--r--packages/SystemUI/res/values-et/strings.xml8
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml2
-rw-r--r--packages/SystemUI/res/values-rm/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java112
-rw-r--r--packages/VpnDialogs/AndroidManifest.xml4
-rw-r--r--packages/VpnDialogs/res/values/styles.xml7
-rw-r--r--packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java46
-rw-r--r--packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java55
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java9
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java19
-rw-r--r--policy/src/com/android/internal/policy/impl/LockScreen.java15
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java6
-rw-r--r--services/audioflinger/AudioFlinger.cpp46
-rw-r--r--services/audioflinger/AudioFlinger.h35
-rw-r--r--services/audioflinger/AudioPolicyService.cpp8
-rw-r--r--services/audioflinger/AudioPolicyService.h2
-rw-r--r--services/input/EventHub.cpp12
-rw-r--r--services/input/InputDispatcher.cpp4
-rw-r--r--services/input/InputDispatcher.h2
-rw-r--r--services/input/InputReader.cpp11
-rw-r--r--services/input/InputReader.h2
-rw-r--r--services/java/com/android/server/ConnectivityService.java6
-rw-r--r--services/java/com/android/server/EventLogTags.logtags4
-rw-r--r--services/java/com/android/server/LocationManagerService.java6
-rw-r--r--services/java/com/android/server/NetworkTimeUpdateService.java5
-rw-r--r--services/java/com/android/server/net/NetworkPolicyManagerService.java3
-rw-r--r--services/java/com/android/server/net/NetworkStatsCollection.java510
-rw-r--r--services/java/com/android/server/net/NetworkStatsRecorder.java341
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java1284
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java17
-rw-r--r--services/java/com/android/server/wm/WindowState.java13
-rw-r--r--services/surfaceflinger/Android.mk7
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.cpp15
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.h5
-rw-r--r--services/surfaceflinger/EventThread.cpp41
-rw-r--r--services/surfaceflinger/EventThread.h8
-rw-r--r--services/surfaceflinger/Layer.cpp46
-rw-r--r--services/surfaceflinger/Layer.h18
-rw-r--r--services/surfaceflinger/LayerBase.cpp11
-rw-r--r--services/surfaceflinger/LayerBase.h6
-rw-r--r--services/surfaceflinger/MessageQueue.cpp61
-rw-r--r--services/surfaceflinger/MessageQueue.h16
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp314
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h8
-rw-r--r--services/surfaceflinger/SurfaceTextureLayer.cpp4
-rw-r--r--services/surfaceflinger/tests/vsync/vsync.cpp2
-rw-r--r--services/tests/servicestests/res/raw/netstats_uid_v4bin0 -> 156516 bytes
-rw-r--r--services/tests/servicestests/res/raw/netstats_v1bin0 -> 18742 bytes
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java75
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java175
-rw-r--r--telephony/java/android/telephony/SignalStrength.java45
-rw-r--r--telephony/java/com/android/internal/telephony/CallManager.java39
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java5
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java24
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java6
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java10
-rw-r--r--telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java24
-rw-r--r--test-runner/src/android/test/mock/MockContentProvider.java8
-rw-r--r--test-runner/src/android/test/mock/MockIContentProvider.java8
-rw-r--r--tests/ActivityTests/res/anim/slow_enter.xml30
-rw-r--r--tests/ActivityTests/res/anim/slow_exit.xml30
-rw-r--r--tests/ActivityTests/res/interpolator/slow_enter.xml22
-rw-r--r--tests/ActivityTests/res/values/themes.xml25
-rw-r--r--tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java17
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java2
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java4
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java40
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java55
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs77
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs37
-rw-r--r--tests/TileBenchmark/res/values/strings.xml16
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java205
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java107
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java69
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java103
-rw-r--r--tools/aapt/AaptAssets.cpp11
-rw-r--r--tools/aapt/AaptAssets.h11
-rw-r--r--tools/aapt/Bundle.h17
-rw-r--r--tools/aapt/Command.cpp7
-rw-r--r--tools/aapt/Resource.cpp3
-rw-r--r--tools/aapt/ResourceTable.cpp90
-rw-r--r--tools/aapt/ResourceTable.h71
-rw-r--r--tools/aapt/StringPool.cpp244
-rw-r--r--tools/aapt/StringPool.h63
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java10
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java4
464 files changed, 20876 insertions, 17976 deletions
diff --git a/Android.mk b/Android.mk
index 83c4b5b1fe4e..ace7b7c163a4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -94,6 +94,7 @@ LOCAL_SRC_FILES += \
core/java/android/bluetooth/IBluetoothHealthCallback.aidl \
core/java/android/bluetooth/IBluetoothPbap.aidl \
core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
+ core/java/android/content/ICancelationSignal.aidl \
core/java/android/content/IClipboard.aidl \
core/java/android/content/IContentService.aidl \
core/java/android/content/IIntentReceiver.aidl \
@@ -449,8 +450,6 @@ web_docs_sample_code_flags := \
resources/samples/training/ads-and-ux "Mobile Advertisement Integration" \
-samplecode $(sample_dir)/MultiResolution \
resources/samples/MultiResolution "Multiple Resolutions" \
- -samplecode $(sample_dir)/NFCDemo \
- resources/samples/NFCDemo "NFC Demo" \
-samplecode $(sample_dir)/training/multiscreen/newsreader \
resources/samples/newsreader "News Reader" \
-samplecode $(sample_dir)/NotePad \
diff --git a/api/current.txt b/api/current.txt
index 8d6a135ca137..fced7f17d39a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -436,7 +436,7 @@ package android {
field public static final int fadeEnabled = 16843390; // 0x101027e
field public static final int fadeOffset = 16843383; // 0x1010277
field public static final int fadeScrollbars = 16843434; // 0x10102aa
- field public static final deprecated int fadingEdge = 16842975; // 0x10100df
+ field public static final int fadingEdge = 16842975; // 0x10100df
field public static final int fadingEdgeLength = 16842976; // 0x10100e0
field public static final int fastScrollAlwaysVisible = 16843573; // 0x1010335
field public static final int fastScrollEnabled = 16843302; // 0x1010226
@@ -2288,7 +2288,8 @@ package android.animation {
method public long getStagger(int);
method public long getStartDelay(int);
method public java.util.List<android.animation.LayoutTransition.TransitionListener> getTransitionListeners();
- method public void hideChild(android.view.ViewGroup, android.view.View);
+ method public deprecated void hideChild(android.view.ViewGroup, android.view.View);
+ method public void hideChild(android.view.ViewGroup, android.view.View, int);
method public boolean isChangingLayout();
method public boolean isRunning();
method public void removeChild(android.view.ViewGroup, android.view.View);
@@ -2300,7 +2301,8 @@ package android.animation {
method public void setInterpolator(int, android.animation.TimeInterpolator);
method public void setStagger(int, long);
method public void setStartDelay(int, long);
- method public void showChild(android.view.ViewGroup, android.view.View);
+ method public deprecated void showChild(android.view.ViewGroup, android.view.View);
+ method public void showChild(android.view.ViewGroup, android.view.View, int);
field public static final int APPEARING = 2; // 0x2
field public static final int CHANGE_APPEARING = 0; // 0x0
field public static final int CHANGE_DISAPPEARING = 1; // 0x1
@@ -2400,6 +2402,16 @@ package android.animation {
}
+package android.annotation {
+
+ public abstract class SuppressLint implements java.lang.annotation.Annotation {
+ }
+
+ public abstract class TargetApi implements java.lang.annotation.Annotation {
+ }
+
+}
+
package android.app {
public abstract class ActionBar {
@@ -4659,7 +4671,9 @@ package android.content {
public abstract class AsyncTaskLoader extends android.content.Loader {
ctor public AsyncTaskLoader(android.content.Context);
method public boolean cancelLoad();
+ method protected boolean isLoadInBackgroundCanceled();
method public abstract D loadInBackground();
+ method protected void onCancelLoadInBackground();
method public void onCanceled(D);
method protected D onLoadInBackground();
method public void setUpdateThrottle(long);
@@ -4701,6 +4715,18 @@ package android.content {
method public final void setResultExtras(android.os.Bundle);
}
+ public final class CancelationSignal {
+ ctor public CancelationSignal();
+ method public void cancel();
+ method public boolean isCanceled();
+ method public void setOnCancelListener(android.content.CancelationSignal.OnCancelListener);
+ method public void throwIfCanceled();
+ }
+
+ public static abstract interface CancelationSignal.OnCancelListener {
+ method public abstract void onCancel();
+ }
+
public class ClipData implements android.os.Parcelable {
ctor public ClipData(java.lang.CharSequence, java.lang.String[], android.content.ClipData.Item);
ctor public ClipData(android.content.ClipDescription, android.content.ClipData.Item);
@@ -4820,6 +4846,7 @@ package android.content {
method public android.os.ParcelFileDescriptor openPipeHelper(android.net.Uri, java.lang.String, android.os.Bundle, T, android.content.ContentProvider.PipeDataWriter<T>) throws java.io.FileNotFoundException;
method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+ method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.content.CancelationSignal);
method protected final void setPathPermissions(android.content.pm.PathPermission[]);
method protected final void setReadPermission(java.lang.String);
method protected final void setWritePermission(java.lang.String);
@@ -4843,6 +4870,7 @@ package android.content {
method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException, android.os.RemoteException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException, android.os.RemoteException;
method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) throws android.os.RemoteException;
+ method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.content.CancelationSignal) throws android.os.RemoteException;
method public boolean release();
method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
}
@@ -4929,6 +4957,7 @@ package android.content {
method public final java.io.OutputStream openOutputStream(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
+ method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.content.CancelationSignal);
method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
method public static void removeStatusChangeListener(java.lang.Object);
@@ -5351,6 +5380,7 @@ package android.content {
method public static android.content.Intent makeMainActivity(android.content.ComponentName);
method public static android.content.Intent makeMainSelectorActivity(java.lang.String, java.lang.String);
method public static android.content.Intent makeRestartActivityTask(android.content.ComponentName);
+ method public static java.lang.String normalizeMimeType(java.lang.String);
method public static android.content.Intent parseIntent(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static android.content.Intent parseUri(java.lang.String, int) throws java.net.URISyntaxException;
method public android.content.Intent putCharSequenceArrayListExtra(java.lang.String, java.util.ArrayList<java.lang.CharSequence>);
@@ -5399,13 +5429,16 @@ package android.content {
method public android.content.Intent setClassName(java.lang.String, java.lang.String);
method public android.content.Intent setComponent(android.content.ComponentName);
method public android.content.Intent setData(android.net.Uri);
+ method public android.content.Intent setDataAndNormalize(android.net.Uri);
method public android.content.Intent setDataAndType(android.net.Uri, java.lang.String);
+ method public android.content.Intent setDataAndTypeAndNormalize(android.net.Uri, java.lang.String);
method public void setExtrasClassLoader(java.lang.ClassLoader);
method public android.content.Intent setFlags(int);
method public android.content.Intent setPackage(java.lang.String);
method public void setSelector(android.content.Intent);
method public void setSourceBounds(android.graphics.Rect);
method public android.content.Intent setType(java.lang.String);
+ method public android.content.Intent setTypeAndNormalize(java.lang.String);
method public deprecated java.lang.String toURI();
method public java.lang.String toUri(int);
method public void writeToParcel(android.os.Parcel, int);
@@ -5777,6 +5810,11 @@ package android.content {
method public int getNumSuccessfulYieldPoints();
}
+ public class OperationCanceledException extends java.lang.RuntimeException {
+ ctor public OperationCanceledException();
+ ctor public OperationCanceledException(java.lang.String);
+ }
+
public class PeriodicSync implements android.os.Parcelable {
ctor public PeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle, long);
method public int describeContents();
@@ -6822,7 +6860,7 @@ package android.database {
public abstract interface Cursor {
method public abstract void close();
method public abstract void copyStringToBuffer(int, android.database.CharArrayBuffer);
- method public abstract void deactivate();
+ method public abstract deprecated void deactivate();
method public abstract byte[] getBlob(int);
method public abstract int getColumnCount();
method public abstract int getColumnIndex(java.lang.String);
@@ -7221,11 +7259,15 @@ package android.database.sqlite {
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory);
method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler);
method public android.database.Cursor query(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ method public android.database.Cursor query(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.content.CancelationSignal);
method public android.database.Cursor query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String);
method public android.database.Cursor query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
method public android.database.Cursor queryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ method public android.database.Cursor queryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.content.CancelationSignal);
method public android.database.Cursor rawQuery(java.lang.String, java.lang.String[]);
+ method public android.database.Cursor rawQuery(java.lang.String, java.lang.String[], android.content.CancelationSignal);
method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String);
+ method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String, android.content.CancelationSignal);
method public static int releaseMemory();
method public long replace(java.lang.String, java.lang.String, android.content.ContentValues);
method public long replaceOrThrow(java.lang.String, java.lang.String, android.content.ContentValues) throws android.database.SQLException;
@@ -7347,6 +7389,7 @@ package android.database.sqlite {
method public java.lang.String getTables();
method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String);
method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.content.CancelationSignal);
method public void setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
method public void setDistinct(boolean);
method public void setProjectionMap(java.util.Map<java.lang.String, java.lang.String>);
@@ -9050,14 +9093,17 @@ package android.graphics.drawable {
ctor public GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation, int[]);
method public void draw(android.graphics.Canvas);
method public int getOpacity();
+ method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
method public void setAlpha(int);
method public void setColor(int);
method public void setColorFilter(android.graphics.ColorFilter);
+ method public void setColors(int[]);
method public void setCornerRadii(float[]);
method public void setCornerRadius(float);
method public void setGradientCenter(float, float);
method public void setGradientRadius(float);
method public void setGradientType(int);
+ method public void setOrientation(android.graphics.drawable.GradientDrawable.Orientation);
method public void setShape(int);
method public void setSize(int, int);
method public void setStroke(int, int);
@@ -11834,6 +11880,7 @@ package android.net {
method public abstract boolean isHierarchical();
method public boolean isOpaque();
method public abstract boolean isRelative();
+ method public android.net.Uri normalize();
method public static android.net.Uri parse(java.lang.String);
method public abstract java.lang.String toString();
method public static android.net.Uri withAppendedPath(android.net.Uri, java.lang.String);
@@ -12616,6 +12663,7 @@ package android.nfc {
ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...);
ctor public NdefMessage(android.nfc.NdefRecord[]);
method public int describeContents();
+ method public int getByteArrayLength();
method public android.nfc.NdefRecord[] getRecords();
method public byte[] toByteArray();
method public void writeToParcel(android.os.Parcel, int);
@@ -12636,6 +12684,8 @@ package android.nfc {
method public short getTnf();
method public byte[] getType();
method public deprecated byte[] toByteArray();
+ method public java.lang.String toMimeType();
+ method public android.net.Uri toUri();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final byte[] RTD_ALTERNATIVE_CARRIER;
@@ -14427,6 +14477,7 @@ package android.os {
field public static final int HONEYCOMB_MR2 = 13; // 0xd
field public static final int ICE_CREAM_SANDWICH = 14; // 0xe
field public static final int ICE_CREAM_SANDWICH_MR1 = 15; // 0xf
+ field public static final int JELLY_BEAN = 10000; // 0x2710
}
public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
@@ -21391,6 +21442,7 @@ package android.util {
field public static final int DENSITY_MEDIUM = 160; // 0xa0
field public static final int DENSITY_TV = 213; // 0xd5
field public static final int DENSITY_XHIGH = 320; // 0x140
+ field public static final int DENSITY_XXHIGH = 480; // 0x1e0
field public float density;
field public int densityDpi;
field public int heightPixels;
@@ -23789,6 +23841,9 @@ package android.view {
method public android.view.ViewPropertyAnimator translationXBy(float);
method public android.view.ViewPropertyAnimator translationY(float);
method public android.view.ViewPropertyAnimator translationYBy(float);
+ method public android.view.ViewPropertyAnimator withEndAction(java.lang.Runnable);
+ method public android.view.ViewPropertyAnimator withLayer();
+ method public android.view.ViewPropertyAnimator withStartAction(java.lang.Runnable);
method public android.view.ViewPropertyAnimator x(float);
method public android.view.ViewPropertyAnimator xBy(float);
method public android.view.ViewPropertyAnimator y(float);
@@ -26676,6 +26731,7 @@ package android.widget {
method public void setOnValueChangedListener(android.widget.NumberPicker.OnValueChangeListener);
method public void setValue(int);
method public void setWrapSelectorWheel(boolean);
+ field public static final int SELECTOR_WHEEL_ITEM_COUNT = 5; // 0x5
}
public static abstract interface NumberPicker.Formatter {
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 83c881a74902..16dc5178504a 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -122,7 +122,7 @@ static void dumpstate() {
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");
- run_command("QTAGUID STATS INFO", 10, "su", "root", "cat", "/proc/net/xt_qtaguid/stats", NULL);
+ dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
dump_file("NETWORK ROUTES", "/proc/net/route");
dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
@@ -334,7 +334,7 @@ int main(int argc, char *argv[]) {
}
/* switch to non-root user and group */
- gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET };
+ gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET, AID_NET_BW_STATS };
if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
return -1;
diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk
index ea80c7d85dc8..8840867a9dfa 100644
--- a/cmds/servicemanager/Android.mk
+++ b/cmds/servicemanager/Android.mk
@@ -9,7 +9,4 @@ include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_MODULE := servicemanager
-ifeq ($(BOARD_USE_LVMX),true)
- LOCAL_CFLAGS += -DLVMX
-endif
include $(BUILD_EXECUTABLE)
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 42d8977339ee..4ed248962189 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -27,9 +27,6 @@ static struct {
unsigned uid;
const char *name;
} allowed[] = {
-#ifdef LVMX
- { AID_MEDIA, "com.lifevibes.mx.ipc" },
-#endif
{ AID_MEDIA, "media.audio_flinger" },
{ AID_MEDIA, "media.player" },
{ AID_MEDIA, "media.camera" },
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 613435df15e8..770305860895 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -38,7 +38,7 @@ static const int32_t kVideoBitRate = 512 * 1024;
static const int32_t kAudioBitRate = 12200;
static const int64_t kDurationUs = 10000000LL; // 10 seconds
-#if 1
+#if 0
class DummySource : public MediaSource {
public:
@@ -318,7 +318,7 @@ int main(int argc, char **argv) {
sp<MetaData> encMeta = new MetaData;
encMeta->setCString(kKeyMIMEType,
- 1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
+ 0 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
encMeta->setInt32(kKeySampleRate, kSampleRate);
encMeta->setInt32(kKeyChannelCount, kNumChannels);
encMeta->setInt32(kKeyMaxInputSize, 8192);
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 894f4287f709..274a9d52471c 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -1024,18 +1024,25 @@ public class LayoutTransition {
*
* @param parent The ViewGroup to which the View is being added.
* @param child The View being added to the ViewGroup.
+ * @param changesLayout Whether the removal will cause changes in the layout of other views
+ * in the container. INVISIBLE views becoming VISIBLE will not cause changes and thus will not
+ * affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
*/
- public void addChild(ViewGroup parent, View child) {
+ private void addChild(ViewGroup parent, View child, boolean changesLayout) {
// Want disappearing animations to finish up before proceeding
cancel(DISAPPEARING);
- // Also, cancel changing animations so that we start fresh ones from current locations
- cancel(CHANGE_APPEARING);
+ if (changesLayout) {
+ // Also, cancel changing animations so that we start fresh ones from current locations
+ cancel(CHANGE_APPEARING);
+ }
if (mListeners != null) {
for (TransitionListener listener : mListeners) {
listener.startTransition(this, parent, child, APPEARING);
}
}
- runChangeTransition(parent, child, APPEARING);
+ if (changesLayout) {
+ runChangeTransition(parent, child, APPEARING);
+ }
runAppearingTransition(parent, child);
}
@@ -1048,8 +1055,31 @@ public class LayoutTransition {
* @param parent The ViewGroup to which the View is being added.
* @param child The View being added to the ViewGroup.
*/
+ public void addChild(ViewGroup parent, View child) {
+ addChild(parent, child, true);
+ }
+
+ /**
+ * @deprecated Use {@link #showChild(android.view.ViewGroup, android.view.View, int)}.
+ */
+ @Deprecated
public void showChild(ViewGroup parent, View child) {
- addChild(parent, child);
+ addChild(parent, child, true);
+ }
+
+ /**
+ * This method is called by ViewGroup when a child view is about to be made visible in the
+ * container. This callback starts the process of a transition; we grab the starting
+ * values, listen for changes to all of the children of the container, and start appropriate
+ * animations.
+ *
+ * @param parent The ViewGroup in which the View is being made visible.
+ * @param child The View being made visible.
+ * @param oldVisibility The previous visibility value of the child View, either
+ * {@link View#GONE} or {@link View#INVISIBLE}.
+ */
+ public void showChild(ViewGroup parent, View child, int oldVisibility) {
+ addChild(parent, child, oldVisibility == View.GONE);
}
/**
@@ -1060,18 +1090,25 @@ public class LayoutTransition {
*
* @param parent The ViewGroup from which the View is being removed.
* @param child The View being removed from the ViewGroup.
+ * @param changesLayout Whether the removal will cause changes in the layout of other views
+ * in the container. Views becoming INVISIBLE will not cause changes and thus will not
+ * affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
*/
- public void removeChild(ViewGroup parent, View child) {
+ private void removeChild(ViewGroup parent, View child, boolean changesLayout) {
// Want appearing animations to finish up before proceeding
cancel(APPEARING);
- // Also, cancel changing animations so that we start fresh ones from current locations
- cancel(CHANGE_DISAPPEARING);
+ if (changesLayout) {
+ // Also, cancel changing animations so that we start fresh ones from current locations
+ cancel(CHANGE_DISAPPEARING);
+ }
if (mListeners != null) {
for (TransitionListener listener : mListeners) {
listener.startTransition(this, parent, child, DISAPPEARING);
}
}
- runChangeTransition(parent, child, DISAPPEARING);
+ if (changesLayout) {
+ runChangeTransition(parent, child, DISAPPEARING);
+ }
runDisappearingTransition(parent, child);
}
@@ -1084,8 +1121,31 @@ public class LayoutTransition {
* @param parent The ViewGroup from which the View is being removed.
* @param child The View being removed from the ViewGroup.
*/
+ public void removeChild(ViewGroup parent, View child) {
+ removeChild(parent, child, true);
+ }
+
+ /**
+ * @deprecated Use {@link #hideChild(android.view.ViewGroup, android.view.View, int)}.
+ */
+ @Deprecated
public void hideChild(ViewGroup parent, View child) {
- removeChild(parent, child);
+ removeChild(parent, child, true);
+ }
+
+ /**
+ * This method is called by ViewGroup when a child view is about to be hidden in
+ * container. This callback starts the process of a transition; we grab the starting
+ * values, listen for changes to all of the children of the container, and start appropriate
+ * animations.
+ *
+ * @param parent The parent ViewGroup of the View being hidden.
+ * @param child The View being hidden.
+ * @param newVisibility The new visibility value of the child View, either
+ * {@link View#GONE} or {@link View#INVISIBLE}.
+ */
+ public void hideChild(ViewGroup parent, View child, int newVisibility) {
+ removeChild(parent, child, newVisibility == View.GONE);
}
/**
diff --git a/core/java/android/annotation/SuppressLint.java b/core/java/android/annotation/SuppressLint.java
new file mode 100644
index 000000000000..2d3456b0ea46
--- /dev/null
+++ b/core/java/android/annotation/SuppressLint.java
@@ -0,0 +1,38 @@
+/*
+ * 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.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** Indicates that Lint should ignore the specified warnings for the annotated element. */
+@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+@Retention(RetentionPolicy.CLASS)
+public @interface SuppressLint {
+ /**
+ * The set of warnings (identified by the lint issue id) that should be
+ * ignored by lint. It is not an error to specify an unrecognized name.
+ */
+ String[] value();
+}
diff --git a/core/java/android/annotation/TargetApi.java b/core/java/android/annotation/TargetApi.java
new file mode 100644
index 000000000000..ea178903eb49
--- /dev/null
+++ b/core/java/android/annotation/TargetApi.java
@@ -0,0 +1,35 @@
+/*
+ * 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.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** Indicates that Lint should treat this type as targeting a given API level, no matter what the
+ project target is. */
+@Target({TYPE, METHOD, CONSTRUCTOR})
+@Retention(RetentionPolicy.CLASS)
+public @interface TargetApi {
+ /**
+ * This sets the target api level for the type..
+ */
+ int value();
+}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 4fe9cef2b7c2..9661b9e0d32b 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1442,9 +1442,10 @@ public class ActivityManager {
public int getLauncherLargeIconDensity() {
final Resources res = mContext.getResources();
final int density = res.getDisplayMetrics().densityDpi;
+ final int sw = res.getConfiguration().smallestScreenWidthDp;
- if ((res.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
- != Configuration.SCREENLAYOUT_SIZE_XLARGE) {
+ if (sw < 600) {
+ // Smaller than approx 7" tablets, use the regular icon size.
return density;
}
@@ -1456,9 +1457,13 @@ public class ActivityManager {
case DisplayMetrics.DENSITY_HIGH:
return DisplayMetrics.DENSITY_XHIGH;
case DisplayMetrics.DENSITY_XHIGH:
- return DisplayMetrics.DENSITY_MEDIUM * 2;
+ return DisplayMetrics.DENSITY_XXHIGH;
+ case DisplayMetrics.DENSITY_XXHIGH:
+ return DisplayMetrics.DENSITY_XHIGH * 2;
default:
- return density;
+ // The density is some abnormal value. Return some other
+ // abnormal value that is a reasonable scaling of it.
+ return (int)(density*1.5f);
}
}
@@ -1471,9 +1476,10 @@ public class ActivityManager {
public int getLauncherLargeIconSize() {
final Resources res = mContext.getResources();
final int size = res.getDimensionPixelSize(android.R.dimen.app_icon_size);
+ final int sw = res.getConfiguration().smallestScreenWidthDp;
- if ((res.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK)
- != Configuration.SCREENLAYOUT_SIZE_XLARGE) {
+ if (sw < 600) {
+ // Smaller than approx 7" tablets, use the regular icon size.
return size;
}
@@ -1487,9 +1493,13 @@ public class ActivityManager {
case DisplayMetrics.DENSITY_HIGH:
return (size * DisplayMetrics.DENSITY_XHIGH) / DisplayMetrics.DENSITY_HIGH;
case DisplayMetrics.DENSITY_XHIGH:
- return (size * DisplayMetrics.DENSITY_MEDIUM * 2) / DisplayMetrics.DENSITY_XHIGH;
+ return (size * DisplayMetrics.DENSITY_XXHIGH) / DisplayMetrics.DENSITY_XHIGH;
+ case DisplayMetrics.DENSITY_XXHIGH:
+ return (size * DisplayMetrics.DENSITY_XHIGH*2) / DisplayMetrics.DENSITY_XXHIGH;
default:
- return size;
+ // The density is some abnormal value. Return some other
+ // abnormal value that is a reasonable scaling of it.
+ return (int)(size*1.5f);
}
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 455d2f0d3db7..3c5f53a6efd8 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3741,7 +3741,6 @@ public final class ActivityThread {
}
final void handleTrimMemory(int level) {
- WindowManagerImpl.getDefault().trimMemory(level);
ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
@@ -3752,6 +3751,7 @@ public final class ActivityThread {
for (int i=0; i<N; i++) {
callbacks.get(i).onTrimMemory(level);
}
+ WindowManagerImpl.getDefault().trimMemory(level);
}
private void setupGraphicsSupport(LoadedApk info) {
@@ -3804,7 +3804,7 @@ public final class ActivityThread {
// implementation to use the pool executor. Normally, we use the
// serialized executor as the default. This has to happen in the
// main thread so the main looper is set right.
- if (data.appInfo.targetSdkVersion <= 12) {
+ if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -4413,7 +4413,7 @@ public final class ActivityThread {
});
}
- public static final ActivityThread systemMain() {
+ public static ActivityThread systemMain() {
HardwareRenderer.disable(true);
ActivityThread thread = new ActivityThread();
thread.attach(true);
@@ -4454,6 +4454,8 @@ public final class ActivityThread {
ActivityThread thread = new ActivityThread();
thread.attach(false);
+ AsyncTask.init();
+
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 8fa95b461ba4..d04e9db37a4a 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -551,7 +551,6 @@ public class SearchDialog extends Dialog {
try {
// If the intent was created from a suggestion, it will always have an explicit
// component here.
- Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toUri(0));
getContext().startActivity(intent);
// If the search switches to a different activity,
// SearchDialogWrapper#performActivityResuming
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index 0b54396ce90a..944ca6b9f33c 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -173,6 +173,7 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
if (DEBUG) Slog.v(TAG, "cancelLoad: cancelled=" + cancelled);
if (cancelled) {
mCancellingTask = mTask;
+ onCancelLoadInBackground();
}
mTask = null;
return cancelled;
@@ -256,6 +257,25 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
}
/**
+ * Override this method to try to abort the computation currently taking
+ * place on a background thread.
+ *
+ * Note that when this method is called, it is possible that {@link #loadInBackground}
+ * has not started yet or has already completed.
+ */
+ protected void onCancelLoadInBackground() {
+ }
+
+ /**
+ * Returns true if the current execution of {@link #loadInBackground()} is being canceled.
+ *
+ * @return True if the current execution of {@link #loadInBackground()} is being canceled.
+ */
+ protected boolean isLoadInBackgroundCanceled() {
+ return mCancellingTask != null;
+ }
+
+ /**
* Locks the current thread until the loader completes the current load
* operation. Returns immediately if there is no load operation running.
* Should not be called from the UI thread: calling it from the UI
diff --git a/core/java/android/content/CancelationSignal.java b/core/java/android/content/CancelationSignal.java
new file mode 100644
index 000000000000..58cf59d485be
--- /dev/null
+++ b/core/java/android/content/CancelationSignal.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import android.os.RemoteException;
+
+/**
+ * Provides the ability to cancel an operation in progress.
+ */
+public final class CancelationSignal {
+ private boolean mIsCanceled;
+ private OnCancelListener mOnCancelListener;
+ private ICancelationSignal mRemote;
+
+ /**
+ * Creates a cancelation signal, initially not canceled.
+ */
+ public CancelationSignal() {
+ }
+
+ /**
+ * Returns true if the operation has been canceled.
+ *
+ * @return True if the operation has been canceled.
+ */
+ public boolean isCanceled() {
+ synchronized (this) {
+ return mIsCanceled;
+ }
+ }
+
+ /**
+ * Throws {@link OperationCanceledException} if the operation has been canceled.
+ *
+ * @throws OperationCanceledException if the operation has been canceled.
+ */
+ public void throwIfCanceled() {
+ if (isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+
+ /**
+ * Cancels the operation and signals the cancelation listener.
+ * If the operation has not yet started, then it will be canceled as soon as it does.
+ */
+ public void cancel() {
+ synchronized (this) {
+ if (!mIsCanceled) {
+ mIsCanceled = true;
+ if (mOnCancelListener != null) {
+ mOnCancelListener.onCancel();
+ }
+ if (mRemote != null) {
+ try {
+ mRemote.cancel();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the cancelation listener to be called when canceled.
+ * If {@link CancelationSignal#cancel} has already been called, then the provided
+ * listener is invoked immediately.
+ *
+ * The listener is called while holding the cancelation signal's lock which is
+ * also held while registering or unregistering the listener. Because of the lock,
+ * it is not possible for the listener to run after it has been unregistered.
+ * This design choice makes it easier for clients of {@link CancelationSignal} to
+ * prevent race conditions related to listener registration and unregistration.
+ *
+ * @param listener The cancelation listener, or null to remove the current listener.
+ */
+ public void setOnCancelListener(OnCancelListener listener) {
+ synchronized (this) {
+ mOnCancelListener = listener;
+ if (mIsCanceled && listener != null) {
+ listener.onCancel();
+ }
+ }
+ }
+
+ /**
+ * Sets the remote transport.
+ *
+ * @param remote The remote transport, or null to remove.
+ *
+ * @hide
+ */
+ public void setRemote(ICancelationSignal remote) {
+ synchronized (this) {
+ mRemote = remote;
+ if (mIsCanceled && remote != null) {
+ try {
+ remote.cancel();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a transport that can be returned back to the caller of
+ * a Binder function and subsequently used to dispatch a cancelation signal.
+ *
+ * @return The new cancelation signal transport.
+ *
+ * @hide
+ */
+ public static ICancelationSignal createTransport() {
+ return new Transport();
+ }
+
+ /**
+ * Given a locally created transport, returns its associated cancelation signal.
+ *
+ * @param transport The locally created transport, or null if none.
+ * @return The associated cancelation signal, or null if none.
+ *
+ * @hide
+ */
+ public static CancelationSignal fromTransport(ICancelationSignal transport) {
+ if (transport instanceof Transport) {
+ return ((Transport)transport).mCancelationSignal;
+ }
+ return null;
+ }
+
+ /**
+ * Listens for cancelation.
+ */
+ public interface OnCancelListener {
+ /**
+ * Called when {@link CancelationSignal#cancel} is invoked.
+ */
+ void onCancel();
+ }
+
+ private static final class Transport extends ICancelationSignal.Stub {
+ final CancelationSignal mCancelationSignal = new CancelationSignal();
+
+ @Override
+ public void cancel() throws RemoteException {
+ mCancelationSignal.cancel();
+ }
+ }
+}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 116ca4858774..adbeb6a82b1e 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -29,6 +29,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Process;
+import android.os.RemoteException;
import android.util.Log;
import java.io.File;
@@ -174,28 +175,33 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return getContentProvider().getClass().getName();
}
+ @Override
public Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
+ String selection, String[] selectionArgs, String sortOrder,
+ ICancelationSignal cancelationSignal) {
enforceReadPermission(uri);
- return ContentProvider.this.query(uri, projection, selection,
- selectionArgs, sortOrder);
+ return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
+ CancelationSignal.fromTransport(cancelationSignal));
}
+ @Override
public String getType(Uri uri) {
return ContentProvider.this.getType(uri);
}
-
+ @Override
public Uri insert(Uri uri, ContentValues initialValues) {
enforceWritePermission(uri);
return ContentProvider.this.insert(uri, initialValues);
}
+ @Override
public int bulkInsert(Uri uri, ContentValues[] initialValues) {
enforceWritePermission(uri);
return ContentProvider.this.bulkInsert(uri, initialValues);
}
+ @Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
for (ContentProviderOperation operation : operations) {
@@ -210,17 +216,20 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return ContentProvider.this.applyBatch(operations);
}
+ @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
enforceWritePermission(uri);
return ContentProvider.this.delete(uri, selection, selectionArgs);
}
+ @Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
enforceWritePermission(uri);
return ContentProvider.this.update(uri, values, selection, selectionArgs);
}
+ @Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
@@ -228,6 +237,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return ContentProvider.this.openFile(uri, mode);
}
+ @Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode)
throws FileNotFoundException {
if (mode != null && mode.startsWith("rw")) enforceWritePermission(uri);
@@ -235,6 +245,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return ContentProvider.this.openAssetFile(uri, mode);
}
+ @Override
public Bundle call(String method, String arg, Bundle extras) {
return ContentProvider.this.call(method, arg, extras);
}
@@ -251,6 +262,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return ContentProvider.this.openTypedAssetFile(uri, mimeType, opts);
}
+ @Override
+ public ICancelationSignal createCancelationSignal() throws RemoteException {
+ return CancelationSignal.createTransport();
+ }
+
private void enforceReadPermission(Uri uri) {
final int uid = Binder.getCallingUid();
if (uid == mMyUid) {
@@ -541,6 +557,75 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
String selection, String[] selectionArgs, String sortOrder);
/**
+ * Implement this to handle query requests from clients with support for cancelation.
+ * This method can be called from multiple threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
+ * and Threads</a>.
+ * <p>
+ * Example client call:<p>
+ * <pre>// Request a specific record.
+ * Cursor managedCursor = managedQuery(
+ ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
+ projection, // Which columns to return.
+ null, // WHERE clause.
+ null, // WHERE clause value substitution
+ People.NAME + " ASC"); // Sort order.</pre>
+ * Example implementation:<p>
+ * <pre>// SQLiteQueryBuilder is a helper class that creates the
+ // proper SQL syntax for us.
+ SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
+
+ // Set the table we're querying.
+ qBuilder.setTables(DATABASE_TABLE_NAME);
+
+ // If the query ends in a specific record number, we're
+ // being asked for a specific record, so set the
+ // WHERE clause in our query.
+ if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
+ qBuilder.appendWhere("_id=" + uri.getPathLeafId());
+ }
+
+ // Make the query.
+ Cursor c = qBuilder.query(mDb,
+ projection,
+ selection,
+ selectionArgs,
+ groupBy,
+ having,
+ sortOrder);
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+ return c;</pre>
+ * <p>
+ * If you implement this method then you must also implement the version of
+ * {@link #query(Uri, String[], String, String[], String)} that does not take a cancelation
+ * provider to ensure correct operation on older versions of the Android Framework in
+ * which the cancelation signal overload was not available.
+ *
+ * @param uri The URI to query. This will be the full URI sent by the client;
+ * if the client is requesting a specific record, the URI will end in a record number
+ * that the implementation should parse and add to a WHERE or HAVING clause, specifying
+ * that _id value.
+ * @param projection The list of columns to put into the cursor. If
+ * null all columns are included.
+ * @param selection A selection criteria to apply when filtering rows.
+ * If null then all rows are included.
+ * @param selectionArgs You may include ?s in selection, which will be replaced by
+ * the values from selectionArgs, in order that they appear in the selection.
+ * The values will be bound as Strings.
+ * @param sortOrder How the rows in the cursor should be sorted.
+ * If null then the provider is free to define the sort order.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return a Cursor or null.
+ */
+ public Cursor query(Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder,
+ CancelationSignal cancelationSignal) {
+ return query(uri, projection, selection, selectionArgs, sortOrder);
+ }
+
+ /**
* Implement this to handle requests for the MIME type of the data at the
* given URI. The returned MIME type should start with
* <code>vnd.android.cursor.item</code> for a single record,
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 0540109b4f91..9a1fa652a42c 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -47,7 +47,20 @@ public class ContentProviderClient {
/** See {@link ContentProvider#query ContentProvider.query} */
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sortOrder) throws RemoteException {
- return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder);
+ return query(url, projection, selection, selectionArgs, sortOrder, null);
+ }
+
+ /** See {@link ContentProvider#query ContentProvider.query} */
+ public Cursor query(Uri url, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder, CancelationSignal cancelationSignal)
+ throws RemoteException {
+ ICancelationSignal remoteCancelationSignal = null;
+ if (cancelationSignal != null) {
+ remoteCancelationSignal = mContentProvider.createCancelationSignal();
+ cancelationSignal.setRemote(remoteCancelationSignal);
+ }
+ return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder,
+ remoteCancelationSignal);
}
/** See {@link ContentProvider#getType ContentProvider.getType} */
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index b089bf2b6584..e0e277aa4a59 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -21,7 +21,6 @@ import android.database.BulkCursorNative;
import android.database.BulkCursorToCursorAdaptor;
import android.database.Cursor;
import android.database.CursorToBulkCursorAdaptor;
-import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.database.IBulkCursor;
import android.database.IContentObserver;
@@ -41,8 +40,6 @@ import java.util.ArrayList;
* {@hide}
*/
abstract public class ContentProviderNative extends Binder implements IContentProvider {
- private static final String TAG = "ContentProvider";
-
public ContentProviderNative()
{
attachInterface(this, descriptor);
@@ -108,8 +105,11 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
String sortOrder = data.readString();
IContentObserver observer = IContentObserver.Stub.asInterface(
data.readStrongBinder());
+ ICancelationSignal cancelationSignal = ICancelationSignal.Stub.asInterface(
+ data.readStrongBinder());
- Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder);
+ Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder,
+ cancelationSignal);
if (cursor != null) {
CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor(
cursor, observer, getProviderName());
@@ -295,6 +295,16 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
}
return true;
}
+
+ case CREATE_CANCELATION_SIGNAL_TRANSACTION:
+ {
+ data.enforceInterface(IContentProvider.descriptor);
+
+ ICancelationSignal cancelationSignal = createCancelationSignal();
+ reply.writeNoException();
+ reply.writeStrongBinder(cancelationSignal.asBinder());
+ return true;
+ }
}
} catch (Exception e) {
DatabaseUtils.writeExceptionToParcel(reply, e);
@@ -324,7 +334,8 @@ final class ContentProviderProxy implements IContentProvider
}
public Cursor query(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) throws RemoteException {
+ String[] selectionArgs, String sortOrder, ICancelationSignal cancelationSignal)
+ throws RemoteException {
BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -352,6 +363,7 @@ final class ContentProviderProxy implements IContentProvider
}
data.writeString(sortOrder);
data.writeStrongBinder(adaptor.getObserver().asBinder());
+ data.writeStrongBinder(cancelationSignal != null ? cancelationSignal.asBinder() : null);
mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
@@ -620,5 +632,24 @@ final class ContentProviderProxy implements IContentProvider
}
}
+ public ICancelationSignal createCancelationSignal() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
+
+ mRemote.transact(IContentProvider.CREATE_CANCELATION_SIGNAL_TRANSACTION,
+ data, reply, 0);
+
+ DatabaseUtils.readExceptionFromParcel(reply);
+ ICancelationSignal cancelationSignal = ICancelationSignal.Stub.asInterface(
+ reply.readStrongBinder());
+ return cancelationSignal;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0debb848b23c..e79475a38218 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -22,6 +22,7 @@ import android.accounts.Account;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
import android.app.AppGlobals;
+import android.content.ContentProvider.Transport;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
@@ -302,13 +303,62 @@ public abstract class ContentResolver {
*/
public final Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
+ return query(uri, projection, selection, selectionArgs, sortOrder, null);
+ }
+
+ /**
+ * <p>
+ * Query the given URI, returning a {@link Cursor} over the result set.
+ * </p>
+ * <p>
+ * For best performance, the caller should follow these guidelines:
+ * <ul>
+ * <li>Provide an explicit projection, to prevent
+ * reading data from storage that aren't going to be used.</li>
+ * <li>Use question mark parameter markers such as 'phone=?' instead of
+ * explicit values in the {@code selection} parameter, so that queries
+ * that differ only by those values will be recognized as the same
+ * for caching purposes.</li>
+ * </ul>
+ * </p>
+ *
+ * @param uri The URI, using the content:// scheme, for the content to
+ * retrieve.
+ * @param projection A list of which columns to return. Passing null will
+ * return all columns, which is inefficient.
+ * @param selection A filter declaring which rows to return, formatted as an
+ * SQL WHERE clause (excluding the WHERE itself). Passing null will
+ * return all rows for the given URI.
+ * @param selectionArgs You may include ?s in selection, which will be
+ * replaced by the values from selectionArgs, in the order that they
+ * appear in the selection. The values will be bound as Strings.
+ * @param sortOrder How to order the rows, formatted as an SQL ORDER BY
+ * clause (excluding the ORDER BY itself). Passing null will use the
+ * default sort order, which may be unordered.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return A Cursor object, which is positioned before the first entry, or null
+ * @see Cursor
+ */
+ public final Cursor query(final Uri uri, String[] projection,
+ String selection, String[] selectionArgs, String sortOrder,
+ CancelationSignal cancelationSignal) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
return null;
}
try {
long startTime = SystemClock.uptimeMillis();
- Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
+
+ ICancelationSignal remoteCancelationSignal = null;
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ remoteCancelationSignal = provider.createCancelationSignal();
+ cancelationSignal.setRemote(remoteCancelationSignal);
+ }
+ Cursor qCursor = provider.query(uri, projection,
+ selection, selectionArgs, sortOrder, remoteCancelationSignal);
if (qCursor == null) {
releaseProvider(provider);
return null;
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 7af535b424bc..6e4aca852c93 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -19,7 +19,6 @@ package android.content;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
-import android.os.AsyncTask;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -49,18 +48,42 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> {
String mSortOrder;
Cursor mCursor;
+ CancelationSignal mCancelationSignal;
/* Runs on a worker thread */
@Override
public Cursor loadInBackground() {
- Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
- mSelectionArgs, mSortOrder);
- if (cursor != null) {
- // Ensure the cursor window is filled
- cursor.getCount();
- registerContentObserver(cursor, mObserver);
+ synchronized (this) {
+ if (isLoadInBackgroundCanceled()) {
+ throw new OperationCanceledException();
+ }
+ mCancelationSignal = new CancelationSignal();
+ }
+ try {
+ Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
+ mSelectionArgs, mSortOrder, mCancelationSignal);
+ if (cursor != null) {
+ // Ensure the cursor window is filled
+ cursor.getCount();
+ registerContentObserver(cursor, mObserver);
+ }
+ return cursor;
+ } finally {
+ synchronized (this) {
+ mCancelationSignal = null;
+ }
+ }
+ }
+
+ @Override
+ protected void onCancelLoadInBackground() {
+ super.onCancelLoadInBackground();
+
+ synchronized (this) {
+ if (mCancelationSignal != null) {
+ mCancelationSignal.cancel();
+ }
}
- return cursor;
}
/**
diff --git a/core/java/android/content/ICancelationSignal.aidl b/core/java/android/content/ICancelationSignal.aidl
new file mode 100644
index 000000000000..3f5a24d82b54
--- /dev/null
+++ b/core/java/android/content/ICancelationSignal.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+/**
+ * @hide
+ */
+interface ICancelationSignal {
+ oneway void cancel();
+}
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 2a67ff8dac54..f52157fb8aa8 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -34,7 +34,8 @@ import java.util.ArrayList;
*/
public interface IContentProvider extends IInterface {
public Cursor query(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) throws RemoteException;
+ String[] selectionArgs, String sortOrder, ICancelationSignal cancelationSignal)
+ throws RemoteException;
public String getType(Uri url) throws RemoteException;
public Uri insert(Uri url, ContentValues initialValues)
throws RemoteException;
@@ -50,6 +51,7 @@ public interface IContentProvider extends IInterface {
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException;
public Bundle call(String method, String arg, Bundle extras) throws RemoteException;
+ public ICancelationSignal createCancelationSignal() throws RemoteException;
// Data interchange.
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException;
@@ -71,4 +73,5 @@ public interface IContentProvider extends IInterface {
static final int CALL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 20;
static final int GET_STREAM_TYPES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 21;
static final int OPEN_TYPED_ASSET_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 22;
+ static final int CREATE_CANCELATION_SIGNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 23;
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e3b1f541d211..fbc1b2b7eca1 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -43,6 +43,7 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Set;
/**
@@ -4420,22 +4421,24 @@ public class Intent implements Parcelable, Cloneable {
/**
* Set the data this intent is operating on. This method automatically
- * clears any type that was previously set by {@link #setType}.
+ * clears any type that was previously set by {@link #setType} or
+ * {@link #setTypeAndNormalize}.
*
- * <p><em>Note: scheme and host name matching in the Android framework is
- * case-sensitive, unlike the formal RFC. As a result,
- * you should always ensure that you write your Uri with these elements
- * using lower case letters, and normalize any Uris you receive from
- * outside of Android to ensure the scheme and host is lower case.</em></p>
+ * <p><em>Note: scheme matching in the Android framework is
+ * case-sensitive, unlike the formal RFC. As a result,
+ * you should always write your Uri with a lower case scheme,
+ * or use {@link Uri#normalize} or
+ * {@link #setDataAndNormalize}
+ * to ensure that the scheme is converted to lower case.</em>
*
- * @param data The URI of the data this intent is now targeting.
+ * @param data The Uri of the data this intent is now targeting.
*
* @return Returns the same Intent object, for chaining multiple calls
* into a single statement.
*
* @see #getData
- * @see #setType
- * @see #setDataAndType
+ * @see #setDataAndNormalize
+ * @see android.net.Intent#normalize
*/
public Intent setData(Uri data) {
mData = data;
@@ -4444,16 +4447,45 @@ public class Intent implements Parcelable, Cloneable {
}
/**
- * Set an explicit MIME data type. This is used to create intents that
- * only specify a type and not data, for example to indicate the type of
- * data to return. This method automatically clears any data that was
- * previously set by {@link #setData}.
+ * Normalize and set the data this intent is operating on.
+ *
+ * <p>This method automatically clears any type that was
+ * previously set (for example, by {@link #setType}).
+ *
+ * <p>The data Uri is normalized using
+ * {@link android.net.Uri#normalize} before it is set,
+ * so really this is just a convenience method for
+ * <pre>
+ * setData(data.normalize())
+ * </pre>
+ *
+ * @param data The Uri of the data this intent is now targeting.
+ *
+ * @return Returns the same Intent object, for chaining multiple calls
+ * into a single statement.
+ *
+ * @see #getData
+ * @see #setType
+ * @see android.net.Uri#normalize
+ */
+ public Intent setDataAndNormalize(Uri data) {
+ return setData(data.normalize());
+ }
+
+ /**
+ * Set an explicit MIME data type.
+ *
+ * <p>This is used to create intents that only specify a type and not data,
+ * for example to indicate the type of data to return.
+ *
+ * <p>This method automatically clears any data that was
+ * previously set (for example by {@link #setData}).
*
* <p><em>Note: MIME type matching in the Android framework is
* case-sensitive, unlike formal RFC MIME types. As a result,
* you should always write your MIME types with lower case letters,
- * and any MIME types you receive from outside of Android should be
- * converted to lower case before supplying them here.</em></p>
+ * or use {@link #normalizeMimeType} or {@link #setTypeAndNormalize}
+ * to ensure that it is converted to lower case.</em>
*
* @param type The MIME type of the data being handled by this intent.
*
@@ -4461,8 +4493,9 @@ public class Intent implements Parcelable, Cloneable {
* into a single statement.
*
* @see #getType
- * @see #setData
+ * @see #setTypeAndNormalize
* @see #setDataAndType
+ * @see #normalizeMimeType
*/
public Intent setType(String type) {
mData = null;
@@ -4471,26 +4504,58 @@ public class Intent implements Parcelable, Cloneable {
}
/**
+ * Normalize and set an explicit MIME data type.
+ *
+ * <p>This is used to create intents that only specify a type and not data,
+ * for example to indicate the type of data to return.
+ *
+ * <p>This method automatically clears any data that was
+ * previously set (for example by {@link #setData}).
+ *
+ * <p>The MIME type is normalized using
+ * {@link #normalizeMimeType} before it is set,
+ * so really this is just a convenience method for
+ * <pre>
+ * setType(Intent.normalizeMimeType(type))
+ * </pre>
+ *
+ * @param type The MIME type of the data being handled by this intent.
+ *
+ * @return Returns the same Intent object, for chaining multiple calls
+ * into a single statement.
+ *
+ * @see #getType
+ * @see #setData
+ * @see #normalizeMimeType
+ */
+ public Intent setTypeAndNormalize(String type) {
+ return setType(normalizeMimeType(type));
+ }
+
+ /**
* (Usually optional) Set the data for the intent along with an explicit
* MIME data type. This method should very rarely be used -- it allows you
* to override the MIME type that would ordinarily be inferred from the
* data with your own type given here.
*
- * <p><em>Note: MIME type, Uri scheme, and host name matching in the
+ * <p><em>Note: MIME type and Uri scheme matching in the
* Android framework is case-sensitive, unlike the formal RFC definitions.
* As a result, you should always write these elements with lower case letters,
- * and normalize any MIME types or Uris you receive from
- * outside of Android to ensure these elements are lower case before
- * supplying them here.</em></p>
+ * or use {@link #normalizeMimeType} or {@link android.net.Uri#normalize} or
+ * {@link #setDataAndTypeAndNormalize}
+ * to ensure that they are converted to lower case.</em>
*
- * @param data The URI of the data this intent is now targeting.
+ * @param data The Uri of the data this intent is now targeting.
* @param type The MIME type of the data being handled by this intent.
*
* @return Returns the same Intent object, for chaining multiple calls
* into a single statement.
*
- * @see #setData
* @see #setType
+ * @see #setData
+ * @see #normalizeMimeType
+ * @see android.net.Uri#normalize
+ * @see #setDataAndTypeAndNormalize
*/
public Intent setDataAndType(Uri data, String type) {
mData = data;
@@ -4499,6 +4564,35 @@ public class Intent implements Parcelable, Cloneable {
}
/**
+ * (Usually optional) Normalize and set both the data Uri and an explicit
+ * MIME data type. This method should very rarely be used -- it allows you
+ * to override the MIME type that would ordinarily be inferred from the
+ * data with your own type given here.
+ *
+ * <p>The data Uri and the MIME type are normalize using
+ * {@link android.net.Uri#normalize} and {@link #normalizeMimeType}
+ * before they are set, so really this is just a convenience method for
+ * <pre>
+ * setDataAndType(data.normalize(), Intent.normalizeMimeType(type))
+ * </pre>
+ *
+ * @param data The Uri of the data this intent is now targeting.
+ * @param type The MIME type of the data being handled by this intent.
+ *
+ * @return Returns the same Intent object, for chaining multiple calls
+ * into a single statement.
+ *
+ * @see #setType
+ * @see #setData
+ * @see #setDataAndType
+ * @see #normalizeMimeType
+ * @see android.net.Uri#normalize
+ */
+ public Intent setDataAndTypeAndNormalize(Uri data, String type) {
+ return setDataAndType(data.normalize(), normalizeMimeType(type));
+ }
+
+ /**
* Add a new category to the intent. Categories provide additional detail
* about the action the intent is perform. When resolving an intent, only
* activities that provide <em>all</em> of the requested categories will be
@@ -5566,7 +5660,7 @@ public class Intent implements Parcelable, Cloneable {
*
* <ul>
* <li> action, as set by {@link #setAction}.
- * <li> data URI and MIME type, as set by {@link #setData(Uri)},
+ * <li> data Uri and MIME type, as set by {@link #setData(Uri)},
* {@link #setType(String)}, or {@link #setDataAndType(Uri, String)}.
* <li> categories, as set by {@link #addCategory}.
* <li> package, as set by {@link #setPackage}.
@@ -6229,4 +6323,38 @@ public class Intent implements Parcelable, Cloneable {
return intent;
}
+
+ /**
+ * Normalize a MIME data type.
+ *
+ * <p>A normalized MIME type has white-space trimmed,
+ * content-type parameters removed, and is lower-case.
+ * This aligns the type with Android best practices for
+ * intent filtering.
+ *
+ * <p>For example, "text/plain; charset=utf-8" becomes "text/plain".
+ * "text/x-vCard" becomes "text/x-vcard".
+ *
+ * <p>All MIME types received from outside Android (such as user input,
+ * or external sources like Bluetooth, NFC, or the Internet) should
+ * be normalized before they are used to create an Intent.
+ *
+ * @param type MIME data type to normalize
+ * @return normalized MIME data type, or null if the input was null
+ * @see {@link #setType}
+ * @see {@link #setTypeAndNormalize}
+ */
+ public static String normalizeMimeType(String type) {
+ if (type == null) {
+ return null;
+ }
+
+ type = type.trim().toLowerCase(Locale.US);
+
+ final int semicolonIndex = type.indexOf(';');
+ if (semicolonIndex != -1) {
+ type = type.substring(0, semicolonIndex);
+ }
+ return type;
+ }
}
diff --git a/core/java/android/content/OperationCanceledException.java b/core/java/android/content/OperationCanceledException.java
new file mode 100644
index 000000000000..24afcfa3ff67
--- /dev/null
+++ b/core/java/android/content/OperationCanceledException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+/**
+ * An exception type that is thrown when an operation in progress is canceled.
+ *
+ * @see CancelationSignal
+ */
+public class OperationCanceledException extends RuntimeException {
+ public OperationCanceledException() {
+ this(null);
+ }
+
+ public OperationCanceledException(String message) {
+ super(message != null ? message : "The operation has been canceled.");
+ }
+}
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 601566841e65..e04b2f75f27a 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -347,6 +347,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
sb.append(" (no locale)");
}
switch (textLayoutDirection) {
+ case LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE: /* ltr not interesting */ break;
case LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break;
default: sb.append(" layoutdir="); sb.append(textLayoutDirection); break;
}
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index a9a71cfb5a4b..59ec89d5382d 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -341,6 +341,7 @@ public interface Cursor {
* Deactivates the Cursor, making all calls on it fail until {@link #requery} is called.
* Inactive Cursors use fewer resources than active Cursors.
* Calling {@link #requery} will make the cursor active again.
+ * @deprecated Since {@link #requery()} is deprecated, so too is this.
*/
void deactivate();
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 72f62fd6aef1..710bd5333b45 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -19,6 +19,8 @@ package android.database.sqlite;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
+import android.content.CancelationSignal;
+import android.content.OperationCanceledException;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
@@ -82,7 +84,7 @@ import java.util.regex.Pattern;
*
* @hide
*/
-public final class SQLiteConnection {
+public final class SQLiteConnection implements CancelationSignal.OnCancelListener {
private static final String TAG = "SQLiteConnection";
private static final boolean DEBUG = false;
@@ -108,6 +110,12 @@ public final class SQLiteConnection {
private boolean mOnlyAllowReadOnlyOperations;
+ // The number of times attachCancelationSignal has been called.
+ // Because SQLite statement execution can be re-entrant, we keep track of how many
+ // times we have attempted to attach a cancelation signal to the connection so that
+ // we can ensure that we detach the signal at the right time.
+ private int mCancelationSignalAttachCount;
+
private static native int nativeOpen(String path, int openFlags, String label,
boolean enableTrace, boolean enableProfile);
private static native void nativeClose(int connectionPtr);
@@ -145,6 +153,8 @@ public final class SQLiteConnection {
int connectionPtr, int statementPtr, int windowPtr,
int startPos, int requiredPos, boolean countAllRows);
private static native int nativeGetDbLookaside(int connectionPtr);
+ private static native void nativeCancel(int connectionPtr);
+ private static native void nativeResetCancel(int connectionPtr, boolean cancelable);
private SQLiteConnection(SQLiteConnectionPool pool,
SQLiteDatabaseConfiguration configuration,
@@ -345,11 +355,14 @@ public final class SQLiteConnection {
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public void execute(String sql, Object[] bindArgs) {
+ public void execute(String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -361,7 +374,12 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- nativeExecute(mConnectionPtr, statement.mStatementPtr);
+ attachCancelationSignal(cancelationSignal);
+ try {
+ nativeExecute(mConnectionPtr, statement.mStatementPtr);
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -378,13 +396,16 @@ public final class SQLiteConnection {
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The value of the first column in the first row of the result set
* as a <code>long</code>, or zero if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLong(String sql, Object[] bindArgs) {
+ public long executeForLong(String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -396,7 +417,12 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- return nativeExecuteForLong(mConnectionPtr, statement.mStatementPtr);
+ attachCancelationSignal(cancelationSignal);
+ try {
+ return nativeExecuteForLong(mConnectionPtr, statement.mStatementPtr);
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -413,13 +439,16 @@ public final class SQLiteConnection {
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The value of the first column in the first row of the result set
* as a <code>String</code>, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public String executeForString(String sql, Object[] bindArgs) {
+ public String executeForString(String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -431,7 +460,12 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- return nativeExecuteForString(mConnectionPtr, statement.mStatementPtr);
+ attachCancelationSignal(cancelationSignal);
+ try {
+ return nativeExecuteForString(mConnectionPtr, statement.mStatementPtr);
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -449,14 +483,17 @@ public final class SQLiteConnection {
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The file descriptor for a shared memory region that contains
* the value of the first column in the first row of the result set as a BLOB,
* or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs) {
+ public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -469,9 +506,14 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- int fd = nativeExecuteForBlobFileDescriptor(
- mConnectionPtr, statement.mStatementPtr);
- return fd >= 0 ? ParcelFileDescriptor.adoptFd(fd) : null;
+ attachCancelationSignal(cancelationSignal);
+ try {
+ int fd = nativeExecuteForBlobFileDescriptor(
+ mConnectionPtr, statement.mStatementPtr);
+ return fd >= 0 ? ParcelFileDescriptor.adoptFd(fd) : null;
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -489,12 +531,15 @@ public final class SQLiteConnection {
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The number of rows that were changed.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public int executeForChangedRowCount(String sql, Object[] bindArgs) {
+ public int executeForChangedRowCount(String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -507,8 +552,13 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- return nativeExecuteForChangedRowCount(
- mConnectionPtr, statement.mStatementPtr);
+ attachCancelationSignal(cancelationSignal);
+ try {
+ return nativeExecuteForChangedRowCount(
+ mConnectionPtr, statement.mStatementPtr);
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -526,12 +576,15 @@ public final class SQLiteConnection {
*
* @param sql The SQL statement to execute.
* @param bindArgs The arguments to bind, or null if none.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The row id of the last row that was inserted, or 0 if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLastInsertedRowId(String sql, Object[] bindArgs) {
+ public long executeForLastInsertedRowId(String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -544,8 +597,13 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- return nativeExecuteForLastInsertedRowId(
- mConnectionPtr, statement.mStatementPtr);
+ attachCancelationSignal(cancelationSignal);
+ try {
+ return nativeExecuteForLastInsertedRowId(
+ mConnectionPtr, statement.mStatementPtr);
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -571,14 +629,17 @@ public final class SQLiteConnection {
* so that it does. Must be greater than or equal to <code>startPos</code>.
* @param countAllRows True to count all rows that the query would return
* regagless of whether they fit in the window.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The number of rows that were counted during query execution. Might
* not be all rows in the result set unless <code>countAllRows</code> is true.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
public int executeForCursorWindow(String sql, Object[] bindArgs,
- CursorWindow window, int startPos, int requiredPos, boolean countAllRows) {
+ CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -597,14 +658,19 @@ public final class SQLiteConnection {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
applyBlockGuardPolicy(statement);
- final long result = nativeExecuteForCursorWindow(
- mConnectionPtr, statement.mStatementPtr, window.mWindowPtr,
- startPos, requiredPos, countAllRows);
- actualPos = (int)(result >> 32);
- countedRows = (int)result;
- filledRows = window.getNumRows();
- window.setStartPosition(actualPos);
- return countedRows;
+ attachCancelationSignal(cancelationSignal);
+ try {
+ final long result = nativeExecuteForCursorWindow(
+ mConnectionPtr, statement.mStatementPtr, window.mWindowPtr,
+ startPos, requiredPos, countAllRows);
+ actualPos = (int)(result >> 32);
+ countedRows = (int)result;
+ filledRows = window.getNumRows();
+ window.setStartPosition(actualPos);
+ return countedRows;
+ } finally {
+ detachCancelationSignal(cancelationSignal);
+ }
} finally {
releasePreparedStatement(statement);
}
@@ -685,6 +751,46 @@ public final class SQLiteConnection {
recyclePreparedStatement(statement);
}
+ private void attachCancelationSignal(CancelationSignal cancelationSignal) {
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+
+ mCancelationSignalAttachCount += 1;
+ if (mCancelationSignalAttachCount == 1) {
+ // Reset cancelation flag before executing the statement.
+ nativeResetCancel(mConnectionPtr, true /*cancelable*/);
+
+ // After this point, onCancel() may be called concurrently.
+ cancelationSignal.setOnCancelListener(this);
+ }
+ }
+ }
+
+ private void detachCancelationSignal(CancelationSignal cancelationSignal) {
+ if (cancelationSignal != null) {
+ assert mCancelationSignalAttachCount > 0;
+
+ mCancelationSignalAttachCount -= 1;
+ if (mCancelationSignalAttachCount == 0) {
+ // After this point, onCancel() cannot be called concurrently.
+ cancelationSignal.setOnCancelListener(null);
+
+ // Reset cancelation flag after executing the statement.
+ nativeResetCancel(mConnectionPtr, false /*cancelable*/);
+ }
+ }
+ }
+
+ // CancelationSignal.OnCancelationListener callback.
+ // This method may be called on a different thread than the executing statement.
+ // However, it will only be called between calls to attachCancelationSignal and
+ // detachCancelationSignal, while a statement is executing. We can safely assume
+ // that the SQLite connection is still alive.
+ @Override
+ public void onCancel() {
+ nativeCancel(mConnectionPtr);
+ }
+
private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
final int count = bindArgs != null ? bindArgs.length : 0;
if (count != statement.mNumParameters) {
@@ -822,8 +928,8 @@ public final class SQLiteConnection {
long pageCount = 0;
long pageSize = 0;
try {
- pageCount = executeForLong("PRAGMA page_count;", null);
- pageSize = executeForLong("PRAGMA page_size;", null);
+ pageCount = executeForLong("PRAGMA page_count;", null, null);
+ pageSize = executeForLong("PRAGMA page_size;", null, null);
} catch (SQLiteException ex) {
// Ignore.
}
@@ -834,15 +940,15 @@ public final class SQLiteConnection {
// the main database which we have already described.
CursorWindow window = new CursorWindow("collectDbStats");
try {
- executeForCursorWindow("PRAGMA database_list;", null, window, 0, 0, false);
+ executeForCursorWindow("PRAGMA database_list;", null, window, 0, 0, false, null);
for (int i = 1; i < window.getNumRows(); i++) {
String name = window.getString(i, 1);
String path = window.getString(i, 2);
pageCount = 0;
pageSize = 0;
try {
- pageCount = executeForLong("PRAGMA " + name + ".page_count;", null);
- pageSize = executeForLong("PRAGMA " + name + ".page_size;", null);
+ pageCount = executeForLong("PRAGMA " + name + ".page_count;", null, null);
+ pageSize = executeForLong("PRAGMA " + name + ".page_size;", null, null);
} catch (SQLiteException ex) {
// Ignore.
}
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 5469213e4b55..d3357387bbf9 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -18,6 +18,8 @@ package android.database.sqlite;
import dalvik.system.CloseGuard;
+import android.content.CancelationSignal;
+import android.content.OperationCanceledException;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.SystemClock;
import android.util.Log;
@@ -282,13 +284,16 @@ public final class SQLiteConnectionPool implements Closeable {
* @param sql If not null, try to find a connection that already has
* the specified SQL statement in its prepared statement cache.
* @param connectionFlags The connection request flags.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The connection that was acquired, never null.
*
* @throws IllegalStateException if the pool has been closed.
* @throws SQLiteException if a database error occurs.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public SQLiteConnection acquireConnection(String sql, int connectionFlags) {
- return waitForConnection(sql, connectionFlags);
+ public SQLiteConnection acquireConnection(String sql, int connectionFlags,
+ CancelationSignal cancelationSignal) {
+ return waitForConnection(sql, connectionFlags, cancelationSignal);
}
/**
@@ -497,7 +502,8 @@ public final class SQLiteConnectionPool implements Closeable {
}
// Might throw.
- private SQLiteConnection waitForConnection(String sql, int connectionFlags) {
+ private SQLiteConnection waitForConnection(String sql, int connectionFlags,
+ CancelationSignal cancelationSignal) {
final boolean wantPrimaryConnection =
(connectionFlags & CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY) != 0;
@@ -505,6 +511,11 @@ public final class SQLiteConnectionPool implements Closeable {
synchronized (mLock) {
throwIfClosedLocked();
+ // Abort if canceled.
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ }
+
// Try to acquire a connection.
SQLiteConnection connection = null;
if (!wantPrimaryConnection) {
@@ -538,6 +549,18 @@ public final class SQLiteConnectionPool implements Closeable {
} else {
mConnectionWaiterQueue = waiter;
}
+
+ if (cancelationSignal != null) {
+ final int nonce = waiter.mNonce;
+ cancelationSignal.setOnCancelListener(new CancelationSignal.OnCancelListener() {
+ @Override
+ public void onCancel() {
+ synchronized (mLock) {
+ cancelConnectionWaiterLocked(waiter, nonce);
+ }
+ }
+ });
+ }
}
// Park the thread until a connection is assigned or the pool is closed.
@@ -547,7 +570,9 @@ public final class SQLiteConnectionPool implements Closeable {
for (;;) {
// Detect and recover from connection leaks.
if (mConnectionLeaked.compareAndSet(true, false)) {
- wakeConnectionWaitersLocked();
+ synchronized (mLock) {
+ wakeConnectionWaitersLocked();
+ }
}
// Wait to be unparked (may already have happened), a timeout, or interruption.
@@ -560,15 +585,16 @@ public final class SQLiteConnectionPool implements Closeable {
synchronized (mLock) {
throwIfClosedLocked();
- SQLiteConnection connection = waiter.mAssignedConnection;
- if (connection != null) {
- recycleConnectionWaiterLocked(waiter);
- return connection;
- }
-
- RuntimeException ex = waiter.mException;
- if (ex != null) {
+ final SQLiteConnection connection = waiter.mAssignedConnection;
+ final RuntimeException ex = waiter.mException;
+ if (connection != null || ex != null) {
+ if (cancelationSignal != null) {
+ cancelationSignal.setOnCancelListener(null);
+ }
recycleConnectionWaiterLocked(waiter);
+ if (connection != null) {
+ return connection;
+ }
throw ex; // rethrow!
}
@@ -585,6 +611,40 @@ public final class SQLiteConnectionPool implements Closeable {
}
// Can't throw.
+ private void cancelConnectionWaiterLocked(ConnectionWaiter waiter, int nonce) {
+ if (waiter.mNonce != nonce) {
+ // Waiter already removed and recycled.
+ return;
+ }
+
+ if (waiter.mAssignedConnection != null || waiter.mException != null) {
+ // Waiter is done waiting but has not woken up yet.
+ return;
+ }
+
+ // Waiter must still be waiting. Dequeue it.
+ ConnectionWaiter predecessor = null;
+ ConnectionWaiter current = mConnectionWaiterQueue;
+ while (current != waiter) {
+ assert current != null;
+ predecessor = current;
+ current = current.mNext;
+ }
+ if (predecessor != null) {
+ predecessor.mNext = waiter.mNext;
+ } else {
+ mConnectionWaiterQueue = waiter.mNext;
+ }
+
+ // Send the waiter an exception and unpark it.
+ waiter.mException = new OperationCanceledException();
+ LockSupport.unpark(waiter.mThread);
+
+ // Check whether removing this waiter will enable other waiters to make progress.
+ wakeConnectionWaitersLocked();
+ }
+
+ // Can't throw.
private void logConnectionPoolBusyLocked(long waitMillis, int connectionFlags) {
final Thread thread = Thread.currentThread();
StringBuilder msg = new StringBuilder();
@@ -826,6 +886,7 @@ public final class SQLiteConnectionPool implements Closeable {
waiter.mSql = null;
waiter.mAssignedConnection = null;
waiter.mException = null;
+ waiter.mNonce += 1;
mConnectionWaiterPool = waiter;
}
@@ -904,5 +965,6 @@ public final class SQLiteConnectionPool implements Closeable {
public int mConnectionFlags;
public SQLiteConnection mAssignedConnection;
public RuntimeException mException;
+ public int mNonce;
}
}
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 946300f37537..82bb23ecb159 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -65,8 +65,7 @@ public class SQLiteCursor extends AbstractWindowedCursor {
* interface. For a query such as: {@code SELECT name, birth, phone FROM
* myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
* phone) would be in the projection argument and everything from
- * {@code FROM} onward would be in the params argument. This constructor
- * has package scope.
+ * {@code FROM} onward would be in the params argument.
*
* @param db a reference to a Database object that is already constructed
* and opened. This param is not used any longer
@@ -86,8 +85,7 @@ public class SQLiteCursor extends AbstractWindowedCursor {
* interface. For a query such as: {@code SELECT name, birth, phone FROM
* myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
* phone) would be in the projection argument and everything from
- * {@code FROM} onward would be in the params argument. This constructor
- * has package scope.
+ * {@code FROM} onward would be in the params argument.
*
* @param editTable the name of the table used for this query
* @param query the {@link SQLiteQuery} object associated with this cursor object.
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 9cb6480ba454..7db7bfb703a2 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -16,7 +16,9 @@
package android.database.sqlite;
+import android.content.CancelationSignal;
import android.content.ContentValues;
+import android.content.OperationCanceledException;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
@@ -492,7 +494,7 @@ public class SQLiteDatabase extends SQLiteClosable {
boolean exclusive) {
getThreadSession().beginTransaction(exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
SQLiteSession.TRANSACTION_MODE_IMMEDIATE, transactionListener,
- getThreadDefaultConnectionFlags(false /*readOnly*/));
+ getThreadDefaultConnectionFlags(false /*readOnly*/), null);
}
/**
@@ -500,7 +502,7 @@ public class SQLiteDatabase extends SQLiteClosable {
* are committed and rolled back.
*/
public void endTransaction() {
- getThreadSession().endTransaction();
+ getThreadSession().endTransaction(null);
}
/**
@@ -597,7 +599,7 @@ public class SQLiteDatabase extends SQLiteClosable {
}
private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
- return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe);
+ return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
}
/**
@@ -935,7 +937,48 @@ public class SQLiteDatabase extends SQLiteClosable {
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit) {
return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
- groupBy, having, orderBy, limit);
+ groupBy, having, orderBy, limit, null);
+ }
+
+ /**
+ * Query the given URL, returning a {@link Cursor} over the result set.
+ *
+ * @param distinct true if you want each row to be unique, false otherwise.
+ * @param table The table name to compile the query against.
+ * @param columns A list of which columns to return. Passing null will
+ * return all columns, which is discouraged to prevent reading
+ * data from storage that isn't going to be used.
+ * @param selection A filter declaring which rows to return, formatted as an
+ * SQL WHERE clause (excluding the WHERE itself). Passing null
+ * will return all rows for the given table.
+ * @param selectionArgs You may include ?s in selection, which will be
+ * replaced by the values from selectionArgs, in order that they
+ * appear in the selection. The values will be bound as Strings.
+ * @param groupBy A filter declaring how to group rows, formatted as an SQL
+ * GROUP BY clause (excluding the GROUP BY itself). Passing null
+ * will cause the rows to not be grouped.
+ * @param having A filter declare which row groups to include in the cursor,
+ * if row grouping is being used, formatted as an SQL HAVING
+ * clause (excluding the HAVING itself). Passing null will cause
+ * all row groups to be included, and is required when row
+ * grouping is not being used.
+ * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+ * (excluding the ORDER BY itself). Passing null will use the
+ * default sort order, which may be unordered.
+ * @param limit Limits the number of rows returned by the query,
+ * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
+ * @see Cursor
+ */
+ public Cursor query(boolean distinct, String table, String[] columns,
+ String selection, String[] selectionArgs, String groupBy,
+ String having, String orderBy, String limit, CancelationSignal cancelationSignal) {
+ return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
+ groupBy, having, orderBy, limit, cancelationSignal);
}
/**
@@ -974,12 +1017,55 @@ public class SQLiteDatabase extends SQLiteClosable {
boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit) {
+ return queryWithFactory(cursorFactory, distinct, table, columns, selection,
+ selectionArgs, groupBy, having, orderBy, limit, null);
+ }
+
+ /**
+ * Query the given URL, returning a {@link Cursor} over the result set.
+ *
+ * @param cursorFactory the cursor factory to use, or null for the default factory
+ * @param distinct true if you want each row to be unique, false otherwise.
+ * @param table The table name to compile the query against.
+ * @param columns A list of which columns to return. Passing null will
+ * return all columns, which is discouraged to prevent reading
+ * data from storage that isn't going to be used.
+ * @param selection A filter declaring which rows to return, formatted as an
+ * SQL WHERE clause (excluding the WHERE itself). Passing null
+ * will return all rows for the given table.
+ * @param selectionArgs You may include ?s in selection, which will be
+ * replaced by the values from selectionArgs, in order that they
+ * appear in the selection. The values will be bound as Strings.
+ * @param groupBy A filter declaring how to group rows, formatted as an SQL
+ * GROUP BY clause (excluding the GROUP BY itself). Passing null
+ * will cause the rows to not be grouped.
+ * @param having A filter declare which row groups to include in the cursor,
+ * if row grouping is being used, formatted as an SQL HAVING
+ * clause (excluding the HAVING itself). Passing null will cause
+ * all row groups to be included, and is required when row
+ * grouping is not being used.
+ * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+ * (excluding the ORDER BY itself). Passing null will use the
+ * default sort order, which may be unordered.
+ * @param limit Limits the number of rows returned by the query,
+ * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
+ * @see Cursor
+ */
+ public Cursor queryWithFactory(CursorFactory cursorFactory,
+ boolean distinct, String table, String[] columns,
+ String selection, String[] selectionArgs, String groupBy,
+ String having, String orderBy, String limit, CancelationSignal cancelationSignal) {
throwIfNotOpen(); // fail fast
String sql = SQLiteQueryBuilder.buildQueryString(
distinct, table, columns, selection, groupBy, having, orderBy, limit);
- return rawQueryWithFactory(
- cursorFactory, sql, selectionArgs, findEditTable(table));
+ return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
+ findEditTable(table), cancelationSignal);
}
/**
@@ -1067,7 +1153,25 @@ public class SQLiteDatabase extends SQLiteClosable {
* {@link Cursor}s are not synchronized, see the documentation for more details.
*/
public Cursor rawQuery(String sql, String[] selectionArgs) {
- return rawQueryWithFactory(null, sql, selectionArgs, null);
+ return rawQueryWithFactory(null, sql, selectionArgs, null, null);
+ }
+
+ /**
+ * Runs the provided SQL and returns a {@link Cursor} over the result set.
+ *
+ * @param sql the SQL query. The SQL string must not be ; terminated
+ * @param selectionArgs You may include ?s in where clause in the query,
+ * which will be replaced by the values from selectionArgs. The
+ * values will be bound as Strings.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
+ */
+ public Cursor rawQuery(String sql, String[] selectionArgs,
+ CancelationSignal cancelationSignal) {
+ return rawQueryWithFactory(null, sql, selectionArgs, null, cancelationSignal);
}
/**
@@ -1085,9 +1189,31 @@ public class SQLiteDatabase extends SQLiteClosable {
public Cursor rawQueryWithFactory(
CursorFactory cursorFactory, String sql, String[] selectionArgs,
String editTable) {
+ return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
+ }
+
+ /**
+ * Runs the provided SQL and returns a cursor over the result set.
+ *
+ * @param cursorFactory the cursor factory to use, or null for the default factory
+ * @param sql the SQL query. The SQL string must not be ; terminated
+ * @param selectionArgs You may include ?s in where clause in the query,
+ * which will be replaced by the values from selectionArgs. The
+ * values will be bound as Strings.
+ * @param editTable the name of the first table, which is editable
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
+ */
+ public Cursor rawQueryWithFactory(
+ CursorFactory cursorFactory, String sql, String[] selectionArgs,
+ String editTable, CancelationSignal cancelationSignal) {
throwIfNotOpen(); // fail fast
- SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable);
+ SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
+ cancelationSignal);
return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
selectionArgs);
}
@@ -1786,7 +1912,7 @@ public class SQLiteDatabase extends SQLiteClosable {
*/
void lockPrimaryConnection() {
getThreadSession().beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED,
- null, SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY);
+ null, SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY, null);
}
/**
@@ -1795,7 +1921,7 @@ public class SQLiteDatabase extends SQLiteClosable {
* @see #lockPrimaryConnection()
*/
void unlockPrimaryConnection() {
- getThreadSession().endTransaction();
+ getThreadSession().endTransaction(null);
}
@Override
diff --git a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
index 52fd1d2709fa..c490dc66f8d1 100644
--- a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
+++ b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
@@ -16,6 +16,7 @@
package android.database.sqlite;
+import android.content.CancelationSignal;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -28,16 +29,19 @@ public class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
private final SQLiteDatabase mDatabase;
private final String mEditTable;
private final String mSql;
+ private final CancelationSignal mCancelationSignal;
private SQLiteQuery mQuery;
- public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable) {
+ public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable,
+ CancelationSignal cancelationSignal) {
mDatabase = db;
mEditTable = editTable;
mSql = sql;
+ mCancelationSignal = cancelationSignal;
}
public Cursor query(CursorFactory factory, String[] selectionArgs) {
- final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql);
+ final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, mCancelationSignal);
final Cursor cursor;
try {
query.bindAllArgsAsStrings(selectionArgs);
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 81944587aa4d..f3da2a6117fc 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -16,6 +16,7 @@
package android.database.sqlite;
+import android.content.CancelationSignal;
import android.database.DatabaseUtils;
import java.util.Arrays;
@@ -36,7 +37,8 @@ public abstract class SQLiteProgram extends SQLiteClosable {
private final int mNumParameters;
private final Object[] mBindArgs;
- SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs) {
+ SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
+ CancelationSignal cancelationSignalForPrepare) {
mDatabase = db;
mSql = sql.trim();
@@ -54,7 +56,8 @@ public abstract class SQLiteProgram extends SQLiteClosable {
boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT);
SQLiteStatementInfo info = new SQLiteStatementInfo();
db.getThreadSession().prepare(mSql,
- db.getThreadDefaultConnectionFlags(assumeReadOnly), info);
+ db.getThreadDefaultConnectionFlags(assumeReadOnly),
+ cancelationSignalForPrepare, info);
mReadOnly = info.readOnly;
mColumnNames = info.columnNames;
mNumParameters = info.numParameters;
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 17aa8865ee49..df2e260656c4 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -16,6 +16,8 @@
package android.database.sqlite;
+import android.content.CancelationSignal;
+import android.content.OperationCanceledException;
import android.database.CursorWindow;
import android.util.Log;
@@ -29,8 +31,12 @@ import android.util.Log;
public final class SQLiteQuery extends SQLiteProgram {
private static final String TAG = "SQLiteQuery";
- SQLiteQuery(SQLiteDatabase db, String query) {
- super(db, query, null);
+ private final CancelationSignal mCancelationSignal;
+
+ SQLiteQuery(SQLiteDatabase db, String query, CancelationSignal cancelationSignal) {
+ super(db, query, null, cancelationSignal);
+
+ mCancelationSignal = cancelationSignal;
}
/**
@@ -44,6 +50,9 @@ public final class SQLiteQuery extends SQLiteProgram {
* return regardless of whether they fit in the window.
* @return Number of rows that were enumerated. Might not be all rows
* unless countAllRows is true.
+ *
+ * @throws SQLiteException if an error occurs.
+ * @throws OperationCanceledException if the operation was canceled.
*/
int fillWindow(CursorWindow window, int startPos, int requiredPos, boolean countAllRows) {
acquireReference();
@@ -51,7 +60,8 @@ public final class SQLiteQuery extends SQLiteProgram {
window.acquireReference();
try {
int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(),
- window, startPos, requiredPos, countAllRows, getConnectionFlags());
+ window, startPos, requiredPos, countAllRows, getConnectionFlags(),
+ mCancelationSignal);
return numRows;
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 1b7b39800d35..89469cbac38d 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -16,6 +16,8 @@
package android.database.sqlite;
+import android.content.CancelationSignal;
+import android.content.OperationCanceledException;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.provider.BaseColumns;
@@ -137,8 +139,9 @@ public class SQLiteQueryBuilder
/**
* Sets the cursor factory to be used for the query. You can use
* one factory for all queries on a database but it is normally
- * easier to specify the factory when doing this query. @param
- * factory the factor to use
+ * easier to specify the factory when doing this query.
+ *
+ * @param factory the factory to use.
*/
public void setCursorFactory(SQLiteDatabase.CursorFactory factory) {
mFactory = factory;
@@ -289,7 +292,7 @@ public class SQLiteQueryBuilder
String selection, String[] selectionArgs, String groupBy,
String having, String sortOrder) {
return query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder,
- null /* limit */);
+ null /* limit */, null /* cancelationSignal */);
}
/**
@@ -327,6 +330,48 @@ public class SQLiteQueryBuilder
public Cursor query(SQLiteDatabase db, String[] projectionIn,
String selection, String[] selectionArgs, String groupBy,
String having, String sortOrder, String limit) {
+ return query(db, projectionIn, selection, selectionArgs,
+ groupBy, having, sortOrder, limit, null);
+ }
+
+ /**
+ * Perform a query by combining all current settings and the
+ * information passed into this method.
+ *
+ * @param db the database to query on
+ * @param projectionIn A list of which columns to return. Passing
+ * null will return all columns, which is discouraged to prevent
+ * reading data from storage that isn't going to be used.
+ * @param selection A filter declaring which rows to return,
+ * formatted as an SQL WHERE clause (excluding the WHERE
+ * itself). Passing null will return all rows for the given URL.
+ * @param selectionArgs You may include ?s in selection, which
+ * will be replaced by the values from selectionArgs, in order
+ * that they appear in the selection. The values will be bound
+ * as Strings.
+ * @param groupBy A filter declaring how to group rows, formatted
+ * as an SQL GROUP BY clause (excluding the GROUP BY
+ * itself). Passing null will cause the rows to not be grouped.
+ * @param having A filter declare which row groups to include in
+ * the cursor, if row grouping is being used, formatted as an
+ * SQL HAVING clause (excluding the HAVING itself). Passing
+ * null will cause all row groups to be included, and is
+ * required when row grouping is not being used.
+ * @param sortOrder How to order the rows, formatted as an SQL
+ * ORDER BY clause (excluding the ORDER BY itself). Passing null
+ * will use the default sort order, which may be unordered.
+ * @param limit Limits the number of rows returned by the query,
+ * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+ * when the query is executed.
+ * @return a cursor over the result set
+ * @see android.content.ContentResolver#query(android.net.Uri, String[],
+ * String, String[], String)
+ */
+ public Cursor query(SQLiteDatabase db, String[] projectionIn,
+ String selection, String[] selectionArgs, String groupBy,
+ String having, String sortOrder, String limit, CancelationSignal cancelationSignal) {
if (mTables == null) {
return null;
}
@@ -341,7 +386,8 @@ public class SQLiteQueryBuilder
// in both the wrapped and original forms.
String sqlForValidation = buildQuery(projectionIn, "(" + selection + ")", groupBy,
having, sortOrder, limit);
- validateQuerySql(db, sqlForValidation); // will throw if query is invalid
+ validateQuerySql(db, sqlForValidation,
+ cancelationSignal); // will throw if query is invalid
}
String sql = buildQuery(
@@ -353,16 +399,18 @@ public class SQLiteQueryBuilder
}
return db.rawQueryWithFactory(
mFactory, sql, selectionArgs,
- SQLiteDatabase.findEditTable(mTables)); // will throw if query is invalid
+ SQLiteDatabase.findEditTable(mTables),
+ cancelationSignal); // will throw if query is invalid
}
/**
* Verifies that a SQL SELECT statement is valid by compiling it.
* If the SQL statement is not valid, this method will throw a {@link SQLiteException}.
*/
- private void validateQuerySql(SQLiteDatabase db, String sql) {
+ private void validateQuerySql(SQLiteDatabase db, String sql,
+ CancelationSignal cancelationSignal) {
db.getThreadSession().prepare(sql,
- db.getThreadDefaultConnectionFlags(true /*readOnly*/), null);
+ db.getThreadDefaultConnectionFlags(true /*readOnly*/), cancelationSignal, null);
}
/**
diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java
index a933051dbd0e..b5a3e31948af 100644
--- a/core/java/android/database/sqlite/SQLiteSession.java
+++ b/core/java/android/database/sqlite/SQLiteSession.java
@@ -16,6 +16,8 @@
package android.database.sqlite;
+import android.content.CancelationSignal;
+import android.content.OperationCanceledException;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.os.ParcelFileDescriptor;
@@ -156,8 +158,6 @@ import android.os.ParcelFileDescriptor;
* triggers may call custom SQLite functions that perform additional queries.
* </p>
*
- * TODO: Support timeouts on all possibly blocking operations.
- *
* @hide
*/
public final class SQLiteSession {
@@ -280,24 +280,34 @@ public final class SQLiteSession {
* @param transactionListener The transaction listener, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
*
* @throws IllegalStateException if {@link #setTransactionSuccessful} has already been
* called for the current transaction.
+ * @throws SQLiteException if an error occurs.
+ * @throws OperationCanceledException if the operation was canceled.
*
* @see #setTransactionSuccessful
* @see #yieldTransaction
* @see #endTransaction
*/
public void beginTransaction(int transactionMode,
- SQLiteTransactionListener transactionListener, int connectionFlags) {
+ SQLiteTransactionListener transactionListener, int connectionFlags,
+ CancelationSignal cancelationSignal) {
throwIfTransactionMarkedSuccessful();
- beginTransactionUnchecked(transactionMode, transactionListener, connectionFlags);
+ beginTransactionUnchecked(transactionMode, transactionListener, connectionFlags,
+ cancelationSignal);
}
private void beginTransactionUnchecked(int transactionMode,
- SQLiteTransactionListener transactionListener, int connectionFlags) {
+ SQLiteTransactionListener transactionListener, int connectionFlags,
+ CancelationSignal cancelationSignal) {
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ }
+
if (mTransactionStack == null) {
- acquireConnection(null, connectionFlags); // might throw
+ acquireConnection(null, connectionFlags, cancelationSignal); // might throw
}
try {
// Set up the transaction such that we can back out safely
@@ -306,13 +316,15 @@ public final class SQLiteSession {
// Execute SQL might throw a runtime exception.
switch (transactionMode) {
case TRANSACTION_MODE_IMMEDIATE:
- mConnection.execute("BEGIN IMMEDIATE;", null); // might throw
+ mConnection.execute("BEGIN IMMEDIATE;", null,
+ cancelationSignal); // might throw
break;
case TRANSACTION_MODE_EXCLUSIVE:
- mConnection.execute("BEGIN EXCLUSIVE;", null); // might throw
+ mConnection.execute("BEGIN EXCLUSIVE;", null,
+ cancelationSignal); // might throw
break;
default:
- mConnection.execute("BEGIN;", null); // might throw
+ mConnection.execute("BEGIN;", null, cancelationSignal); // might throw
break;
}
}
@@ -323,7 +335,7 @@ public final class SQLiteSession {
transactionListener.onBegin(); // might throw
} catch (RuntimeException ex) {
if (mTransactionStack == null) {
- mConnection.execute("ROLLBACK;", null); // might throw
+ mConnection.execute("ROLLBACK;", null, cancelationSignal); // might throw
}
throw ex;
}
@@ -372,20 +384,28 @@ public final class SQLiteSession {
* This method must be called exactly once for each call to {@link #beginTransaction}.
* </p>
*
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
+ *
* @throws IllegalStateException if there is no current transaction.
+ * @throws SQLiteException if an error occurs.
+ * @throws OperationCanceledException if the operation was canceled.
*
* @see #beginTransaction
* @see #setTransactionSuccessful
* @see #yieldTransaction
*/
- public void endTransaction() {
+ public void endTransaction(CancelationSignal cancelationSignal) {
throwIfNoTransaction();
assert mConnection != null;
- endTransactionUnchecked();
+ endTransactionUnchecked(cancelationSignal);
}
- private void endTransactionUnchecked() {
+ private void endTransactionUnchecked(CancelationSignal cancelationSignal) {
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ }
+
final Transaction top = mTransactionStack;
boolean successful = top.mMarkedSuccessful && !top.mChildFailed;
@@ -414,9 +434,9 @@ public final class SQLiteSession {
} else {
try {
if (successful) {
- mConnection.execute("COMMIT;", null); // might throw
+ mConnection.execute("COMMIT;", null, cancelationSignal); // might throw
} else {
- mConnection.execute("ROLLBACK;", null); // might throw
+ mConnection.execute("ROLLBACK;", null, cancelationSignal); // might throw
}
} finally {
releaseConnection(); // might throw
@@ -467,16 +487,20 @@ public final class SQLiteSession {
* @param throwIfUnsafe If true, then instead of returning false when no
* transaction is in progress, a nested transaction is in progress, or when
* the transaction has already been marked successful, throws {@link IllegalStateException}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return True if the transaction was actually yielded.
*
* @throws IllegalStateException if <code>throwIfNested</code> is true and
* there is no current transaction, there is a nested transaction in progress or
* if {@link #setTransactionSuccessful} has already been called for the current transaction.
+ * @throws SQLiteException if an error occurs.
+ * @throws OperationCanceledException if the operation was canceled.
*
* @see #beginTransaction
* @see #endTransaction
*/
- public boolean yieldTransaction(long sleepAfterYieldDelayMillis, boolean throwIfUnsafe) {
+ public boolean yieldTransaction(long sleepAfterYieldDelayMillis, boolean throwIfUnsafe,
+ CancelationSignal cancelationSignal) {
if (throwIfUnsafe) {
throwIfNoTransaction();
throwIfTransactionMarkedSuccessful();
@@ -493,10 +517,16 @@ public final class SQLiteSession {
return false;
}
- return yieldTransactionUnchecked(sleepAfterYieldDelayMillis); // might throw
+ return yieldTransactionUnchecked(sleepAfterYieldDelayMillis,
+ cancelationSignal); // might throw
}
- private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis) {
+ private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis,
+ CancelationSignal cancelationSignal) {
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ }
+
if (!mConnectionPool.shouldYieldConnection(mConnection, mConnectionFlags)) {
return false;
}
@@ -504,7 +534,7 @@ public final class SQLiteSession {
final int transactionMode = mTransactionStack.mMode;
final SQLiteTransactionListener listener = mTransactionStack.mListener;
final int connectionFlags = mConnectionFlags;
- endTransactionUnchecked(); // might throw
+ endTransactionUnchecked(cancelationSignal); // might throw
if (sleepAfterYieldDelayMillis > 0) {
try {
@@ -514,7 +544,8 @@ public final class SQLiteSession {
}
}
- beginTransactionUnchecked(transactionMode, listener, connectionFlags); // might throw
+ beginTransactionUnchecked(transactionMode, listener, connectionFlags,
+ cancelationSignal); // might throw
return true;
}
@@ -535,17 +566,24 @@ public final class SQLiteSession {
* @param sql The SQL statement to prepare.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
* with information about the statement, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public void prepare(String sql, int connectionFlags, SQLiteStatementInfo outStatementInfo) {
+ public void prepare(String sql, int connectionFlags, CancelationSignal cancelationSignal,
+ SQLiteStatementInfo outStatementInfo) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- acquireConnection(sql, connectionFlags); // might throw
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ }
+
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
mConnection.prepare(sql, outStatementInfo); // might throw
} finally {
@@ -560,22 +598,25 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public void execute(String sql, Object[] bindArgs, int connectionFlags) {
+ public void execute(String sql, Object[] bindArgs, int connectionFlags,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
return;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
- mConnection.execute(sql, bindArgs); // might throw
+ mConnection.execute(sql, bindArgs, cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -588,24 +629,27 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The value of the first column in the first row of the result set
* as a <code>long</code>, or zero if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLong(String sql, Object[] bindArgs, int connectionFlags) {
+ public long executeForLong(String sql, Object[] bindArgs, int connectionFlags,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
return 0;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
- return mConnection.executeForLong(sql, bindArgs); // might throw
+ return mConnection.executeForLong(sql, bindArgs, cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -618,24 +662,27 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The value of the first column in the first row of the result set
* as a <code>String</code>, or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public String executeForString(String sql, Object[] bindArgs, int connectionFlags) {
+ public String executeForString(String sql, Object[] bindArgs, int connectionFlags,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
return null;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
- return mConnection.executeForString(sql, bindArgs); // might throw
+ return mConnection.executeForString(sql, bindArgs, cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -649,26 +696,29 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The file descriptor for a shared memory region that contains
* the value of the first column in the first row of the result set as a BLOB,
* or null if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
- int connectionFlags) {
+ int connectionFlags, CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
return null;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
- return mConnection.executeForBlobFileDescriptor(sql, bindArgs); // might throw
+ return mConnection.executeForBlobFileDescriptor(sql, bindArgs,
+ cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -682,23 +732,27 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The number of rows that were changed.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public int executeForChangedRowCount(String sql, Object[] bindArgs, int connectionFlags) {
+ public int executeForChangedRowCount(String sql, Object[] bindArgs, int connectionFlags,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
return 0;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
- return mConnection.executeForChangedRowCount(sql, bindArgs); // might throw
+ return mConnection.executeForChangedRowCount(sql, bindArgs,
+ cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -712,23 +766,27 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The row id of the last row that was inserted, or 0 if none.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLastInsertedRowId(String sql, Object[] bindArgs, int connectionFlags) {
+ public long executeForLastInsertedRowId(String sql, Object[] bindArgs, int connectionFlags,
+ CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
return 0;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
- return mConnection.executeForLastInsertedRowId(sql, bindArgs); // might throw
+ return mConnection.executeForLastInsertedRowId(sql, bindArgs,
+ cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -750,15 +808,17 @@ public final class SQLiteSession {
* regagless of whether they fit in the window.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return The number of rows that were counted during query execution. Might
* not be all rows in the result set unless <code>countAllRows</code> is true.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
public int executeForCursorWindow(String sql, Object[] bindArgs,
CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
- int connectionFlags) {
+ int connectionFlags, CancelationSignal cancelationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -766,15 +826,16 @@ public final class SQLiteSession {
throw new IllegalArgumentException("window must not be null.");
}
- if (executeSpecial(sql, bindArgs, connectionFlags)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancelationSignal)) {
window.clear();
return 0;
}
- acquireConnection(sql, connectionFlags); // might throw
+ acquireConnection(sql, connectionFlags, cancelationSignal); // might throw
try {
return mConnection.executeForCursorWindow(sql, bindArgs,
- window, startPos, requiredPos, countAllRows); // might throw
+ window, startPos, requiredPos, countAllRows,
+ cancelationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -793,35 +854,45 @@ public final class SQLiteSession {
* @param bindArgs The arguments to bind, or null if none.
* @param connectionFlags The connection flags to use if a connection must be
* acquired by this operation. Refer to {@link SQLiteConnectionPool}.
+ * @param cancelationSignal A signal to cancel the operation in progress, or null if none.
* @return True if the statement was of a special form that was handled here,
* false otherwise.
*
* @throws SQLiteException if an error occurs, such as a syntax error
* or invalid number of bind arguments.
+ * @throws OperationCanceledException if the operation was canceled.
*/
- private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags) {
+ private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags,
+ CancelationSignal cancelationSignal) {
+ if (cancelationSignal != null) {
+ cancelationSignal.throwIfCanceled();
+ }
+
final int type = DatabaseUtils.getSqlStatementType(sql);
switch (type) {
case DatabaseUtils.STATEMENT_BEGIN:
- beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags);
+ beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags,
+ cancelationSignal);
return true;
case DatabaseUtils.STATEMENT_COMMIT:
setTransactionSuccessful();
- endTransaction();
+ endTransaction(cancelationSignal);
return true;
case DatabaseUtils.STATEMENT_ABORT:
- endTransaction();
+ endTransaction(cancelationSignal);
return true;
}
return false;
}
- private void acquireConnection(String sql, int connectionFlags) {
+ private void acquireConnection(String sql, int connectionFlags,
+ CancelationSignal cancelationSignal) {
if (mConnection == null) {
assert mConnectionUseCount == 0;
- mConnection = mConnectionPool.acquireConnection(sql, connectionFlags); // might throw
+ mConnection = mConnectionPool.acquireConnection(sql, connectionFlags,
+ cancelationSignal); // might throw
mConnectionFlags = connectionFlags;
}
mConnectionUseCount += 1;
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 4e20da00c25c..b1092d765a9a 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -28,7 +28,7 @@ import android.os.ParcelFileDescriptor;
*/
public final class SQLiteStatement extends SQLiteProgram {
SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) {
- super(db, sql, bindArgs);
+ super(db, sql, bindArgs, null);
}
/**
@@ -41,7 +41,7 @@ public final class SQLiteStatement extends SQLiteProgram {
public void execute() {
acquireReference();
try {
- getSession().execute(getSql(), getBindArgs(), getConnectionFlags());
+ getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -62,7 +62,7 @@ public final class SQLiteStatement extends SQLiteProgram {
acquireReference();
try {
return getSession().executeForChangedRowCount(
- getSql(), getBindArgs(), getConnectionFlags());
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -84,7 +84,7 @@ public final class SQLiteStatement extends SQLiteProgram {
acquireReference();
try {
return getSession().executeForLastInsertedRowId(
- getSql(), getBindArgs(), getConnectionFlags());
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -105,7 +105,7 @@ public final class SQLiteStatement extends SQLiteProgram {
acquireReference();
try {
return getSession().executeForLong(
- getSql(), getBindArgs(), getConnectionFlags());
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -126,7 +126,7 @@ public final class SQLiteStatement extends SQLiteProgram {
acquireReference();
try {
return getSession().executeForString(
- getSql(), getBindArgs(), getConnectionFlags());
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -147,7 +147,7 @@ public final class SQLiteStatement extends SQLiteProgram {
acquireReference();
try {
return getSession().executeForBlobFileDescriptor(
- getSql(), getBindArgs(), getConnectionFlags());
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index e8f60b49686f..7a1ef6623e5b 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -102,6 +102,15 @@ public class NetworkStats implements Parcelable {
this.operations = operations;
}
+ public boolean isNegative() {
+ return rxBytes < 0 || rxPackets < 0 || txBytes < 0 || txPackets < 0 || operations < 0;
+ }
+
+ public boolean isEmpty() {
+ return rxBytes == 0 && rxPackets == 0 && txBytes == 0 && txPackets == 0
+ && operations == 0;
+ }
+
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
@@ -343,6 +352,7 @@ public class NetworkStats implements Parcelable {
* on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface},
* since operation counts are at data layer.
*/
+ @Deprecated
public void spliceOperationsFrom(NetworkStats stats) {
for (int i = 0; i < size; i++) {
final int j = stats.findIndex(IFACE_ALL, uid[i], set[i], tag[i]);
@@ -397,7 +407,7 @@ public class NetworkStats implements Parcelable {
* Return total of all fields represented by this snapshot object.
*/
public Entry getTotal(Entry recycle) {
- return getTotal(recycle, null, UID_ALL);
+ return getTotal(recycle, null, UID_ALL, false);
}
/**
@@ -405,7 +415,7 @@ public class NetworkStats implements Parcelable {
* the requested {@link #uid}.
*/
public Entry getTotal(Entry recycle, int limitUid) {
- return getTotal(recycle, null, limitUid);
+ return getTotal(recycle, null, limitUid, false);
}
/**
@@ -413,7 +423,11 @@ public class NetworkStats implements Parcelable {
* the requested {@link #iface}.
*/
public Entry getTotal(Entry recycle, HashSet<String> limitIface) {
- return getTotal(recycle, limitIface, UID_ALL);
+ return getTotal(recycle, limitIface, UID_ALL, false);
+ }
+
+ public Entry getTotalIncludingTags(Entry recycle) {
+ return getTotal(recycle, null, UID_ALL, true);
}
/**
@@ -423,7 +437,8 @@ public class NetworkStats implements Parcelable {
* @param limitIface Set of {@link #iface} to include in total; or {@code
* null} to include all ifaces.
*/
- private Entry getTotal(Entry recycle, HashSet<String> limitIface, int limitUid) {
+ private Entry getTotal(
+ Entry recycle, HashSet<String> limitIface, int limitUid, boolean includeTags) {
final Entry entry = recycle != null ? recycle : new Entry();
entry.iface = IFACE_ALL;
@@ -442,7 +457,7 @@ public class NetworkStats implements Parcelable {
if (matchesUid && matchesIface) {
// skip specific tags, since already counted in TAG_NONE
- if (tag[i] != TAG_NONE) continue;
+ if (tag[i] != TAG_NONE && !includeTags) continue;
entry.rxBytes += rxBytes[i];
entry.rxPackets += rxPackets[i];
@@ -460,7 +475,7 @@ public class NetworkStats implements Parcelable {
* time, and that none of them have disappeared.
*/
public NetworkStats subtract(NetworkStats right) {
- return subtract(this, right, null);
+ return subtract(this, right, null, null);
}
/**
@@ -471,12 +486,12 @@ public class NetworkStats implements Parcelable {
* If counters have rolled backwards, they are clamped to {@code 0} and
* reported to the given {@link NonMonotonicObserver}.
*/
- public static NetworkStats subtract(
- NetworkStats left, NetworkStats right, NonMonotonicObserver observer) {
+ public static <C> NetworkStats subtract(
+ NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) {
long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
if (deltaRealtime < 0) {
if (observer != null) {
- observer.foundNonMonotonic(left, -1, right, -1);
+ observer.foundNonMonotonic(left, -1, right, -1, cookie);
}
deltaRealtime = 0;
}
@@ -510,7 +525,7 @@ public class NetworkStats implements Parcelable {
if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
|| entry.txPackets < 0 || entry.operations < 0) {
if (observer != null) {
- observer.foundNonMonotonic(left, i, right, j);
+ observer.foundNonMonotonic(left, i, right, j, cookie);
}
entry.rxBytes = Math.max(entry.rxBytes, 0);
entry.rxPackets = Math.max(entry.rxPackets, 0);
@@ -663,8 +678,8 @@ public class NetworkStats implements Parcelable {
}
};
- public interface NonMonotonicObserver {
+ public interface NonMonotonicObserver<C> {
public void foundNonMonotonic(
- NetworkStats left, int leftIndex, NetworkStats right, int rightIndex);
+ NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie);
}
}
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index 8c01331595c9..faf8a3f9feb5 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -26,16 +26,18 @@ import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray;
import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
+import static com.android.internal.util.ArrayUtils.total;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.MathUtils;
+import com.android.internal.util.IndentingPrintWriter;
+
import java.io.CharArrayWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.PrintWriter;
import java.net.ProtocolException;
import java.util.Arrays;
import java.util.Random;
@@ -74,6 +76,7 @@ public class NetworkStatsHistory implements Parcelable {
private long[] txBytes;
private long[] txPackets;
private long[] operations;
+ private long totalBytes;
public static class Entry {
public static final long UNKNOWN = -1;
@@ -106,6 +109,12 @@ public class NetworkStatsHistory implements Parcelable {
if ((fields & FIELD_TX_PACKETS) != 0) txPackets = new long[initialSize];
if ((fields & FIELD_OPERATIONS) != 0) operations = new long[initialSize];
bucketCount = 0;
+ totalBytes = 0;
+ }
+
+ public NetworkStatsHistory(NetworkStatsHistory existing, long bucketDuration) {
+ this(bucketDuration, existing.estimateResizeBuckets(bucketDuration));
+ recordEntireHistory(existing);
}
public NetworkStatsHistory(Parcel in) {
@@ -118,6 +127,7 @@ public class NetworkStatsHistory implements Parcelable {
txPackets = readLongArray(in);
operations = readLongArray(in);
bucketCount = bucketStart.length;
+ totalBytes = in.readLong();
}
/** {@inheritDoc} */
@@ -130,6 +140,7 @@ public class NetworkStatsHistory implements Parcelable {
writeLongArray(out, txBytes, bucketCount);
writeLongArray(out, txPackets, bucketCount);
writeLongArray(out, operations, bucketCount);
+ out.writeLong(totalBytes);
}
public NetworkStatsHistory(DataInputStream in) throws IOException {
@@ -144,6 +155,7 @@ public class NetworkStatsHistory implements Parcelable {
txPackets = new long[bucketStart.length];
operations = new long[bucketStart.length];
bucketCount = bucketStart.length;
+ totalBytes = total(rxBytes) + total(txBytes);
break;
}
case VERSION_ADD_PACKETS:
@@ -158,6 +170,7 @@ public class NetworkStatsHistory implements Parcelable {
txPackets = readVarLongArray(in);
operations = readVarLongArray(in);
bucketCount = bucketStart.length;
+ totalBytes = total(rxBytes) + total(txBytes);
break;
}
default: {
@@ -208,6 +221,13 @@ public class NetworkStatsHistory implements Parcelable {
}
/**
+ * Return total bytes represented by this history.
+ */
+ public long getTotalBytes() {
+ return totalBytes;
+ }
+
+ /**
* Return index of bucket that contains or is immediately before the
* requested time.
*/
@@ -266,13 +286,16 @@ public class NetworkStatsHistory implements Parcelable {
* distribute across internal buckets, creating new buckets as needed.
*/
public void recordData(long start, long end, NetworkStats.Entry entry) {
- if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0
- || entry.operations < 0) {
+ long rxBytes = entry.rxBytes;
+ long rxPackets = entry.rxPackets;
+ long txBytes = entry.txBytes;
+ long txPackets = entry.txPackets;
+ long operations = entry.operations;
+
+ if (entry.isNegative()) {
throw new IllegalArgumentException("tried recording negative data");
}
- if (entry.rxBytes == 0 && entry.rxPackets == 0 && entry.txBytes == 0 && entry.txPackets == 0
- && entry.operations == 0) {
- // nothing to record; skip
+ if (entry.isEmpty()) {
return;
}
@@ -295,21 +318,23 @@ public class NetworkStatsHistory implements Parcelable {
if (overlap <= 0) continue;
// integer math each time is faster than floating point
- final long fracRxBytes = entry.rxBytes * overlap / duration;
- final long fracRxPackets = entry.rxPackets * overlap / duration;
- final long fracTxBytes = entry.txBytes * overlap / duration;
- final long fracTxPackets = entry.txPackets * overlap / duration;
- final long fracOperations = entry.operations * overlap / duration;
+ final long fracRxBytes = rxBytes * overlap / duration;
+ final long fracRxPackets = rxPackets * overlap / duration;
+ final long fracTxBytes = txBytes * overlap / duration;
+ final long fracTxPackets = txPackets * overlap / duration;
+ final long fracOperations = operations * overlap / duration;
addLong(activeTime, i, overlap);
- addLong(rxBytes, i, fracRxBytes); entry.rxBytes -= fracRxBytes;
- addLong(rxPackets, i, fracRxPackets); entry.rxPackets -= fracRxPackets;
- addLong(txBytes, i, fracTxBytes); entry.txBytes -= fracTxBytes;
- addLong(txPackets, i, fracTxPackets); entry.txPackets -= fracTxPackets;
- addLong(operations, i, fracOperations); entry.operations -= fracOperations;
+ addLong(this.rxBytes, i, fracRxBytes); rxBytes -= fracRxBytes;
+ addLong(this.rxPackets, i, fracRxPackets); rxPackets -= fracRxPackets;
+ addLong(this.txBytes, i, fracTxBytes); txBytes -= fracTxBytes;
+ addLong(this.txPackets, i, fracTxPackets); txPackets -= fracTxPackets;
+ addLong(this.operations, i, fracOperations); operations -= fracOperations;
duration -= overlap;
}
+
+ totalBytes += entry.rxBytes + entry.txBytes;
}
/**
@@ -394,6 +419,7 @@ public class NetworkStatsHistory implements Parcelable {
/**
* Remove buckets older than requested cutoff.
*/
+ @Deprecated
public void removeBucketsBefore(long cutoff) {
int i;
for (i = 0; i < bucketCount; i++) {
@@ -415,6 +441,8 @@ public class NetworkStatsHistory implements Parcelable {
if (txPackets != null) txPackets = Arrays.copyOfRange(txPackets, i, length);
if (operations != null) operations = Arrays.copyOfRange(operations, i, length);
bucketCount -= i;
+
+ // TODO: subtract removed values from totalBytes
}
}
@@ -527,19 +555,17 @@ public class NetworkStatsHistory implements Parcelable {
return (long) (start + (r.nextFloat() * (end - start)));
}
- public void dump(String prefix, PrintWriter pw, boolean fullHistory) {
- pw.print(prefix);
+ public void dump(IndentingPrintWriter pw, boolean fullHistory) {
pw.print("NetworkStatsHistory: bucketDuration="); pw.println(bucketDuration);
+ pw.increaseIndent();
final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32);
if (start > 0) {
- pw.print(prefix);
- pw.print(" (omitting "); pw.print(start); pw.println(" buckets)");
+ pw.print("(omitting "); pw.print(start); pw.println(" buckets)");
}
for (int i = start; i < bucketCount; i++) {
- pw.print(prefix);
- pw.print(" bucketStart="); pw.print(bucketStart[i]);
+ pw.print("bucketStart="); pw.print(bucketStart[i]);
if (activeTime != null) { pw.print(" activeTime="); pw.print(activeTime[i]); }
if (rxBytes != null) { pw.print(" rxBytes="); pw.print(rxBytes[i]); }
if (rxPackets != null) { pw.print(" rxPackets="); pw.print(rxPackets[i]); }
@@ -548,12 +574,14 @@ public class NetworkStatsHistory implements Parcelable {
if (operations != null) { pw.print(" operations="); pw.print(operations[i]); }
pw.println();
}
+
+ pw.decreaseIndent();
}
@Override
public String toString() {
final CharArrayWriter writer = new CharArrayWriter();
- dump("", new PrintWriter(writer), false);
+ dump(new IndentingPrintWriter(writer, " "), false);
return writer.toString();
}
@@ -579,6 +607,10 @@ public class NetworkStatsHistory implements Parcelable {
if (array != null) array[i] += value;
}
+ public int estimateResizeBuckets(long newBucketDuration) {
+ return (int) (size() * getBucketDuration() / newBucketDuration);
+ }
+
/**
* Utility methods for interacting with {@link DataInputStream} and
* {@link DataOutputStream}, mostly dealing with writing partial arrays.
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 418b82fdeaa2..8ebfd8d0aaf9 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -18,6 +18,7 @@ package android.net;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkIdentity.scrubSubscriberId;
import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
@@ -231,10 +232,13 @@ public class NetworkTemplate implements Parcelable {
* Check if matches Wi-Fi network template.
*/
private boolean matchesWifi(NetworkIdentity ident) {
- if (ident.mType == TYPE_WIFI) {
- return true;
+ switch (ident.mType) {
+ case TYPE_WIFI:
+ case TYPE_WIFI_P2P:
+ return true;
+ default:
+ return false;
}
- return false;
}
/**
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 8bdb669d5824..dfdea383d6c7 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -195,7 +195,7 @@ public class TrafficStats {
// subtract starting values and return delta
final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
final NetworkStats profilingDelta = NetworkStats.subtract(
- profilingStop, sActiveProfilingStart, null);
+ profilingStop, sActiveProfilingStart, null, null);
sActiveProfilingStart = null;
return profilingDelta;
}
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 0fb49bcad14c..defe7aa0abcc 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Locale;
import java.util.RandomAccess;
import java.util.Set;
import libcore.net.UriCodec;
@@ -1716,6 +1717,38 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
return (!"false".equals(flag) && !"0".equals(flag));
}
+ /**
+ * Return a normalized representation of this Uri.
+ *
+ * <p>A normalized Uri has a lowercase scheme component.
+ * This aligns the Uri with Android best practices for
+ * intent filtering.
+ *
+ * <p>For example, "HTTP://www.android.com" becomes
+ * "http://www.android.com"
+ *
+ * <p>All URIs received from outside Android (such as user input,
+ * or external sources like Bluetooth, NFC, or the Internet) should
+ * be normalized before they are used to create an Intent.
+ *
+ * <p class="note">This method does <em>not</em> validate bad URI's,
+ * or 'fix' poorly formatted URI's - so do not use it for input validation.
+ * A Uri will always be returned, even if the Uri is badly formatted to
+ * begin with and a scheme component cannot be found.
+ *
+ * @return normalized Uri (never null)
+ * @see {@link android.content.Intent#setData}
+ * @see {@link #setNormalizedData}
+ */
+ public Uri normalize() {
+ String scheme = getScheme();
+ if (scheme == null) return this; // give up
+ String lowerScheme = scheme.toLowerCase(Locale.US);
+ if (scheme.equals(lowerScheme)) return this; // no change
+
+ return buildUpon().scheme(lowerScheme).build();
+ }
+
/** Identifies a null parcelled Uri. */
private static final int NULL_TYPE_ID = 0;
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 0b93ad03fe5f..61bc324a2f8e 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -17,7 +17,6 @@
package android.nfc;
import android.app.PendingIntent;
-import android.content.ComponentName;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.Tag;
@@ -44,4 +43,6 @@ interface INfcAdapter
void setForegroundDispatch(in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void setForegroundNdefPush(in NdefMessage msg, in INdefPushCallback callback);
+
+ void dispatch(in Tag tag);
}
diff --git a/core/java/android/nfc/NdefMessage.java b/core/java/android/nfc/NdefMessage.java
index 38bc16d6c223..5df9272c9fea 100644
--- a/core/java/android/nfc/NdefMessage.java
+++ b/core/java/android/nfc/NdefMessage.java
@@ -92,9 +92,7 @@ public final class NdefMessage implements Parcelable {
* @throws FormatException if the data cannot be parsed
*/
public NdefMessage(byte[] data) throws FormatException {
- if (data == null) {
- throw new NullPointerException("null data");
- }
+ if (data == null) throw new NullPointerException("data is null");
ByteBuffer buffer = ByteBuffer.wrap(data);
mRecords = NdefRecord.parse(buffer, false);
@@ -112,9 +110,8 @@ public final class NdefMessage implements Parcelable {
*/
public NdefMessage(NdefRecord record, NdefRecord ... records) {
// validate
- if (record == null) {
- throw new NullPointerException("record cannot be null");
- }
+ if (record == null) throw new NullPointerException("record cannot be null");
+
for (NdefRecord r : records) {
if (r == null) {
throw new NullPointerException("record cannot be null");
@@ -147,7 +144,12 @@ public final class NdefMessage implements Parcelable {
/**
* Get the NDEF Records inside this NDEF Message.<p>
- * An NDEF Message always has one or more NDEF Records.
+ * An {@link NdefMessage} always has one or more NDEF Records: so the
+ * following code to retrieve the first record is always safe
+ * (no need to check for null or array length >= 1):
+ * <pre>
+ * NdefRecord firstRecord = ndefMessage.getRecords()[0];
+ * </pre>
*
* @return array of one or more NDEF records.
*/
@@ -156,7 +158,28 @@ public final class NdefMessage implements Parcelable {
}
/**
- * Return this NDEF MEssage as raw bytes.<p>
+ * Return the length of this NDEF Message if it is written to a byte array
+ * with {@link #toByteArray}.<p>
+ * An NDEF Message can be formatted to bytes in different ways
+ * depending on chunking, SR, and ID flags, so the length returned
+ * by this method may not be equal to the length of the original
+ * byte array used to construct this NDEF Message. However it will
+ * always be equal to the length of the byte array produced by
+ * {@link #toByteArray}.
+ *
+ * @return length of this NDEF Message when written to bytes with {@link #toByteArray}
+ * @see #toByteArray
+ */
+ public int getByteArrayLength() {
+ int length = 0;
+ for (NdefRecord r : mRecords) {
+ length += r.getByteLength();
+ }
+ return length;
+ }
+
+ /**
+ * Return this NDEF Message as raw bytes.<p>
* The NDEF Message is formatted as per the NDEF 1.0 specification,
* and the byte array is suitable for network transmission or storage
* in an NFC Forum NDEF compatible tag.<p>
@@ -164,13 +187,10 @@ public final class NdefMessage implements Parcelable {
* short record (SR) format and omit the identifier field when possible.
*
* @return NDEF Message in binary format
+ * @see getByteArrayLength
*/
public byte[] toByteArray() {
- int length = 0;
- for (NdefRecord r : mRecords) {
- length += r.getByteLength();
- }
-
+ int length = getByteArrayLength();
ByteBuffer buffer = ByteBuffer.allocate(length);
for (int i=0; i<mRecords.length; i++) {
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index b4c488b7c0f8..0e9e8f4bfcf0 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -25,6 +26,7 @@ import java.nio.charset.Charsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Locale;
/**
* Represents an immutable NDEF Record.
@@ -305,9 +307,9 @@ public final class NdefRecord implements Parcelable {
* @return Android application NDEF record
*/
public static NdefRecord createApplicationRecord(String packageName) {
- if (packageName.length() == 0) {
- throw new IllegalArgumentException("empty package name");
- }
+ if (packageName == null) throw new NullPointerException("packageName is null");
+ if (packageName.length() == 0) throw new IllegalArgumentException("packageName is empty");
+
return new NdefRecord(TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, null,
packageName.getBytes(Charsets.UTF_8));
}
@@ -318,32 +320,27 @@ public final class NdefRecord implements Parcelable {
* Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
* and {@link #RTD_URI}. This is the most efficient encoding
* of a URI into NDEF.<p>
+ * The uri parameter will be normalized with
+ * {@link Uri#normalize} to set the scheme to lower case to
+ * follow Android best practices for intent filtering.
+ * However the unchecked exception
+ * {@link IllegalArgumentException} may be thrown if the uri
+ * parameter has serious problems, for example if it is empty, so always
+ * catch this exception if you are passing user-generated data into this
+ * method.<p>
+ *
* Reference specification: NFCForum-TS-RTD_URI_1.0
*
* @param uri URI to encode.
* @return an NDEF Record containing the URI
- * @throws IllegalArugmentException if a valid record cannot be created
+ * @throws IllegalArugmentException if the uri is empty or invalid
*/
public static NdefRecord createUri(Uri uri) {
- return createUri(uri.toString());
- }
+ if (uri == null) throw new NullPointerException("uri is null");
- /**
- * Create a new NDEF Record containing a URI.<p>
- * Use this method to encode a URI (or URL) into an NDEF Record.<p>
- * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
- * and {@link #RTD_URI}. This is the most efficient encoding
- * of a URI into NDEF.<p>
- * Reference specification: NFCForum-TS-RTD_URI_1.0
- *
- * @param uriString string URI to encode.
- * @return an NDEF Record containing the URI
- * @throws IllegalArugmentException if a valid record cannot be created
- */
- public static NdefRecord createUri(String uriString) {
- if (uriString.length() == 0) {
- throw new IllegalArgumentException("empty uriString");
- }
+ uri = uri.normalize();
+ String uriString = uri.toString();
+ if (uriString.length() == 0) throw new IllegalArgumentException("uri is empty");
byte prefix = 0;
for (int i = 1; i < URI_PREFIX_MAP.length; i++) {
@@ -361,28 +358,72 @@ public final class NdefRecord implements Parcelable {
}
/**
+ * Create a new NDEF Record containing a URI.<p>
+ * Use this method to encode a URI (or URL) into an NDEF Record.<p>
+ * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
+ * and {@link #RTD_URI}. This is the most efficient encoding
+ * of a URI into NDEF.<p>
+ * The uriString parameter will be normalized with
+ * {@link Uri#normalize} to set the scheme to lower case to
+ * follow Android best practices for intent filtering.
+ * However the unchecked exception
+ * {@link IllegalArgumentException} may be thrown if the uriString
+ * parameter has serious problems, for example if it is empty, so always
+ * catch this exception if you are passing user-generated data into this
+ * method.<p>
+ *
+ * Reference specification: NFCForum-TS-RTD_URI_1.0
+ *
+ * @param uriString string URI to encode.
+ * @return an NDEF Record containing the URI
+ * @throws IllegalArugmentException if the uriString is empty or invalid
+ */
+ public static NdefRecord createUri(String uriString) {
+ return createUri(Uri.parse(uriString));
+ }
+
+ /**
* Create a new NDEF Record containing MIME data.<p>
* Use this method to encode MIME-typed data into an NDEF Record,
* such as "text/plain", or "image/jpeg".<p>
- * Expects US-ASCII characters in mimeType. The encoding of the
- * mimeData depends on the mimeType.<p>
+ * The mimeType parameter will be normalized with
+ * {@link Intent#normalizeMimeType} to follow Android best
+ * practices for intent filtering, for example to force lower-case.
+ * However the unchecked exception
+ * {@link IllegalArgumentException} may be thrown
+ * if the mimeType parameter has serious problems,
+ * for example if it is empty, so always catch this
+ * exception if you are passing user-generated data into this method.
+ * <p>
* For efficiency, This method might not make an internal copy of the
* mimeData byte array, so take care not
- * to re-use the mimeData byte array while still using the returned
+ * to modify the mimeData byte array while still using the returned
* NdefRecord.
*
- * @param mimeType MIME type, expects US-ASCII characters only
+ * @param mimeType a valid MIME type
* @param mimeData MIME data as bytes
* @return an NDEF Record containing the MIME-typed data
- * @throws IllegalArugmentException if a valid record cannot be created
+ * @throws IllegalArugmentException if the mimeType is empty or invalid
+ *
*/
public static NdefRecord createMime(String mimeType, byte[] mimeData) {
- if (mimeType.length() == 0) {
- throw new IllegalArgumentException("empty mimeType");
+ if (mimeType == null) throw new NullPointerException("mimeType is null");
+
+ // We only do basic MIME type validation: trying to follow the
+ // RFCs strictly only ends in tears, since there are lots of MIME
+ // types in common use that are not strictly valid as per RFC rules
+ mimeType = Intent.normalizeMimeType(mimeType);
+ if (mimeType.length() == 0) throw new IllegalArgumentException("mimeType is empty");
+ int slashIndex = mimeType.indexOf('/');
+ if (slashIndex == 0) throw new IllegalArgumentException("mimeType must have major type");
+ if (slashIndex == mimeType.length() - 1) {
+ throw new IllegalArgumentException("mimeType must have minor type");
}
+ // missing '/' is allowed
- return new NdefRecord(TNF_MIME_MEDIA, mimeType.getBytes(Charsets.US_ASCII), null,
- mimeData);
+ // MIME RFCs suggest ASCII encoding for content-type
+ byte[] typeBytes = mimeType.getBytes(Charsets.US_ASCII);
+ return new NdefRecord(TNF_MIME_MEDIA, typeBytes, null, mimeData);
}
/**
@@ -391,32 +432,38 @@ public final class NdefRecord implements Parcelable {
* The data is typed by a domain name (usually your Android package name) and
* a domain-specific type. This data is packaged into a "NFC Forum External
* Type" NDEF Record.<p>
- * Both the domain and type used to construct an external record are case
- * insensitive, and this implementation will encode all characters to lower
- * case. Only a subset of ASCII characters are allowed for the domain
- * and type. There are no restrictions on the payload data.<p>
+ * NFC Forum requires that the domain and type used in an external record
+ * are treated as case insensitive, however Android intent filtering is
+ * always case sensitive. So this method will force the domain and type to
+ * lower-case before creating the NDEF Record.<p>
+ * The unchecked exception {@link IllegalArgumentException} will be thrown
+ * if the domain and type have serious problems, for example if either field
+ * is empty, so always catch this
+ * exception if you are passing user-generated data into this method.<p>
+ * There are no such restrictions on the payload data.<p>
* For efficiency, This method might not make an internal copy of the
* data byte array, so take care not
- * to re-use the data byte array while still using the returned
+ * to modify the data byte array while still using the returned
* NdefRecord.
*
* Reference specification: NFCForum-TS-RTD_1.0
* @param domain domain-name of issuing organization
* @param type domain-specific type of data
* @param data payload as bytes
- * @throws IllegalArugmentException if a valid record cannot be created
+ * @throws IllegalArugmentException if either domain or type are empty or invalid
*/
public static NdefRecord createExternal(String domain, String type, byte[] data) {
- if (domain.length() == 0 || type.length() == 0) {
- throw new IllegalArgumentException("empty domain or type");
- }
- byte[] byteDomain = domain.getBytes(Charsets.US_ASCII);
- ensureValidDomain(byteDomain);
- toLowerCase(byteDomain);
- byte[] byteType = type.getBytes(Charsets.US_ASCII);
- ensureValidWkt(byteType);
- toLowerCase(byteType);
+ if (domain == null) throw new NullPointerException("domain is null");
+ if (type == null) throw new NullPointerException("type is null");
+
+ domain = domain.trim().toLowerCase(Locale.US);
+ type = type.trim().toLowerCase(Locale.US);
+
+ if (domain.length() == 0) throw new IllegalArgumentException("domain is empty");
+ if (type.length() == 0) throw new IllegalArgumentException("type is empty");
+ byte[] byteDomain = domain.getBytes(Charsets.UTF_8);
+ byte[] byteType = type.getBytes(Charsets.UTF_8);
byte[] b = new byte[byteDomain.length + 1 + byteType.length];
System.arraycopy(byteDomain, 0, b, 0, byteDomain.length);
b[byteDomain.length] = ':';
@@ -574,51 +621,113 @@ public final class NdefRecord implements Parcelable {
}
/**
- * Helper to return the NdefRecord as a URI.
- * TODO: Consider making a member method instead of static
- * TODO: Consider more validation that this is a URI record
- * TODO: Make a public API
- * @hide
+ * Map this record to a MIME type, or return null if it cannot be mapped.<p>
+ * Currently this method considers all {@link #TNF_MIME_MEDIA} records to
+ * be MIME records, as well as some {@link #TNF_WELL_KNOWN} records such as
+ * {@link #RTD_TEXT}. If this is a MIME record then the MIME type as string
+ * is returned, otherwise null is returned.<p>
+ * This method does not perform validation that the MIME type is
+ * actually valid. It always attempts to
+ * return a string containing the type if this is a MIME record.<p>
+ * The returned MIME type will by normalized to lower-case using
+ * {@link Intent#normalizeMimeType}.<p>
+ * The MIME payload can be obtained using {@link #getPayload}.
+ *
+ * @return MIME type as a string, or null if this is not a MIME record
*/
- public static Uri parseWellKnownUriRecord(NdefRecord record) throws FormatException {
- byte[] payload = record.getPayload();
- if (payload.length < 2) {
- throw new FormatException("Payload is not a valid URI (missing prefix)");
+ public String toMimeType() {
+ switch (mTnf) {
+ case NdefRecord.TNF_WELL_KNOWN:
+ if (Arrays.equals(mType, NdefRecord.RTD_TEXT)) {
+ return "text/plain";
+ }
+ break;
+ case NdefRecord.TNF_MIME_MEDIA:
+ String mimeType = new String(mType, Charsets.US_ASCII);
+ return Intent.normalizeMimeType(mimeType);
}
+ return null;
+ }
- /*
- * payload[0] contains the URI Identifier Code, per the
- * NFC Forum "URI Record Type Definition" section 3.2.2.
- *
- * payload[1]...payload[payload.length - 1] contains the rest of
- * the URI.
- */
- int prefixIndex = (payload[0] & 0xff);
- if (prefixIndex < 0 || prefixIndex >= URI_PREFIX_MAP.length) {
- throw new FormatException("Payload is not a valid URI (invalid prefix)");
+ /**
+ * Map this record to a URI, or return null if it cannot be mapped.<p>
+ * Currently this method considers the following to be URI records:
+ * <ul>
+ * <li>{@link #TNF_ABSOLUTE_URI} records.</li>
+ * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_URI}.</li>
+ * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_SMART_POSTER}
+ * and containing a URI record in the NDEF message nested in the payload.
+ * </li>
+ * <li>{@link #TNF_EXTERNAL_TYPE} records.</li>
+ * </ul>
+ * If this is not a URI record by the above rules, then null is returned.<p>
+ * This method does not perform validation that the URI is
+ * actually valid: it always attempts to create and return a URI if
+ * this record appears to be a URI record by the above rules.<p>
+ * The returned URI will be normalized to have a lower case scheme
+ * using {@link Uri#normalize}.<p>
+ *
+ * @return URI, or null if this is not a URI record
+ */
+ public Uri toUri() {
+ return toUri(false);
+ }
+
+ private Uri toUri(boolean inSmartPoster) {
+ switch (mTnf) {
+ case TNF_WELL_KNOWN:
+ if (Arrays.equals(mType, RTD_SMART_POSTER) && !inSmartPoster) {
+ try {
+ // check payload for a nested NDEF Message containing a URI
+ NdefMessage nestedMessage = new NdefMessage(mPayload);
+ for (NdefRecord nestedRecord : nestedMessage.getRecords()) {
+ Uri uri = nestedRecord.toUri(true);
+ if (uri != null) {
+ return uri;
+ }
+ }
+ } catch (FormatException e) { }
+ } else if (Arrays.equals(mType, RTD_URI)) {
+ return parseWktUri().normalize();
+ }
+ break;
+
+ case TNF_ABSOLUTE_URI:
+ Uri uri = Uri.parse(new String(mType, Charsets.UTF_8));
+ return uri.normalize();
+
+ case TNF_EXTERNAL_TYPE:
+ if (inSmartPoster) {
+ break;
+ }
+ return Uri.parse("vnd.android.nfc://ext/" + new String(mType, Charsets.US_ASCII));
}
- String prefix = URI_PREFIX_MAP[prefixIndex];
- byte[] fullUri = concat(prefix.getBytes(Charsets.UTF_8),
- Arrays.copyOfRange(payload, 1, payload.length));
- return Uri.parse(new String(fullUri, Charsets.UTF_8));
+ return null;
}
- private static byte[] concat(byte[]... arrays) {
- int length = 0;
- for (byte[] array : arrays) {
- length += array.length;
+ /**
+ * Return complete URI of {@link #TNF_WELL_KNOWN}, {@link #RTD_URI} records.
+ * @return complete URI, or null if invalid
+ */
+ private Uri parseWktUri() {
+ if (mPayload.length < 2) {
+ return null;
}
- byte[] result = new byte[length];
- int pos = 0;
- for (byte[] array : arrays) {
- System.arraycopy(array, 0, result, pos, array.length);
- pos += array.length;
+
+ // payload[0] contains the URI Identifier Code, as per
+ // NFC Forum "URI Record Type Definition" section 3.2.2.
+ int prefixIndex = (mPayload[0] & (byte)0xFF);
+ if (prefixIndex < 0 || prefixIndex >= URI_PREFIX_MAP.length) {
+ return null;
}
- return result;
+ String prefix = URI_PREFIX_MAP[prefixIndex];
+ String suffix = new String(Arrays.copyOfRange(mPayload, 1, mPayload.length),
+ Charsets.UTF_8);
+ return Uri.parse(prefix + suffix);
}
/**
- * Main parsing method.<p>
+ * Main record parsing method.<p>
* Expects NdefMessage to begin immediately, allows trailing data.<p>
* Currently has strict validation of all fields as per NDEF 1.0
* specification section 2.5. We will attempt to keep this as strict as
@@ -902,42 +1011,4 @@ public final class NdefRecord implements Parcelable {
}
return s;
}
-
- /** Ensure valid 'DNS-char' as per RFC2234 */
- private static void ensureValidDomain(byte[] bs) {
- for (int i = 0; i < bs.length; i++) {
- byte b = bs[i];
- if ((b >= 'A' && b <= 'Z') ||
- (b >= 'a' && b <= 'z') ||
- (b >= '0' && b <= '9') ||
- b == '.' || b == '-') {
- continue;
- }
- throw new IllegalArgumentException("invalid character in domain");
- }
- }
-
- /** Ensure valid 'WKT-char' as per RFC2234 */
- private static void ensureValidWkt(byte[] bs) {
- for (int i = 0; i < bs.length; i++) {
- byte b = bs[i];
- if ((b >= 'A' && b <= 'Z') ||
- (b >= 'a' && b <= 'z') ||
- (b >= '0' && b <= '9') ||
- b == '(' || b == ')' || b == '+' || b == ',' || b == '-' ||
- b == ':' || b == '=' || b == '@' || b == ';' || b == '$' ||
- b == '_' || b == '!' || b == '*' || b == '\'' || b == '.') {
- continue;
- }
- throw new IllegalArgumentException("invalid character in type");
- }
- }
-
- private static void toLowerCase(byte[] b) {
- for (int i = 0; i < b.length; i++) {
- if (b[i] >= 'A' && b[i] <= 'Z') {
- b[i] += 0x20;
- }
- }
- }
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 53a0341f562a..5176857880d6 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -66,6 +66,9 @@ public final class NfcAdapter {
* <p>If the tag has an NDEF payload this intent is started before
* {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither
* {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started.
+ *
+ * <p>The MIME type or data URI of this intent are normalized before dispatch -
+ * so that MIME, URI scheme and URI host are always lower-case.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
@@ -151,9 +154,13 @@ public final class NfcAdapter {
public static final String EXTRA_TAG = "android.nfc.extra.TAG";
/**
- * Optional extra containing an array of {@link NdefMessage} present on the discovered tag for
- * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
- * {@link #ACTION_TAG_DISCOVERED} intents.
+ * Extra containing an array of {@link NdefMessage} present on the discovered tag.<p>
+ * This extra is mandatory for {@link #ACTION_NDEF_DISCOVERED} intents,
+ * and optional for {@link #ACTION_TECH_DISCOVERED}, and
+ * {@link #ACTION_TAG_DISCOVERED} intents.<p>
+ * When this extra is present there will always be at least one
+ * {@link NdefMessage} element. Most NDEF tags have only one NDEF message,
+ * but we use an array for future compatibility.
*/
public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
@@ -386,10 +393,10 @@ public final class NfcAdapter {
*/
@Deprecated
public static NfcAdapter getDefaultAdapter() {
- // introduce in API version 9 (GB 2.3)
+ // introduced in API version 9 (GB 2.3)
// deprecated in API version 10 (GB 2.3.3)
// removed from public API in version 16 (ICS MR2)
- // will need to maintain this as a hidden API for a while longer...
+ // should maintain as a hidden API for binary compatibility for a little longer
Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " +
"NfcAdapter.getDefaultAdapter(Context) instead", new Exception());
@@ -803,6 +810,7 @@ public final class NfcAdapter {
* @throws IllegalStateException if the Activity has already been paused
* @deprecated use {@link #setNdefPushMessage} instead
*/
+ @Deprecated
public void disableForegroundNdefPush(Activity activity) {
if (activity == null) {
throw new NullPointerException();
@@ -875,6 +883,24 @@ public final class NfcAdapter {
}
/**
+ * Inject a mock NFC tag.<p>
+ * Used for testing purposes.
+ * <p class="note">Requires the
+ * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ * @hide
+ */
+ public void dispatch(Tag tag) {
+ if (tag == null) {
+ throw new NullPointerException("tag cannot be null");
+ }
+ try {
+ sService.dispatch(tag);
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ }
+ }
+
+ /**
* @hide
*/
public INfcAdapterExtras getNfcAdapterExtrasInterface() {
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 9fe0bedfe358..f9b765cb290b 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -108,14 +108,14 @@ import java.util.Arrays;
* <p>
*/
public final class Tag implements Parcelable {
- /*package*/ final byte[] mId;
- /*package*/ final int[] mTechList;
- /*package*/ final String[] mTechStringList;
- /*package*/ final Bundle[] mTechExtras;
- /*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
- /*package*/ final INfcTag mTagService; // interface to NFC service, will be null if mock tag
-
- /*package*/ int mConnectedTechnology;
+ final byte[] mId;
+ final int[] mTechList;
+ final String[] mTechStringList;
+ final Bundle[] mTechExtras;
+ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
+ final INfcTag mTagService; // interface to NFC service, will be null if mock tag
+
+ int mConnectedTechnology;
/**
* Hidden constructor to be used by NFC service and internal classes.
diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java
index 913ae0eccda6..b6b347ca0619 100644
--- a/core/java/android/nfc/tech/BasicTagTechnology.java
+++ b/core/java/android/nfc/tech/BasicTagTechnology.java
@@ -18,7 +18,6 @@ package android.nfc.tech;
import android.nfc.ErrorCodes;
import android.nfc.Tag;
-import android.nfc.TagLostException;
import android.nfc.TransceiveResult;
import android.os.RemoteException;
import android.util.Log;
@@ -28,12 +27,13 @@ import java.io.IOException;
/**
* A base class for tag technologies that are built on top of transceive().
*/
-/* package */ abstract class BasicTagTechnology implements TagTechnology {
+abstract class BasicTagTechnology implements TagTechnology {
private static final String TAG = "NFC";
- /*package*/ final Tag mTag;
- /*package*/ boolean mIsConnected;
- /*package*/ int mSelectedTechnology;
+ final Tag mTag;
+
+ boolean mIsConnected;
+ int mSelectedTechnology;
BasicTagTechnology(Tag tag, int tech) throws RemoteException {
mTag = tag;
@@ -139,7 +139,7 @@ import java.io.IOException;
}
}
/** Internal transceive */
- /*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException {
+ byte[] transceive(byte[] data, boolean raw) throws IOException {
checkConnected();
try {
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 5e9abb7ba612..fd6bed7ee761 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -135,6 +135,8 @@ import java.util.concurrent.atomic.AtomicInteger;
* <p>There are a few threading rules that must be followed for this class to
* work properly:</p>
* <ul>
+ * <li>The AsyncTask class must be loaded on the UI thread. This is done
+ * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.</li>
* <li>The task instance must be created on the UI thread.</li>
* <li>{@link #execute} must be invoked on the UI thread.</li>
* <li>Do not call {@link #onPreExecute()}, {@link #onPostExecute},
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 88fea910395c..c106092122dc 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -167,6 +167,8 @@ public class Build {
* medium density normal size screens unless otherwise indicated).
* They can still explicitly specify screen support either way with the
* supports-screens manifest tag.
+ * <li> {@link android.widget.TabHost} will use the new dark tab
+ * background design.
* </ul>
*/
public static final int DONUT = 4;
@@ -208,6 +210,13 @@ public class Build {
/**
* November 2010: Android 2.3
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li> The application's notification icons will be shown on the new
+ * dark status bar background, so must be visible in this situation.
+ * </ul>
*/
public static final int GINGERBREAD = 9;
@@ -224,14 +233,34 @@ public class Build {
* <ul>
* <li> The default theme for applications is now dark holographic:
* {@link android.R.style#Theme_Holo}.
+ * <li> On large screen devices that do not have a physical menu
+ * button, the soft (compatibility) menu is disabled.
* <li> The activity lifecycle has changed slightly as per
* {@link android.app.Activity}.
+ * <li> An application will crash if it does not call through
+ * to the super implementation of its
+ * {@link android.app.Activity#onPause Activity.onPause()} method.
* <li> When an application requires a permission to access one of
* its components (activity, receiver, service, provider), this
* permission is no longer enforced when the application wants to
* access its own component. This means it can require a permission
* on a component that it does not itself hold and still access that
* component.
+ * <li> {@link android.content.Context#getSharedPreferences
+ * Context.getSharedPreferences()} will not automatically reload
+ * the preferences if they have changed on storage, unless
+ * {@link android.content.Context#MODE_MULTI_PROCESS} is used.
+ * <li> {@link android.view.ViewGroup#setMotionEventSplittingEnabled}
+ * will default to true.
+ * <li> {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH}
+ * is enabled by default on windows.
+ * <li> {@link android.widget.PopupWindow#isSplitTouchEnabled()
+ * PopupWindow.isSplitTouchEnabled()} will return true by default.
+ * <li> {@link android.widget.GridView} and {@link android.widget.ListView}
+ * will use {@link android.view.View#setActivated View.setActivated}
+ * for selected items if they do not implement {@link android.widget.Checkable}.
+ * <li> {@link android.widget.Scroller} will be constructed with
+ * "flywheel" behavior enabled by default.
* </ul>
*/
public static final int HONEYCOMB = 11;
@@ -266,13 +295,26 @@ public class Build {
* preferred over the older screen size buckets and for older devices
* the appropriate buckets will be inferred from them.</p>
*
- * <p>New {@link android.content.pm.PackageManager#FEATURE_SCREEN_PORTRAIT}
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li><p>New {@link android.content.pm.PackageManager#FEATURE_SCREEN_PORTRAIT}
* and {@link android.content.pm.PackageManager#FEATURE_SCREEN_LANDSCAPE}
- * features are introduced in this release. Applications that target
+ * features were introduced in this release. Applications that target
* previous platform versions are assumed to require both portrait and
* landscape support in the device; when targeting Honeycomb MR1 or
* greater the application is responsible for specifying any specific
* orientation it requires.</p>
+ * <li><p>{@link android.os.AsyncTask} will use the serial executor
+ * by default when calling {@link android.os.AsyncTask#execute}.</p>
+ * <li><p>{@link android.content.pm.ActivityInfo#configChanges
+ * ActivityInfo.configChanges} will have the
+ * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE} and
+ * {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE}
+ * bits set; these need to be cleared for older applications because
+ * some developers have done absolute comparisons against this value
+ * instead of correctly masking the bits they are interested in.
+ * </ul>
*/
public static final int HONEYCOMB_MR2 = 13;
@@ -306,14 +348,31 @@ public class Build {
* <li> The fadingEdge attribute on views will be ignored (fading edges is no
* longer a standard part of the UI). A new requiresFadingEdge attribute allows
* applications to still force fading edges on for special cases.
+ * <li> {@link android.content.Context#bindService Context.bindService()}
+ * will not automatically add in {@link android.content.Context#BIND_WAIVE_PRIORITY}.
+ * <li> App Widgets will have standard padding automatically added around
+ * them, rather than relying on the padding being baked into the widget itself.
+ * <li> An exception will be thrown if you try to change the type of a
+ * window after it has been added to the window manager. Previously this
+ * would result in random incorrect behavior.
+ * <li> {@link android.view.animation.AnimationSet} will parse out
+ * the duration, fillBefore, fillAfter, repeatMode, and startOffset
+ * XML attributes that are defined.
+ * <li> {@link android.app.ActionBar#setHomeButtonEnabled
+ * ActionBar.setHomeButtonEnabled()} is false by default.
* </ul>
*/
public static final int ICE_CREAM_SANDWICH = 14;
/**
- * Android 4.0.3.
+ * December 2011: Android 4.0.3.
*/
public static final int ICE_CREAM_SANDWICH_MR1 = 15;
+
+ /**
+ * Next up on Android!
+ */
+ public static final int JELLY_BEAN = CUR_DEVELOPMENT;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 4e016723eba3..d11219b0431c 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -62,6 +62,14 @@ public final class MediaStore {
public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
/**
+ * The method name used by the media scanner and mtp to tell the media provider to
+ * rescan and reclassify that have become unhidden because of renaming folders or
+ * removing nomedia files
+ * @hide
+ */
+ public static final String UNHIDE_CALL = "unhide";
+
+ /**
* Activity Action: Launch a music player.
* The activity should be able to play, browse, or manipulate music files stored on the device.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ba9046cbc5cb..f14d27e7e60a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -747,7 +747,7 @@ public final class Settings {
Cursor c = null;
try {
c = cp.query(mUri, SELECT_VALUE, NAME_EQ_PLACEHOLDER,
- new String[]{name}, null);
+ new String[]{name}, null, null);
if (c == null) {
Log.w(TAG, "Can't get key " + name + " from " + mUri);
return null;
@@ -4111,17 +4111,38 @@ public final class Settings {
/** {@hide} */
public static final String NETSTATS_POLL_INTERVAL = "netstats_poll_interval";
/** {@hide} */
- public static final String NETSTATS_PERSIST_THRESHOLD = "netstats_persist_threshold";
+ public static final String NETSTATS_TIME_CACHE_MAX_AGE = "netstats_time_cache_max_age";
/** {@hide} */
- public static final String NETSTATS_NETWORK_BUCKET_DURATION = "netstats_network_bucket_duration";
+ public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes";
/** {@hide} */
- public static final String NETSTATS_NETWORK_MAX_HISTORY = "netstats_network_max_history";
+ public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled";
+
+ /** {@hide} */
+ public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration";
+ /** {@hide} */
+ public static final String NETSTATS_DEV_PERSIST_BYTES = "netstats_dev_persist_bytes";
+ /** {@hide} */
+ public static final String NETSTATS_DEV_ROTATE_AGE = "netstats_dev_rotate_age";
+ /** {@hide} */
+ public static final String NETSTATS_DEV_DELETE_AGE = "netstats_dev_delete_age";
+
/** {@hide} */
public static final String NETSTATS_UID_BUCKET_DURATION = "netstats_uid_bucket_duration";
/** {@hide} */
- public static final String NETSTATS_UID_MAX_HISTORY = "netstats_uid_max_history";
+ public static final String NETSTATS_UID_PERSIST_BYTES = "netstats_uid_persist_bytes";
+ /** {@hide} */
+ public static final String NETSTATS_UID_ROTATE_AGE = "netstats_uid_rotate_age";
+ /** {@hide} */
+ public static final String NETSTATS_UID_DELETE_AGE = "netstats_uid_delete_age";
+
+ /** {@hide} */
+ public static final String NETSTATS_UID_TAG_BUCKET_DURATION = "netstats_uid_tag_bucket_duration";
+ /** {@hide} */
+ public static final String NETSTATS_UID_TAG_PERSIST_BYTES = "netstats_uid_tag_persist_bytes";
+ /** {@hide} */
+ public static final String NETSTATS_UID_TAG_ROTATE_AGE = "netstats_uid_tag_rotate_age";
/** {@hide} */
- public static final String NETSTATS_TAG_MAX_HISTORY = "netstats_tag_max_history";
+ public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
/** Preferred NTP server. {@hide} */
public static final String NTP_SERVER = "ntp_server";
diff --git a/core/java/android/text/MeasuredText.java b/core/java/android/text/MeasuredText.java
index c184c1164c45..a52e2bae9e2a 100644
--- a/core/java/android/text/MeasuredText.java
+++ b/core/java/android/text/MeasuredText.java
@@ -109,6 +109,9 @@ class MeasuredText {
for (int i = 0; i < spans.length; i++) {
int startInPara = spanned.getSpanStart(spans[i]) - start;
int endInPara = spanned.getSpanEnd(spans[i]) - start;
+ // The span interval may be larger and must be restricted to [start, end[
+ if (startInPara < 0) startInPara = 0;
+ if (endInPara > len) endInPara = len;
for (int j = startInPara; j < endInPara; j++) {
mChars[j] = '\uFFFC';
}
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index b4445ca1e0ed..e9b0d325d257 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -481,6 +481,9 @@ public class Time {
* @throws android.util.TimeFormatException if s cannot be parsed.
*/
public boolean parse3339(String s) {
+ if (s == null) {
+ throw new NullPointerException("time string is null");
+ }
if (nativeParse3339(s)) {
timezone = TIMEZONE_UTC;
return true;
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 0f26a34ece8d..5dc206fe730b 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -25,6 +25,7 @@ import android.os.SystemClock;
import android.text.ParcelableSpan;
import android.text.TextPaint;
import android.text.TextUtils;
+import android.util.Log;
import android.widget.TextView;
import java.util.Arrays;
@@ -114,7 +115,7 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
* @param context Context for the application
* @param locale locale Locale of the suggestions
* @param suggestions Suggestions for the string under the span. Only the first up to
- * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered.
+ * {@link SuggestionSpan#SUGGESTIONS_MAX_SIZE} will be considered. Null values not permitted.
* @param flags Additional flags indicating how this span is handled in TextView
* @param notificationTargetClass if not null, this class will get notified when the user
* selects one of the suggestions.
@@ -124,10 +125,13 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan {
final int N = Math.min(SUGGESTIONS_MAX_SIZE, suggestions.length);
mSuggestions = Arrays.copyOf(suggestions, N);
mFlags = flags;
- if (context != null && locale == null) {
+ if (locale != null) {
+ mLocaleString = locale.toString();
+ } else if (context != null) {
mLocaleString = context.getResources().getConfiguration().locale.toString();
} else {
- mLocaleString = locale.toString();
+ Log.e("SuggestionSpan", "No locale or context specified in SuggestionSpan constructor");
+ mLocaleString = "";
}
if (notificationTargetClass != null) {
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 519b98056b9f..a43d36c14660 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -57,6 +57,13 @@ public class DisplayMetrics {
public static final int DENSITY_XHIGH = 320;
/**
+ * Standard quantized DPI for extra-extra-high-density screens. Applications
+ * should not generally worry about this density; relying on XHIGH graphics
+ * being scaled up to it should be sufficient for almost all cases.
+ */
+ public static final int DENSITY_XXHIGH = 480;
+
+ /**
* The reference density used throughout the system.
*/
public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index 34e7d4d746bb..0349a2be3fbf 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -18,9 +18,15 @@ package android.view;
/**
- * Represents a contextual mode of the user interface. Action modes can be used for
- * modal interactions with content and replace parts of the normal UI until finished.
- * Examples of good action modes include selection modes, search, content editing, etc.
+ * Represents a contextual mode of the user interface. Action modes can be used to provide
+ * alternative interaction modes and replace parts of the normal UI until finished.
+ * Examples of good action modes include text selection and contextual actions.
+ * <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>
+ * developer guide.</p>
+ * </div>
*/
public abstract class ActionMode {
private Object mTag;
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index c08a402412c5..fa4dd25a6f38 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -189,7 +189,7 @@ class GLES20Canvas extends HardwareCanvas {
}
private static native int nGetMaximumTextureWidth();
- private static native int nGetMaximumTextureHeight();
+ private static native int nGetMaximumTextureHeight();
///////////////////////////////////////////////////////////////////////////
// Setup
@@ -268,6 +268,24 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nFinish(int renderer);
+ /**
+ * Returns the size of the stencil buffer required by the underlying
+ * implementation.
+ *
+ * @return The minimum number of bits the stencil buffer must. Always >= 0.
+ *
+ * @hide
+ */
+ public static int getStencilSize() {
+ return nGetStencilSize();
+ }
+
+ private static native int nGetStencilSize();
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Functor
+ ///////////////////////////////////////////////////////////////////////////
+
@Override
public boolean callDrawGLFunction(int drawGLFunction) {
return nCallDrawGLFunction(mRenderer, drawGLFunction);
@@ -275,7 +293,6 @@ class GLES20Canvas extends HardwareCanvas {
private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
-
///////////////////////////////////////////////////////////////////////////
// Memory
///////////////////////////////////////////////////////////////////////////
@@ -361,6 +378,12 @@ class GLES20Canvas extends HardwareCanvas {
private static native int nGetDisplayListSize(int displayList);
+ static void setDisplayListName(int displayList, String name) {
+ nSetDisplayListName(displayList, name);
+ }
+
+ private static native void nSetDisplayListName(int displayList, String name);
+
@Override
public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
return nDrawDisplayList(mRenderer,
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 0cb944957130..969c9ab0710f 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -31,10 +31,17 @@ class GLES20DisplayList extends DisplayList {
private GLES20RecordingCanvas mCanvas;
private boolean mValid;
+ // Used for debugging
+ private final String mName;
+
// The native display list will be destroyed when this object dies.
// DO NOT overwrite this reference once it is set.
private DisplayListFinalizer mFinalizer;
+ GLES20DisplayList(String name) {
+ mName = name;
+ }
+
int getNativeDisplayList() {
if (!mValid || mFinalizer == null) {
throw new IllegalStateException("The display list is not valid.");
@@ -75,6 +82,7 @@ class GLES20DisplayList extends DisplayList {
mCanvas.end(mFinalizer.mNativeDisplayList);
} else {
mFinalizer = new DisplayListFinalizer(mCanvas.end(0));
+ GLES20Canvas.setDisplayListName(mFinalizer.mNativeDisplayList, mName);
}
mCanvas.recycle();
mCanvas = null;
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 4592ae6c1a57..9e8a228edfa1 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -238,6 +238,15 @@ public abstract class HardwareRenderer {
private static native void nSetupShadersDiskCache(String cacheFile);
/**
+ * Notifies EGL that the frame is about to be rendered.
+ */
+ private static void beginFrame() {
+ nBeginFrame();
+ }
+
+ private static native void nBeginFrame();
+
+ /**
* Interface used to receive callbacks whenever a view is drawn by
* a hardware renderer instance.
*/
@@ -274,9 +283,12 @@ public abstract class HardwareRenderer {
* Creates a new display list that can be used to record batches of
* drawing operations.
*
+ * @param name The name of the display list, used for debugging purpose.
+ * May be null
+ *
* @return A new display list.
*/
- public abstract DisplayList createDisplayList();
+ public abstract DisplayList createDisplayList(String name);
/**
* Creates a new hardware layer. A hardware layer built by calling this
@@ -808,6 +820,7 @@ public abstract class HardwareRenderer {
}
void onPreDraw(Rect dirty) {
+
}
void onPostDraw() {
@@ -832,6 +845,8 @@ public abstract class HardwareRenderer {
dirty = null;
}
+ beginFrame();
+
onPreDraw(dirty);
HardwareCanvas canvas = mCanvas;
@@ -1035,7 +1050,7 @@ public abstract class HardwareRenderer {
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 0,
- EGL_STENCIL_SIZE, 0,
+ EGL_STENCIL_SIZE, GLES20Canvas.getStencilSize(),
EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
(dirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
EGL_NONE
@@ -1082,8 +1097,8 @@ public abstract class HardwareRenderer {
}
@Override
- public DisplayList createDisplayList() {
- return new GLES20DisplayList();
+ public DisplayList createDisplayList(String name) {
+ return new GLES20DisplayList(name);
}
@Override
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1b6e0ac12f11..d80d0801f2c9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3770,6 +3770,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
if ((mPrivateFlags & FOCUSED) != 0) {
+ // If this is the first focusable do not clear focus since the we
+ // try to give it focus every time a view clears its focus. Hence,
+ // the view that would gain focus already has it.
+ View firstFocusable = getFirstFocusable();
+ if (firstFocusable == this) {
+ return;
+ }
+
mPrivateFlags &= ~FOCUSED;
if (mParent != null) {
@@ -3778,9 +3786,24 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
onFocusChanged(false, 0, null);
refreshDrawableState();
+
+ // The view cleared focus and invoked the callbacks, so now is the
+ // time to give focus to the the first focusable to ensure that the
+ // gain focus is announced after clear focus.
+ if (firstFocusable != null) {
+ firstFocusable.requestFocus(FOCUS_FORWARD);
+ }
}
}
+ private View getFirstFocusable() {
+ ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot != null) {
+ return viewRoot.focusSearch(null, FOCUS_FORWARD);
+ }
+ return null;
+ }
+
/**
* Called to clear the focus of a view that is about to be removed.
* Doesn't call clearChildFocus, which prevents this view from taking
@@ -6822,7 +6845,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if ((changed & VISIBILITY_MASK) != 0) {
if (mParent instanceof ViewGroup) {
- ((ViewGroup) mParent).onChildVisibilityChanged(this, (flags & VISIBILITY_MASK));
+ ((ViewGroup) mParent).onChildVisibilityChanged(this, (changed & VISIBILITY_MASK),
+ (flags & VISIBILITY_MASK));
((View) mParent).invalidate(true);
} else if (mParent != null) {
mParent.invalidateChild(this, null);
@@ -10373,7 +10397,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
// we copy in child display lists into ours in drawChild()
mRecreateDisplayList = true;
if (mDisplayList == null) {
- mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList();
+ final String name = getClass().getSimpleName();
+ mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList(name);
// If we're creating a new display list, make sure our parent gets invalidated
// since they will need to recreate their display list to account for this
// new child display list.
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 8652366517dd..d3af61841295 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -675,11 +675,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
@Override
public void clearFocus() {
- super.clearFocus();
-
- // clear any child focus if it exists
- if (mFocused != null) {
+ if (DBG) {
+ System.out.println(this + " clearFocus()");
+ }
+ if (mFocused == null) {
+ super.clearFocus();
+ } else {
mFocused.clearFocus();
+ mFocused = null;
}
}
@@ -691,12 +694,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (DBG) {
System.out.println(this + " unFocus()");
}
-
- super.unFocus();
- if (mFocused != null) {
+ if (mFocused == null) {
+ super.unFocus();
+ } else {
mFocused.unFocus();
+ mFocused = null;
}
- mFocused = null;
}
/**
@@ -888,18 +891,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
+ * Called when a view's visibility has changed. Notify the parent to take any appropriate
+ * action.
+ *
+ * @param child The view whose visibility has changed
+ * @param oldVisibility The previous visibility value (GONE, INVISIBLE, or VISIBLE).
+ * @param newVisibility The new visibility value (GONE, INVISIBLE, or VISIBLE).
* @hide
- * @param child
- * @param visibility
*/
- protected void onChildVisibilityChanged(View child, int visibility) {
+ protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
if (mTransition != null) {
- if (visibility == VISIBLE) {
- mTransition.showChild(this, child);
+ if (newVisibility == VISIBLE) {
+ mTransition.showChild(this, child, oldVisibility);
} else {
- mTransition.hideChild(this, child);
- }
- if (visibility != VISIBLE) {
+ mTransition.hideChild(this, child, newVisibility);
// Only track this on disappearing views - appearing views are already visible
// and don't need special handling during drawChild()
if (mVisibilityChangingChildren == null) {
@@ -914,7 +919,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// in all cases, for drags
if (mCurrentDrag != null) {
- if (visibility == VISIBLE) {
+ if (newVisibility == VISIBLE) {
notifyChildOfDrag(child);
}
}
@@ -2661,8 +2666,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
child.onAnimationStart();
}
- more = a.getTransformation(drawingTime, mChildTransformation,
- scalingRequired ? mAttachInfo.mApplicationScale : 1f);
+ more = a.getTransformation(drawingTime, mChildTransformation, 1f);
if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
if (mInvalidationTransformation == null) {
mInvalidationTransformation = new Transformation();
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 89a1ef26918d..0fdcd0f2d879 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -113,6 +113,10 @@ public class ViewPropertyAnimator {
* on that list are added to the list of properties associated with that animator.
*/
ArrayList<NameValuesHolder> mPendingAnimations = new ArrayList<NameValuesHolder>();
+ private Runnable mPendingSetupAction;
+ private Runnable mPendingCleanupAction;
+ private Runnable mPendingOnStartAction;
+ private Runnable mPendingOnEndAction;
/**
* Constants used to associate a property being requested and the mechanism used to set
@@ -199,6 +203,10 @@ public class ViewPropertyAnimator {
*/
private HashMap<Animator, PropertyBundle> mAnimatorMap =
new HashMap<Animator, PropertyBundle>();
+ private HashMap<Animator, Runnable> mAnimatorSetupMap;
+ private HashMap<Animator, Runnable> mAnimatorCleanupMap;
+ private HashMap<Animator, Runnable> mAnimatorOnStartMap;
+ private HashMap<Animator, Runnable> mAnimatorOnEndMap;
/**
* This is the information we need to set each property during the animation.
@@ -614,6 +622,93 @@ public class ViewPropertyAnimator {
}
/**
+ * The View associated with this ViewPropertyAnimator will have its
+ * {@link View#setLayerType(int, android.graphics.Paint) layer type} set to
+ * {@link View#LAYER_TYPE_HARDWARE} for the duration of the next animation. This state
+ * is not persistent, either on the View or on this ViewPropertyAnimator: the layer type
+ * of the View will be restored when the animation ends to what it was when this method was
+ * called, and this setting on ViewPropertyAnimator is only valid for the next animation.
+ * Note that calling this method and then independently setting the layer type of the View
+ * (by a direct call to {@link View#setLayerType(int, android.graphics.Paint)}) will result
+ * in some inconsistency, including having the layer type restored to its pre-withLayer()
+ * value when the animation ends.
+ *
+ * @see View#setLayerType(int, android.graphics.Paint)
+ * @return This object, allowing calls to methods in this class to be chained.
+ */
+ public ViewPropertyAnimator withLayer() {
+ mPendingSetupAction= new Runnable() {
+ @Override
+ public void run() {
+ mView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+ };
+ final int currentLayerType = mView.getLayerType();
+ mPendingCleanupAction = new Runnable() {
+ @Override
+ public void run() {
+ mView.setLayerType(currentLayerType, null);
+ }
+ };
+ if (mAnimatorSetupMap == null) {
+ mAnimatorSetupMap = new HashMap<Animator, Runnable>();
+ }
+ if (mAnimatorCleanupMap == null) {
+ mAnimatorCleanupMap = new HashMap<Animator, Runnable>();
+ }
+
+ return this;
+ }
+
+ /**
+ * Specifies an action to take place when the next animation runs. If there is a
+ * {@link #setStartDelay(long) startDelay} set on this ViewPropertyAnimator, then the
+ * action will run after that startDelay expires, when the actual animation begins.
+ * This method, along with {@link #withEndAction(Runnable)}, is intended to help facilitate
+ * choreographing ViewPropertyAnimator animations with other animations or actions
+ * in the application.
+ *
+ * @param runnable The action to run when the next animation starts.
+ * @return This object, allowing calls to methods in this class to be chained.
+ */
+ public ViewPropertyAnimator withStartAction(Runnable runnable) {
+ mPendingOnStartAction = runnable;
+ if (runnable != null && mAnimatorOnStartMap == null) {
+ mAnimatorOnStartMap = new HashMap<Animator, Runnable>();
+ }
+ return this;
+ }
+
+ /**
+ * Specifies an action to take place when the next animation ends. The action is only
+ * run if the animation ends normally; if the ViewPropertyAnimator is canceled during
+ * that animation, the runnable will not run.
+ * This method, along with {@link #withStartAction(Runnable)}, is intended to help facilitate
+ * choreographing ViewPropertyAnimator animations with other animations or actions
+ * in the application.
+ *
+ * <p>For example, the following code animates a view to x=200 and then back to 0:</p>
+ * <pre>
+ * Runnable endAction = new Runnable() {
+ * public void run() {
+ * view.animate().x(0);
+ * }
+ * };
+ * view.animate().x(200).onEnd(endAction);
+ * </pre>
+ *
+ * @param runnable The action to run when the next animation ends.
+ * @return This object, allowing calls to methods in this class to be chained.
+ */
+ public ViewPropertyAnimator withEndAction(Runnable runnable) {
+ mPendingOnEndAction = runnable;
+ if (runnable != null && mAnimatorOnEndMap == null) {
+ mAnimatorOnEndMap = new HashMap<Animator, Runnable>();
+ }
+ return this;
+ }
+
+ /**
* Starts the underlying Animator for a set of properties. We use a single animator that
* simply runs from 0 to 1, and then use that fractional value to set each property
* value accordingly.
@@ -630,6 +725,22 @@ public class ViewPropertyAnimator {
propertyMask |= nameValuesHolder.mNameConstant;
}
mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList));
+ if (mPendingSetupAction != null) {
+ mAnimatorSetupMap.put(animator, mPendingSetupAction);
+ mPendingSetupAction = null;
+ }
+ if (mPendingCleanupAction != null) {
+ mAnimatorCleanupMap.put(animator, mPendingCleanupAction);
+ mPendingCleanupAction = null;
+ }
+ if (mPendingOnStartAction != null) {
+ mAnimatorOnStartMap.put(animator, mPendingOnStartAction);
+ mPendingOnStartAction = null;
+ }
+ if (mPendingOnEndAction != null) {
+ mAnimatorOnEndMap.put(animator, mPendingOnEndAction);
+ mPendingOnEndAction = null;
+ }
animator.addUpdateListener(mAnimatorEventListener);
animator.addListener(mAnimatorEventListener);
if (mStartDelaySet) {
@@ -800,6 +911,20 @@ public class ViewPropertyAnimator {
implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
@Override
public void onAnimationStart(Animator animation) {
+ if (mAnimatorSetupMap != null) {
+ Runnable r = mAnimatorSetupMap.get(animation);
+ if (r != null) {
+ r.run();
+ }
+ mAnimatorSetupMap.remove(animation);
+ }
+ if (mAnimatorOnStartMap != null) {
+ Runnable r = mAnimatorOnStartMap.get(animation);
+ if (r != null) {
+ r.run();
+ }
+ mAnimatorOnStartMap.remove(animation);
+ }
if (mListener != null) {
mListener.onAnimationStart(animation);
}
@@ -810,6 +935,9 @@ public class ViewPropertyAnimator {
if (mListener != null) {
mListener.onAnimationCancel(animation);
}
+ if (mAnimatorOnEndMap != null) {
+ mAnimatorOnEndMap.remove(animation);
+ }
}
@Override
@@ -824,6 +952,20 @@ public class ViewPropertyAnimator {
if (mListener != null) {
mListener.onAnimationEnd(animation);
}
+ if (mAnimatorOnEndMap != null) {
+ Runnable r = mAnimatorOnEndMap.get(animation);
+ if (r != null) {
+ r.run();
+ }
+ mAnimatorOnEndMap.remove(animation);
+ }
+ if (mAnimatorCleanupMap != null) {
+ Runnable r = mAnimatorCleanupMap.get(animation);
+ if (r != null) {
+ r.run();
+ }
+ mAnimatorCleanupMap.remove(animation);
+ }
mAnimatorMap.remove(animation);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e43258fba87b..3f61e6b38fe8 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -169,6 +169,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
View mView;
View mFocusedView;
View mRealFocusedView; // this is not set to null in touch mode
+ View mOldFocusedView;
int mViewVisibility;
boolean mAppVisible = true;
int mOrigWindowType = -1;
@@ -2229,32 +2230,33 @@ public final class ViewRootImpl extends Handler implements ViewParent,
public void requestChildFocus(View child, View focused) {
checkThread();
- if (mFocusedView != focused) {
- mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mFocusedView, focused);
- scheduleTraversals();
+
+ if (DEBUG_INPUT_RESIZE) {
+ Log.v(TAG, "Request child focus: focus now " + focused);
}
+
+ mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, focused);
+ scheduleTraversals();
+
mFocusedView = mRealFocusedView = focused;
- if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Request child focus: focus now "
- + mFocusedView);
}
public void clearChildFocus(View child) {
checkThread();
- View oldFocus = mFocusedView;
+ if (DEBUG_INPUT_RESIZE) {
+ Log.v(TAG, "Clearing child focus");
+ }
+
+ mOldFocusedView = mFocusedView;
- if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Clearing child focus");
- mFocusedView = mRealFocusedView = null;
- if (mView != null && !mView.hasFocus()) {
- // If a view gets the focus, the listener will be invoked from requestChildFocus()
- if (!mView.requestFocus(View.FOCUS_FORWARD)) {
- mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
- }
- } else if (oldFocus != null) {
- mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null);
+ // Invoke the listener only if there is no view to take focus
+ if (focusSearch(null, View.FOCUS_FORWARD) == null) {
+ mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mOldFocusedView, null);
}
- }
+ mFocusedView = mRealFocusedView = null;
+ }
public void focusableViewAvailable(View v) {
checkThread();
@@ -2727,6 +2729,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mView.unFocus();
mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(focused, null);
mFocusedView = null;
+ mOldFocusedView = null;
return true;
}
}
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 5ec1ec3e03f3..bd02d62b64f2 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -193,10 +193,12 @@ public class BaseInputConnection implements InputConnection {
/**
* The default implementation performs the deletion around the current
* selection position of the editable text.
+ * @param beforeLength
+ * @param afterLength
*/
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
- if (DEBUG) Log.v(TAG, "deleteSurroundingText " + leftLength
- + " / " + rightLength);
+ public boolean deleteSurroundingText(int beforeLength, int afterLength) {
+ if (DEBUG) Log.v(TAG, "deleteSurroundingText " + beforeLength
+ + " / " + afterLength);
final Editable content = getEditable();
if (content == null) return false;
@@ -226,17 +228,17 @@ public class BaseInputConnection implements InputConnection {
int deleted = 0;
- if (leftLength > 0) {
- int start = a - leftLength;
+ if (beforeLength > 0) {
+ int start = a - beforeLength;
if (start < 0) start = 0;
content.delete(start, a);
deleted = a - start;
}
- if (rightLength > 0) {
+ if (afterLength > 0) {
b = b - deleted;
- int end = b + rightLength;
+ int end = b + afterLength;
if (end > content.length()) end = content.length();
content.delete(b, end);
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index a6639d18511b..3563d4d31eef 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -138,19 +138,21 @@ public interface InputConnection {
int flags);
/**
- * Delete <var>leftLength</var> characters of text before the current cursor
- * position, and delete <var>rightLength</var> characters of text after the
- * current cursor position, excluding composing text.
+ * Delete <var>beforeLength</var> characters of text before the current cursor
+ * position, and delete <var>afterLength</var> characters of text after the
+ * current cursor position, excluding composing text. Before and after refer
+ * to the order of the characters in the string, not to their visual representation.
*
- * @param leftLength The number of characters to be deleted before the
+ *
+ * @param beforeLength The number of characters to be deleted before the
* current cursor position.
- * @param rightLength The number of characters to be deleted after the
+ * @param afterLength The number of characters to be deleted after the
* current cursor position.
- *
+ *
* @return Returns true on success, false if the input connection is no longer
* valid.
*/
- public boolean deleteSurroundingText(int leftLength, int rightLength);
+ public boolean deleteSurroundingText(int beforeLength, int afterLength);
/**
* Set composing text around the current cursor position with the given text,
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index 690ea85306b8..a48473e17932 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -62,8 +62,8 @@ public class InputConnectionWrapper implements InputConnection {
return mTarget.getExtractedText(request, flags);
}
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
- return mTarget.deleteSurroundingText(leftLength, rightLength);
+ public boolean deleteSurroundingText(int beforeLength, int afterLength) {
+ return mTarget.deleteSurroundingText(beforeLength, afterLength);
}
public boolean setComposingText(CharSequence text, int newCursorPosition) {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index b41e6f5e7907..0985e1465b0b 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -651,19 +651,7 @@ public final class InputMethodManager {
}
}
- if (mServedInputConnection != null) {
- // We need to tell the previously served view that it is no
- // longer the input target, so it can reset its state. Schedule
- // this call on its window's Handler so it will be on the correct
- // thread and outside of our lock.
- Handler vh = mServedView.getHandler();
- if (vh != null) {
- // This will result in a call to reportFinishInputConnection()
- // below.
- vh.sendMessage(vh.obtainMessage(ViewRootImpl.FINISH_INPUT_CONNECTION,
- mServedInputConnection));
- }
- }
+ notifyInputConnectionFinished();
mServedView = null;
mCompletions = null;
@@ -671,7 +659,25 @@ public final class InputMethodManager {
clearConnectionLocked();
}
}
-
+
+ /**
+ * Notifies the served view that the current InputConnection will no longer be used.
+ */
+ private void notifyInputConnectionFinished() {
+ if (mServedView != null && mServedInputConnection != null) {
+ // We need to tell the previously served view that it is no
+ // longer the input target, so it can reset its state. Schedule
+ // this call on its window's Handler so it will be on the correct
+ // thread and outside of our lock.
+ Handler vh = mServedView.getHandler();
+ if (vh != null) {
+ // This will result in a call to reportFinishInputConnection() below.
+ vh.sendMessage(vh.obtainMessage(ViewRootImpl.FINISH_INPUT_CONNECTION,
+ mServedInputConnection));
+ }
+ }
+ }
+
/**
* Called from the FINISH_INPUT_CONNECTION message above.
* @hide
@@ -681,7 +687,7 @@ public final class InputMethodManager {
ic.finishComposingText();
}
}
-
+
public void displayCompletions(View view, CompletionInfo[] completions) {
checkFocus();
synchronized (mH) {
@@ -831,7 +837,7 @@ public final class InputMethodManager {
* shown with {@link #SHOW_FORCED}.
*/
public static final int HIDE_NOT_ALWAYS = 0x0002;
-
+
/**
* Synonym for {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)}
* without a result: request to hide the soft input window from the
@@ -993,7 +999,7 @@ public final class InputMethodManager {
tba.fieldId = view.getId();
InputConnection ic = view.onCreateInputConnection(tba);
if (DEBUG) Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic);
-
+
synchronized (mH) {
// Now that we are locked again, validate that our state hasn't
// changed.
@@ -1012,6 +1018,8 @@ public final class InputMethodManager {
// Hook 'em up and let 'er rip.
mCurrentTextBoxAttribute = tba;
mServedConnecting = false;
+ // Notify the served view that its previous input connection is finished
+ notifyInputConnectionFinished();
mServedInputConnection = ic;
IInputContext servedContext;
if (ic != null) {
@@ -1115,7 +1123,7 @@ public final class InputMethodManager {
}
}
- void scheduleCheckFocusLocked(View view) {
+ static void scheduleCheckFocusLocked(View view) {
Handler vh = view.getHandler();
if (vh != null && !vh.hasMessages(ViewRootImpl.CHECK_FOCUS)) {
// This will result in a call to checkFocus() below.
diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java
index 30bbb04b72d3..ee9b9492ebeb 100644
--- a/core/java/android/webkit/Network.java
+++ b/core/java/android/webkit/Network.java
@@ -169,7 +169,9 @@ class Network {
if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()))
return;
- NetworkInfo info = (NetworkInfo)intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
+ final ConnectivityManager connManager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ final NetworkInfo info = connManager.getActiveNetworkInfo();
if (info != null)
mRoaming = info.isRoaming();
};
diff --git a/core/java/android/webkit/WebCoreThreadWatchdog.java b/core/java/android/webkit/WebCoreThreadWatchdog.java
index d100260c0616..0541d5db4157 100644
--- a/core/java/android/webkit/WebCoreThreadWatchdog.java
+++ b/core/java/android/webkit/WebCoreThreadWatchdog.java
@@ -40,9 +40,6 @@ class WebCoreThreadWatchdog implements Runnable {
// WebCore thread unresponsive.
private static final int TIMED_OUT = 101;
- // Message to tell the Watchdog thread to terminate.
- private static final int QUIT = 102;
-
// Wait 10s after hearing back from the WebCore thread before checking it's still alive.
private static final int HEARTBEAT_PERIOD = 10 * 1000;
@@ -57,7 +54,6 @@ class WebCoreThreadWatchdog implements Runnable {
private Handler mWebCoreThreadHandler;
private Handler mHandler;
private boolean mPaused;
- private boolean mPendingQuit;
private static WebCoreThreadWatchdog sInstance;
@@ -88,12 +84,6 @@ class WebCoreThreadWatchdog implements Runnable {
}
}
- public synchronized static void quit() {
- if (sInstance != null) {
- sInstance.quitWatchdog();
- }
- }
-
private void setContext(Context context) {
mContext = context;
}
@@ -103,19 +93,6 @@ class WebCoreThreadWatchdog implements Runnable {
mWebCoreThreadHandler = webCoreThreadHandler;
}
- private void quitWatchdog() {
- if (mHandler == null) {
- // The thread hasn't started yet, so set a flag to stop it starting.
- mPendingQuit = true;
- return;
- }
- // Clear any pending messages, and then post a quit to the WatchDog handler.
- mHandler.removeMessages(TIMED_OUT);
- mHandler.removeMessages(IS_ALIVE);
- mWebCoreThreadHandler.removeMessages(EventHub.HEARTBEAT);
- mHandler.obtainMessage(QUIT).sendToTarget();
- }
-
private void pauseWatchdog() {
mPaused = true;
@@ -146,12 +123,8 @@ class WebCoreThreadWatchdog implements Runnable {
mHandler.sendMessageDelayed(mHandler.obtainMessage(TIMED_OUT), TIMEOUT_PERIOD);
}
- private boolean createHandler() {
+ private void createHandler() {
synchronized (WebCoreThreadWatchdog.class) {
- if (mPendingQuit) {
- return false;
- }
-
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -206,15 +179,9 @@ class WebCoreThreadWatchdog implements Runnable {
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
break;
-
- case QUIT:
- Looper.myLooper().quit();
- break;
}
}
};
-
- return true;
}
}
@@ -222,9 +189,7 @@ class WebCoreThreadWatchdog implements Runnable {
public void run() {
Looper.prepare();
- if (!createHandler()) {
- return;
- }
+ createHandler();
// Send the initial control to WebViewCore and start the timeout timer as long as we aren't
// paused.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 148be5c84813..2c2cf644f775 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -60,6 +60,10 @@ import android.os.StrictMode;
import android.os.SystemClock;
import android.provider.Settings;
import android.speech.tts.TextToSpeech;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.Selection;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.EventLog;
import android.util.Log;
@@ -125,12 +129,6 @@ import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-
-import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY;
-
/**
* <p>A View that displays web pages. This class is the basis upon which you
* can roll your own web browser or simply display some online content within your Activity.
@@ -363,39 +361,126 @@ public class WebView extends AbsoluteLayout
}
/**
- * InputConnection used for ContentEditable. This captures the 'delete'
- * commands and sends delete key presses.
+ * InputConnection used for ContentEditable. This captures changes
+ * to the text and sends them either as key strokes or text changes.
*/
private class WebViewInputConnection extends BaseInputConnection {
+ // Used for mapping characters to keys typed.
+ private KeyCharacterMap mKeyCharacterMap;
+
public WebViewInputConnection() {
- super(WebView.this, false);
+ super(WebView.this, true);
+ }
+
+ @Override
+ public boolean setComposingText(CharSequence text, int newCursorPosition) {
+ Editable editable = getEditable();
+ int start = getComposingSpanStart(editable);
+ int end = getComposingSpanEnd(editable);
+ if (start < 0 || end < 0) {
+ start = Selection.getSelectionStart(editable);
+ end = Selection.getSelectionEnd(editable);
+ }
+ if (end < start) {
+ int temp = end;
+ end = start;
+ start = temp;
+ }
+ setNewText(start, end, text);
+ return super.setComposingText(text, newCursorPosition);
+ }
+
+ @Override
+ public boolean commitText(CharSequence text, int newCursorPosition) {
+ setComposingText(text, newCursorPosition);
+ finishComposingText();
+ return true;
+ }
+
+ @Override
+ public boolean deleteSurroundingText(int leftLength, int rightLength) {
+ Editable editable = getEditable();
+ int cursorPosition = Selection.getSelectionEnd(editable);
+ int startDelete = Math.max(0, cursorPosition - leftLength);
+ int endDelete = Math.min(editable.length(),
+ cursorPosition + rightLength);
+ setNewText(startDelete, endDelete, "");
+ return super.deleteSurroundingText(leftLength, rightLength);
+ }
+
+ /**
+ * Sends a text change to webkit indirectly. If it is a single-
+ * character add or delete, it sends it as a key stroke. If it cannot
+ * be represented as a key stroke, it sends it as a field change.
+ * @param start The start offset (inclusive) of the text being changed.
+ * @param end The end offset (exclusive) of the text being changed.
+ * @param text The new text to replace the changed text.
+ */
+ private void setNewText(int start, int end, CharSequence text) {
+ Editable editable = getEditable();
+ CharSequence original = editable.subSequence(start, end);
+ boolean isCharacterAdd = false;
+ boolean isCharacterDelete = false;
+ int textLength = text.length();
+ int originalLength = original.length();
+ if (textLength > originalLength) {
+ isCharacterAdd = (textLength == originalLength + 1)
+ && TextUtils.regionMatches(text, 0, original, 0,
+ originalLength);
+ } else if (originalLength > textLength) {
+ isCharacterDelete = (textLength == originalLength - 1)
+ && TextUtils.regionMatches(text, 0, original, 0,
+ textLength);
+ }
+ if (isCharacterAdd) {
+ sendCharacter(text.charAt(textLength - 1));
+ mTextGeneration++;
+ } else if (isCharacterDelete) {
+ sendDeleteKey();
+ mTextGeneration++;
+ } else if (textLength != originalLength ||
+ !TextUtils.regionMatches(text, 0, original, 0,
+ textLength)) {
+ // Send a message so that key strokes and text replacement
+ // do not come out of order.
+ Message replaceMessage = mPrivateHandler.obtainMessage(
+ REPLACE_TEXT, start, end, text.toString());
+ mPrivateHandler.sendMessage(replaceMessage);
+ }
+ }
+
+ /**
+ * Send a single character to the WebView as a key down and up event.
+ * @param c The character to be sent.
+ */
+ private void sendCharacter(char c) {
+ if (mKeyCharacterMap == null) {
+ mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+ }
+ char[] chars = new char[1];
+ chars[0] = c;
+ KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
+ if (events != null) {
+ for (KeyEvent event : events) {
+ sendKeyEvent(event);
+ }
+ }
}
- private void sendKeyPress(int keyCode) {
+ /**
+ * Send the delete character as a key down and up event.
+ */
+ private void sendDeleteKey() {
long eventTime = SystemClock.uptimeMillis();
sendKeyEvent(new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, keyCode, 0, 0,
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD));
sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
- KeyEvent.ACTION_UP, keyCode, 0, 0,
+ KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD));
}
-
- @Override
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
- // Look for one-character delete and send it as a key press.
- if (leftLength == 1 && rightLength == 0) {
- sendKeyPress(KeyEvent.KEYCODE_DEL);
- } else if (leftLength == 0 && rightLength == 1){
- sendKeyPress(KeyEvent.KEYCODE_FORWARD_DEL);
- } else if (mWebViewCore != null) {
- mWebViewCore.sendMessage(EventHub.DELETE_SURROUNDING_TEXT,
- leftLength, rightLength);
- }
- return super.deleteSurroundingText(leftLength, rightLength);
- }
}
@@ -704,12 +789,18 @@ public class WebView extends AbsoluteLayout
// know to handle Shift and arrows natively first
private boolean mAccessibilityScriptInjected;
- static final boolean USE_JAVA_TEXT_SELECTION = true;
- static final boolean DEBUG_TEXT_HANDLES = false;
- private Region mTextSelectionRegion = new Region();
- private Paint mTextSelectionPaint;
private Drawable mSelectHandleLeft;
private Drawable mSelectHandleRight;
+ private Rect mSelectCursorBase = new Rect();
+ private int mSelectCursorBaseLayerId;
+ private Rect mSelectCursorExtent = new Rect();
+ private int mSelectCursorExtentLayerId;
+ private Rect mSelectDraggingCursor;
+ private Point mSelectDraggingOffset = new Point();
+ static final int HANDLE_ID_START = 0;
+ static final int HANDLE_ID_END = 1;
+ static final int HANDLE_ID_BASE = 2;
+ static final int HANDLE_ID_EXTENT = 3;
static boolean sDisableNavcache = false;
// the color used to highlight the touch rectangles
@@ -799,6 +890,8 @@ public class WebView extends AbsoluteLayout
static final int EXIT_FULLSCREEN_VIDEO = 140;
static final int COPY_TO_CLIPBOARD = 141;
+ static final int INIT_EDIT_FIELD = 142;
+ static final int REPLACE_TEXT = 143;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
@@ -976,9 +1069,6 @@ public class WebView extends AbsoluteLayout
private Rect mScrollingLayerBounds = new Rect();
private boolean mSentAutoScrollMessage = false;
- // Temporary hack to work around the context removal upon memory pressure
- private static boolean mIncrementEGLContextHack = false;
-
// used for serializing asynchronously handled touch events.
private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
@@ -2572,12 +2662,6 @@ public class WebView extends AbsoluteLayout
return mZoomManager.getScale();
}
- // Called by JNI. Returns the scale to apply to the text selection handles
- /* package */ float getTextHandleScale() {
- float density = mContext.getResources().getDisplayMetrics().density;
- return density / getScale();
- }
-
/**
* Compute the reading level scale of the WebView
* @param scale The current scale.
@@ -3768,6 +3852,16 @@ public class WebView extends AbsoluteLayout
if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) {
return;
}
+ if (mSelectingText) {
+ int dx = mScrollingLayerRect.left - x;
+ int dy = mScrollingLayerRect.top - y;
+ if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) {
+ mSelectCursorBase.offset(dx, dy);
+ }
+ if (mSelectCursorExtentLayerId == mCurrentScrollingLayerId) {
+ mSelectCursorExtent.offset(dx, dy);
+ }
+ }
nativeScrollLayer(mCurrentScrollingLayerId, x, y);
mScrollingLayerRect.left = x;
mScrollingLayerRect.top = y;
@@ -4385,13 +4479,6 @@ public class WebView extends AbsoluteLayout
}
if (canvas.isHardwareAccelerated()) {
- if (mIncrementEGLContextHack == false) {
- mIncrementEGLContextHack = true;
- EGL10 egl = (EGL10) EGLContext.getEGL();
- EGLDisplay eglDisplay = egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
- int[] version = new int[2];
- egl.eglInitialize(eglDisplay, version);
- }
mZoomManager.setHardwareAccelerated();
}
@@ -4547,12 +4634,7 @@ public class WebView extends AbsoluteLayout
* Select the word at the indicated content coordinates.
*/
boolean selectText(int x, int y) {
- if (!setUpSelect(true, x, y)) {
- return false;
- }
- nativeSetExtendSelection();
- mDrawSelectionPointer = false;
- mTouchMode = TOUCH_DRAG_MODE;
+ mWebViewCore.sendMessage(EventHub.SELECT_WORD_AT, x, y);
return true;
}
@@ -4753,11 +4835,8 @@ public class WebView extends AbsoluteLayout
int extras = DRAW_EXTRAS_NONE;
if (mFindIsUp) {
extras = DRAW_EXTRAS_FIND;
- } else if (mSelectingText && (!USE_JAVA_TEXT_SELECTION || DEBUG_TEXT_HANDLES)) {
+ } else if (mSelectingText) {
extras = DRAW_EXTRAS_SELECTION;
- nativeSetSelectionPointer(mNativeClass,
- mDrawSelectionPointer,
- mZoomManager.getInvScale(), mSelectX, mSelectY - getTitleHeight());
} else if (drawCursorRing) {
extras = DRAW_EXTRAS_CURSOR_RING;
}
@@ -4802,7 +4881,7 @@ public class WebView extends AbsoluteLayout
}
canvas.restoreToCount(saveCount);
- if (mSelectingText && USE_JAVA_TEXT_SELECTION) {
+ if (mSelectingText) {
drawTextSelectionHandles(canvas);
}
@@ -4824,30 +4903,12 @@ public class WebView extends AbsoluteLayout
}
private void drawTextSelectionHandles(Canvas canvas) {
- if (mTextSelectionPaint == null) {
- mTextSelectionPaint = new Paint();
- mTextSelectionPaint.setColor(HIGHLIGHT_COLOR);
- }
- mTextSelectionRegion.setEmpty();
- nativeGetTextSelectionRegion(mNativeClass, mTextSelectionRegion);
- Rect r = new Rect();
- RegionIterator iter = new RegionIterator(mTextSelectionRegion);
- Rect clip = canvas.getClipBounds();
- while (iter.next(r)) {
- r.set(contentToViewDimension(r.left),
- contentToViewDimension(r.top),
- contentToViewDimension(r.right),
- contentToViewDimension(r.bottom));
- if (r.intersect(clip)) {
- canvas.drawRect(r, mTextSelectionPaint);
- }
- }
if (mSelectHandleLeft == null) {
mSelectHandleLeft = mContext.getResources().getDrawable(
com.android.internal.R.drawable.text_select_handle_left);
}
int[] handles = new int[4];
- nativeGetSelectionHandles(mNativeClass, handles);
+ getSelectionHandles(handles);
int start_x = contentToViewDimension(handles[0]);
int start_y = contentToViewDimension(handles[1]);
int end_x = contentToViewDimension(handles[2]);
@@ -4865,14 +4926,31 @@ public class WebView extends AbsoluteLayout
mSelectHandleRight.setBounds(end_x, end_y,
end_x + mSelectHandleRight.getIntrinsicWidth(),
end_y + mSelectHandleRight.getIntrinsicHeight());
- if (DEBUG_TEXT_HANDLES) {
- mSelectHandleLeft.setAlpha(125);
- mSelectHandleRight.setAlpha(125);
- }
mSelectHandleLeft.draw(canvas);
mSelectHandleRight.draw(canvas);
}
+ /**
+ * Takes an int[4] array as an output param with the values being
+ * startX, startY, endX, endY
+ */
+ private void getSelectionHandles(int[] handles) {
+ handles[0] = mSelectCursorBase.right;
+ handles[1] = mSelectCursorBase.bottom -
+ (mSelectCursorBase.height() / 4);
+ handles[2] = mSelectCursorExtent.left;
+ handles[3] = mSelectCursorExtent.bottom
+ - (mSelectCursorExtent.height() / 4);
+ if (!nativeIsBaseFirst(mNativeClass)) {
+ int swap = handles[0];
+ handles[0] = handles[2];
+ handles[2] = swap;
+ swap = handles[1];
+ handles[1] = handles[3];
+ handles[3] = swap;
+ }
+ }
+
// draw history
private boolean mDrawHistory = false;
private Picture mHistoryPicture = null;
@@ -4932,7 +5010,7 @@ public class WebView extends AbsoluteLayout
/* package */ void deleteSelection(int start, int end) {
mTextGeneration++;
WebViewCore.TextSelectionData data
- = new WebViewCore.TextSelectionData(start, end);
+ = new WebViewCore.TextSelectionData(start, end, 0);
mWebViewCore.sendMessage(EventHub.DELETE_SELECTION, mTextGeneration, 0,
data);
}
@@ -4951,12 +5029,18 @@ public class WebView extends AbsoluteLayout
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN
+ outAttrs.inputType = EditorInfo.IME_FLAG_NO_FULLSCREEN
| EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_NORMAL;
+ | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT
+ | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
+ | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT
+ | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES;
+ outAttrs.imeOptions = EditorInfo.IME_ACTION_NONE;
+
if (mInputConnection == null) {
mInputConnection = new WebViewInputConnection();
}
+ outAttrs.initialCapsMode = mInputConnection.getCursorCapsMode(InputType.TYPE_CLASS_TEXT);
return mInputConnection;
}
@@ -5379,15 +5463,6 @@ public class WebView extends AbsoluteLayout
return pinScrollTo(mContentWidth, mScrollY, true, 0);
}
}
- if (mSelectingText) {
- int xRate = keyCode == KeyEvent.KEYCODE_DPAD_LEFT
- ? -1 : keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ? 1 : 0;
- int yRate = keyCode == KeyEvent.KEYCODE_DPAD_UP ?
- -1 : keyCode == KeyEvent.KEYCODE_DPAD_DOWN ? 1 : 0;
- int multiplier = event.getRepeatCount() + 1;
- moveSelection(xRate * multiplier, yRate * multiplier);
- return true;
- }
if (navHandledKey(keyCode, 1, false, event.getEventTime())) {
playSoundEffect(keyCodeToSoundsEffect(keyCode));
return true;
@@ -5540,14 +5615,8 @@ public class WebView extends AbsoluteLayout
mGotCenterDown = false;
if (mSelectingText) {
- if (mExtendSelection) {
- copySelection();
- selectionDone();
- } else {
- mExtendSelection = true;
- nativeSetExtendSelection();
- invalidate(); // draw the i-beam instead of the arrow
- }
+ copySelection();
+ selectionDone();
return true; // discard press if copy in progress
}
@@ -5593,21 +5662,7 @@ public class WebView extends AbsoluteLayout
return false;
}
- /*
- * Enter selecting text mode, and see if CAB should be shown.
- * Returns true if the WebView is now in
- * selecting text mode (including if it was already in that mode, and this
- * method did nothing).
- */
- private boolean setUpSelect(boolean selectWord, int x, int y) {
- if (0 == mNativeClass) return false; // client isn't initialized
- if (inFullScreenMode()) return false;
- if (mSelectingText) return true;
- nativeResetSelection();
- if (selectWord && !nativeWordSelection(x, y)) {
- selectionDone();
- return false;
- }
+ private boolean startSelectActionMode() {
mSelectCallback = new SelectActionModeCallback();
mSelectCallback.setWebView(this);
if (startActionMode(mSelectCallback) == null) {
@@ -5616,52 +5671,41 @@ public class WebView extends AbsoluteLayout
selectionDone();
return false;
}
- mExtendSelection = false;
- mSelectingText = mDrawSelectionPointer = true;
- if (DEBUG_TEXT_HANDLES) {
- // Debugging text handles requires running in software mode
- setLayerType(LAYER_TYPE_SOFTWARE, null);
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ return true;
+ }
+
+ private void syncSelectionCursors() {
+ mSelectCursorBaseLayerId =
+ nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE, mSelectCursorBase);
+ mSelectCursorExtentLayerId =
+ nativeGetHandleLayerId(mNativeClass, HANDLE_ID_EXTENT, mSelectCursorExtent);
+ }
+
+ private boolean setupWebkitSelect() {
+ syncSelectionCursors();
+ if (!startSelectActionMode()) {
+ selectionDone();
+ return false;
}
- // don't let the picture change during text selection
- WebViewCore.pauseUpdatePicture(mWebViewCore);
- if (nativeHasCursorNode()) {
- Rect rect = nativeCursorNodeBounds();
- mSelectX = contentToViewX(rect.left);
- mSelectY = contentToViewY(rect.top);
- } else if (mLastTouchY > getVisibleTitleHeightImpl()) {
- mSelectX = mScrollX + mLastTouchX;
- mSelectY = mScrollY + mLastTouchY;
+ mSelectingText = true;
+ mTouchMode = TOUCH_DRAG_MODE;
+ return true;
+ }
+
+ private void updateWebkitSelection() {
+ int[] handles = null;
+ if (mSelectingText) {
+ handles = new int[4];
+ handles[0] = mSelectCursorBase.centerX();
+ handles[1] = mSelectCursorBase.centerY();
+ handles[2] = mSelectCursorExtent.centerX();
+ handles[3] = mSelectCursorExtent.centerY();
} else {
- mSelectX = mScrollX + getViewWidth() / 2;
- mSelectY = mScrollY + getViewHeightWithTitle() / 2;
+ nativeSetTextSelection(mNativeClass, 0);
}
- nativeHideCursor();
- mMinAutoScrollX = 0;
- mMaxAutoScrollX = getViewWidth();
- mMinAutoScrollY = 0;
- mMaxAutoScrollY = getViewHeightWithTitle();
- mCurrentScrollingLayerId = nativeScrollableLayer(viewToContentX(mSelectX),
- viewToContentY(mSelectY), mScrollingLayerRect,
- mScrollingLayerBounds);
- if (mCurrentScrollingLayerId != 0) {
- if (mScrollingLayerRect.left != mScrollingLayerRect.right) {
- mMinAutoScrollX = Math.max(mMinAutoScrollX,
- contentToViewX(mScrollingLayerBounds.left));
- mMaxAutoScrollX = Math.min(mMaxAutoScrollX,
- contentToViewX(mScrollingLayerBounds.right));
- }
- if (mScrollingLayerRect.top != mScrollingLayerRect.bottom) {
- mMinAutoScrollY = Math.max(mMinAutoScrollY,
- contentToViewY(mScrollingLayerBounds.top));
- mMaxAutoScrollY = Math.min(mMaxAutoScrollY,
- contentToViewY(mScrollingLayerBounds.bottom));
- }
- }
- mMinAutoScrollX += SELECT_SCROLL;
- mMaxAutoScrollX -= SELECT_SCROLL;
- mMinAutoScrollY += SELECT_SCROLL;
- mMaxAutoScrollY -= SELECT_SCROLL;
- return true;
+ mWebViewCore.removeMessages(EventHub.SELECT_TEXT);
+ mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT, handles);
}
/**
@@ -5672,7 +5716,6 @@ public class WebView extends AbsoluteLayout
@Deprecated
public void emulateShiftHeld() {
checkThread();
- setUpSelect(false, 0, 0);
}
/**
@@ -5681,17 +5724,7 @@ public class WebView extends AbsoluteLayout
* @hide This is an implementation detail.
*/
public void selectAll() {
- if (0 == mNativeClass) return; // client isn't initialized
- if (inFullScreenMode()) return;
- if (!mSelectingText) {
- // retrieve a point somewhere within the text
- Point select = nativeSelectableText();
- if (!selectText(select.x, select.y)) return;
- }
- nativeSelectAll();
- mDrawSelectionPointer = false;
- mExtendSelection = true;
- invalidate();
+ mWebViewCore.sendMessage(EventHub.SELECT_ALL);
}
/**
@@ -5700,17 +5733,11 @@ public class WebView extends AbsoluteLayout
void selectionDone() {
if (mSelectingText) {
mSelectingText = false;
- if (DEBUG_TEXT_HANDLES) {
- // Debugging text handles required running in software mode, set
- // back to default now
- setLayerType(LAYER_TYPE_NONE, null);
- }
// finish is idempotent, so this is fine even if selectionDone was
// called by mSelectCallback.onDestroyActionMode
mSelectCallback.finish();
mSelectCallback = null;
- WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
+ updateWebkitSelection();
invalidate(); // redraw without selection
mAutoScrollX = 0;
mAutoScrollY = 0;
@@ -5738,7 +5765,7 @@ public class WebView extends AbsoluteLayout
.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(selection);
int[] handles = new int[4];
- nativeGetSelectionHandles(mNativeClass, handles);
+ getSelectionHandles(handles);
mWebViewCore.sendMessage(EventHub.COPY_TEXT, handles);
}
invalidate(); // remove selection region and pointer
@@ -5753,7 +5780,7 @@ public class WebView extends AbsoluteLayout
public void cutSelection() {
copySelection();
int[] handles = new int[4];
- nativeGetSelectionHandles(mNativeClass, handles);
+ getSelectionHandles(handles);
mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
}
@@ -5771,7 +5798,7 @@ public class WebView extends AbsoluteLayout
CharSequence pasteText = clipItem.getText();
if (pasteText != null) {
int[] handles = new int[4];
- nativeGetSelectionHandles(mNativeClass, handles);
+ getSelectionHandles(handles);
mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
mWebViewCore.sendMessage(EventHub.INSERT_TEXT,
pasteText.toString());
@@ -6324,12 +6351,26 @@ public class WebView extends AbsoluteLayout
(eventTime - mLastTouchUpTime), eventTime);
}
if (mSelectingText) {
- mDrawSelectionPointer = false;
- mSelectionStarted = nativeStartSelection(contentX, contentY);
+ mSelectionStarted = false;
+ int shiftedY = y - getTitleHeight() + mScrollY;
+ int shiftedX = x + mScrollX;
+ if (mSelectHandleLeft.getBounds()
+ .contains(shiftedX, shiftedY)) {
+ mSelectionStarted = true;
+ mSelectDraggingCursor = mSelectCursorBase;
+ } else if (mSelectHandleRight.getBounds()
+ .contains(shiftedX, shiftedY)) {
+ mSelectionStarted = true;
+ mSelectDraggingCursor = mSelectCursorExtent;
+ }
+ if (mSelectDraggingCursor != null) {
+ mSelectDraggingOffset.set(
+ mSelectDraggingCursor.left - contentX,
+ mSelectDraggingCursor.top - contentY);
+ }
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "select=" + contentX + "," + contentY);
}
- invalidate();
}
}
// Trigger the link
@@ -6395,6 +6436,26 @@ public class WebView extends AbsoluteLayout
removeTouchHighlight();
}
}
+ if (mSelectingText && mSelectionStarted) {
+ if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "extend=" + contentX + "," + contentY);
+ }
+ ViewParent parent = getParent();
+ if (parent != null) {
+ parent.requestDisallowInterceptTouchEvent(true);
+ }
+ if (deltaX != 0 || deltaY != 0) {
+ mSelectDraggingCursor.offsetTo(
+ contentX + mSelectDraggingOffset.x,
+ contentY + mSelectDraggingOffset.y);
+ updateWebkitSelection();
+ mLastTouchX = x;
+ mLastTouchY = y;
+ invalidate();
+ }
+ break;
+ }
+
// pass the touch events from UI thread to WebCore thread
if (shouldForwardTouchEvent() && mConfirmMove && (firstMove
|| eventTime - mLastSentTouchTime > mCurrentTouchInterval)) {
@@ -6437,30 +6498,6 @@ public class WebView extends AbsoluteLayout
} else {
mVelocityTracker.addMovement(ev);
}
- if (mSelectingText && mSelectionStarted) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "extend=" + contentX + "," + contentY);
- }
- ViewParent parent = getParent();
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- mAutoScrollX = x <= mMinAutoScrollX ? -SELECT_SCROLL
- : x >= mMaxAutoScrollX ? SELECT_SCROLL : 0;
- mAutoScrollY = y <= mMinAutoScrollY ? -SELECT_SCROLL
- : y >= mMaxAutoScrollY ? SELECT_SCROLL : 0;
- if ((mAutoScrollX != 0 || mAutoScrollY != 0)
- && !mSentAutoScrollMessage) {
- mSentAutoScrollMessage = true;
- mPrivateHandler.sendEmptyMessageDelayed(
- SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL);
- }
- if (deltaX != 0 || deltaY != 0) {
- nativeExtendSelection(contentX, contentY);
- invalidate();
- }
- break;
- }
if (mTouchMode != TOUCH_DRAG_MODE &&
mTouchMode != TOUCH_DRAG_LAYER_MODE) {
@@ -6675,7 +6712,7 @@ public class WebView extends AbsoluteLayout
} else {
if (mSelectingText) {
// tapping on selection or controls does nothing
- if (!nativeHitSelection(contentX, contentY)) {
+ if (!mSelectionStarted) {
selectionDone();
}
break;
@@ -6972,6 +7009,12 @@ public class WebView extends AbsoluteLayout
if (mOverScrollGlow != null) {
mOverScrollGlow.releaseAll();
}
+
+ if (mSelectingText) {
+ mSelectionStarted = false;
+ syncSelectionCursors();
+ invalidate();
+ }
}
private void cancelTouch() {
@@ -7036,8 +7079,6 @@ public class WebView extends AbsoluteLayout
private int mTrackballYMove = 0;
private boolean mSelectingText = false;
private boolean mSelectionStarted = false;
- private boolean mExtendSelection = false;
- private boolean mDrawSelectionPointer = false;
private static final int TRACKBALL_KEY_TIMEOUT = 1000;
private static final int TRACKBALL_TIMEOUT = 200;
private static final int TRACKBALL_WAIT = 100;
@@ -7106,14 +7147,8 @@ public class WebView extends AbsoluteLayout
mTrackballDown = false;
mTrackballUpTime = time;
if (mSelectingText) {
- if (mExtendSelection) {
- copySelection();
- selectionDone();
- } else {
- mExtendSelection = true;
- nativeSetExtendSelection();
- invalidate(); // draw the i-beam instead of the arrow
- }
+ copySelection();
+ selectionDone();
return true; // discard press if copy in progress
}
if (DebugFlags.WEB_VIEW) {
@@ -7156,42 +7191,6 @@ public class WebView extends AbsoluteLayout
return true;
}
- void moveSelection(float xRate, float yRate) {
- if (mNativeClass == 0)
- return;
- int width = getViewWidth();
- int height = getViewHeight();
- mSelectX += xRate;
- mSelectY += yRate;
- int maxX = width + mScrollX;
- int maxY = height + mScrollY;
- mSelectX = Math.min(maxX, Math.max(mScrollX - SELECT_CURSOR_OFFSET
- , mSelectX));
- mSelectY = Math.min(maxY, Math.max(mScrollY - SELECT_CURSOR_OFFSET
- , mSelectY));
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "moveSelection"
- + " mSelectX=" + mSelectX
- + " mSelectY=" + mSelectY
- + " mScrollX=" + mScrollX
- + " mScrollY=" + mScrollY
- + " xRate=" + xRate
- + " yRate=" + yRate
- );
- }
- nativeMoveSelection(viewToContentX(mSelectX), viewToContentY(mSelectY));
- int scrollX = mSelectX < mScrollX ? -SELECT_CURSOR_OFFSET
- : mSelectX > maxX - SELECT_CURSOR_OFFSET ? SELECT_CURSOR_OFFSET
- : 0;
- int scrollY = mSelectY < mScrollY ? -SELECT_CURSOR_OFFSET
- : mSelectY > maxY - SELECT_CURSOR_OFFSET ? SELECT_CURSOR_OFFSET
- : 0;
- pinScrollBy(scrollX, scrollY, true, 0);
- Rect select = new Rect(mSelectX, mSelectY, mSelectX + 1, mSelectY + 1);
- requestRectangleOnScreen(select);
- invalidate();
- }
-
private int scaleTrackballX(float xRate, int width) {
int xMove = (int) (xRate / TRACKBALL_SCALE * width);
int nextXMove = xMove;
@@ -7245,21 +7244,6 @@ public class WebView extends AbsoluteLayout
float yRate = mTrackballRemainsY * 1000 / elapsed;
int viewWidth = getViewWidth();
int viewHeight = getViewHeight();
- if (mSelectingText) {
- if (!mDrawSelectionPointer) {
- // The last selection was made by touch, disabling drawing the
- // selection pointer. Allow the trackball to adjust the
- // position of the touch control.
- mSelectX = contentToViewX(nativeSelectionX());
- mSelectY = contentToViewY(nativeSelectionY());
- mDrawSelectionPointer = mExtendSelection = true;
- nativeSetExtendSelection();
- }
- moveSelection(scaleTrackballX(xRate, viewWidth),
- scaleTrackballY(yRate, viewHeight));
- mTrackballRemainsX = mTrackballRemainsY = 0;
- return;
- }
float ax = Math.abs(xRate);
float ay = Math.abs(yRate);
float maxA = Math.max(ax, ay);
@@ -8963,6 +8947,31 @@ public class WebView extends AbsoluteLayout
copyToClipboard((String) msg.obj);
break;
+ case INIT_EDIT_FIELD:
+ if (mInputConnection != null) {
+ mTextGeneration = 0;
+ String text = (String)msg.obj;
+ mInputConnection.beginBatchEdit();
+ Editable editable = mInputConnection.getEditable();
+ editable.replace(0, editable.length(), text);
+ int start = msg.arg1;
+ int end = msg.arg2;
+ mInputConnection.setComposingRegion(end, end);
+ mInputConnection.setSelection(start, end);
+ mInputConnection.endBatchEdit();
+ }
+ break;
+
+ case REPLACE_TEXT:{
+ String text = (String)msg.obj;
+ int start = msg.arg1;
+ int end = msg.arg2;
+ int cursorPosition = start + text.length();
+ replaceTextfieldText(start, end, text,
+ cursorPosition, cursorPosition);
+ break;
+ }
+
default:
super.handleMessage(msg);
break;
@@ -9088,11 +9097,26 @@ public class WebView extends AbsoluteLayout
*/
private void updateTextSelectionFromMessage(int nodePointer,
int textGeneration, WebViewCore.TextSelectionData data) {
- if (inEditingMode()
- && mWebTextView.isSameTextField(nodePointer)
- && textGeneration == mTextGeneration) {
- mWebTextView.setSelectionFromWebKit(data.mStart, data.mEnd);
+ if (textGeneration == mTextGeneration) {
+ if (inEditingMode()
+ && mWebTextView.isSameTextField(nodePointer)) {
+ mWebTextView.setSelectionFromWebKit(data.mStart, data.mEnd);
+ } else if (mInputConnection != null){
+ mInputConnection.setSelection(data.mStart, data.mEnd);
+ }
}
+
+ nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);
+ if (data.mSelectTextPtr != 0) {
+ if (!mSelectingText) {
+ setupWebkitSelect();
+ } else if (!mSelectionStarted) {
+ syncSelectionCursors();
+ }
+ } else {
+ selectionDone();
+ }
+ invalidate();
}
// Class used to use a dropdown for a <select> element
@@ -9841,7 +9865,6 @@ public class WebView extends AbsoluteLayout
private native boolean nativeMoveCursor(int keyCode, int count,
boolean noScroll);
private native int nativeMoveGeneration();
- private native void nativeMoveSelection(int x, int y);
/**
* @return true if the page should get the shift and arrow keys, rather
* than select text/navigation.
@@ -9851,15 +9874,8 @@ public class WebView extends AbsoluteLayout
*/
private native boolean nativePageShouldHandleShiftAndArrows();
private native boolean nativePointInNavCache(int x, int y, int slop);
- // Like many other of our native methods, you must make sure that
- // mNativeClass is not null before calling this method.
- private native void nativeResetSelection();
- private native Point nativeSelectableText();
- private native void nativeSelectAll();
private native void nativeSelectBestAt(Rect rect);
private native void nativeSelectAt(int x, int y);
- private native int nativeSelectionX();
- private native int nativeSelectionY();
private native int nativeFindIndex();
private native void nativeSetExtendSelection();
private native void nativeSetFindIsEmpty();
@@ -9915,12 +9931,14 @@ public class WebView extends AbsoluteLayout
private native int nativeGetBackgroundColor();
native boolean nativeSetProperty(String key, String value);
native String nativeGetProperty(String key);
- private native void nativeGetTextSelectionRegion(int instance, Region region);
- private native void nativeGetSelectionHandles(int instance, int[] handles);
/**
* See {@link ComponentCallbacks2} for the trim levels and descriptions
*/
private static native void nativeOnTrimMemory(int level);
private static native void nativeSetPauseDrawing(int instance, boolean pause);
private static native boolean nativeDisableNavcache();
+ private static native void nativeSetTextSelection(int instance, int selection);
+ private static native int nativeGetHandleLayerId(int instance, int handle,
+ Rect cursorLocation);
+ private static native boolean nativeIsBaseFirst(int instance);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index fe5c04c0abfd..395a638ab942 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -647,18 +647,6 @@ public final class WebViewCore {
int end, int textGeneration);
/**
- * Delete text near the cursor.
- * @param nativeClass The pointer to the native class (mNativeClass)
- * @param leftLength The number of characters to the left of the cursor to
- * delete
- * @param rightLength The number of characters to the right of the cursor
- * to delete.
- */
- private native void nativeDeleteSurroundingText(int nativeClass,
- int leftLength,
- int rightLength);
-
- /**
* Set the selection to (start, end) in the focused textfield. If start and
* end are out of order, swap them.
* @param nativeClass Pointer to the C++ WebViewCore object mNativeClass
@@ -847,12 +835,14 @@ public final class WebViewCore {
}
static class TextSelectionData {
- public TextSelectionData(int start, int end) {
+ public TextSelectionData(int start, int end, int selectTextPtr) {
mStart = start;
mEnd = end;
+ mSelectTextPtr = selectTextPtr;
}
int mStart;
int mEnd;
+ int mSelectTextPtr;
}
static class TouchUpData {
@@ -1130,6 +1120,9 @@ public final class WebViewCore {
static final int COPY_TEXT = 210;
static final int DELETE_TEXT = 211;
static final int INSERT_TEXT = 212;
+ static final int SELECT_TEXT = 213;
+ static final int SELECT_WORD_AT = 214;
+ static final int SELECT_ALL = 215;
// Private handler for WebCore messages.
private Handler mHandler;
@@ -1206,7 +1199,6 @@ public final class WebViewCore {
mSettings.onDestroyed();
mNativeClass = 0;
mWebView = null;
- WebCoreThreadWatchdog.quit();
}
break;
@@ -1576,11 +1568,6 @@ public final class WebViewCore {
deleteSelectionData.mStart, deleteSelectionData.mEnd, msg.arg1);
break;
- case DELETE_SURROUNDING_TEXT:
- nativeDeleteSurroundingText(mNativeClass,
- msg.arg1, msg.arg2);
- break;
-
case SET_SELECTION:
nativeSetSelection(mNativeClass, msg.arg1, msg.arg2);
break;
@@ -1764,6 +1751,25 @@ public final class WebViewCore {
case INSERT_TEXT:
nativeInsertText(mNativeClass, (String) msg.obj);
break;
+ case SELECT_TEXT: {
+ int[] args = (int[]) msg.obj;
+ if (args == null) {
+ nativeClearTextSelection(mNativeClass);
+ } else {
+ nativeSelectText(mNativeClass, args[0],
+ args[1], args[2], args[3]);
+ }
+ break;
+ }
+ case SELECT_WORD_AT: {
+ int x = msg.arg1;
+ int y = msg.arg2;
+ nativeSelectWordAt(mNativeClass, x, y);
+ break;
+ }
+ case SELECT_ALL:
+ nativeSelectAll(mNativeClass);
+ break;
}
}
};
@@ -2717,11 +2723,11 @@ public final class WebViewCore {
// called by JNI
private void updateTextSelection(int pointer, int start, int end,
- int textGeneration) {
+ int textGeneration, int selectionPtr) {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
WebView.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration,
- new TextSelectionData(start, end)).sendToTarget();
+ new TextSelectionData(start, end, selectionPtr)).sendToTarget();
}
}
@@ -2739,6 +2745,15 @@ public final class WebViewCore {
WebView.FIND_AGAIN).sendToTarget();
}
+ // called by JNI
+ private void initEditField(String text, int start, int end) {
+ if (mWebView == null) {
+ return;
+ }
+ Message.obtain(mWebView.mPrivateHandler,
+ WebView.INIT_EDIT_FIELD, start, end, text).sendToTarget();
+ }
+
private native void nativeUpdateFrameCacheIfLoading(int nativeClass);
private native void nativeRevealSelection(int nativeClass);
private native String nativeRequestLabel(int nativeClass, int framePtr,
@@ -2779,7 +2794,7 @@ public final class WebViewCore {
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
WebView.REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID, pointer,
- textGeneration, new TextSelectionData(selStart, selEnd))
+ textGeneration, new TextSelectionData(selStart, selEnd, 0))
.sendToTarget();
}
}
@@ -3034,4 +3049,9 @@ public final class WebViewCore {
*/
private native String nativeGetText(int nativeClass,
int startX, int startY, int endX, int endY);
+ private native void nativeSelectText(int nativeClass,
+ int startX, int startY, int endX, int endY);
+ private native void nativeClearTextSelection(int nativeClass);
+ private native void nativeSelectWordAt(int nativeClass, int x, int y);
+ private native void nativeSelectAll(int nativeClass);
}
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 60b24bc1207e..be6b4e2f5c76 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -33,8 +33,6 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
import android.widget.ActivityChooserModel.ActivityChooserModelClient;
/**
@@ -366,7 +364,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
getListPopupWindow().dismiss();
ViewTreeObserver viewTreeObserver = getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
- viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
+ viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
}
}
return true;
@@ -400,7 +398,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
}
ViewTreeObserver viewTreeObserver = getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
- viewTreeObserver.removeGlobalOnLayoutListener(mOnGlobalLayoutListener);
+ viewTreeObserver.removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
}
mIsAttachedToWindow = false;
}
@@ -547,6 +545,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
position = mAdapter.getShowDefaultActivity() ? position : position + 1;
Intent launchIntent = mAdapter.getDataModel().chooseActivity(position);
if (launchIntent != null) {
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
mContext.startActivity(launchIntent);
}
}
@@ -564,6 +563,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
final int index = mAdapter.getDataModel().getActivityIndex(defaultActivity);
Intent launchIntent = mAdapter.getDataModel().chooseActivity(index);
if (launchIntent != null) {
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
mContext.startActivity(launchIntent);
}
} else if (view == mExpandActivityOverflowButton) {
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index e226d378a01c..bb000498f9a6 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -558,7 +558,9 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
mCurrentWindowEnd = newWindowEnd;
mCurrentWindowStartUnbounded = newWindowStartUnbounded;
if (mRemoteViewsAdapter != null) {
- mRemoteViewsAdapter.setVisibleRangeHint(mCurrentWindowStart, mCurrentWindowEnd);
+ int adapterStart = modulo(mCurrentWindowStart, adapterCount);
+ int adapterEnd = modulo(mCurrentWindowEnd, adapterCount);
+ mRemoteViewsAdapter.setVisibleRangeHint(adapterStart, adapterEnd);
}
}
requestLayout();
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 7d58011c2b51..984ec79bee3e 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -842,9 +842,11 @@ public class GridLayout extends ViewGroup {
* @hide
*/
@Override
- protected void onChildVisibilityChanged(View child, int visibility) {
- super.onChildVisibilityChanged(child, visibility);
- invalidateStructure();
+ protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
+ super.onChildVisibilityChanged(child, oldVisibility, newVisibility);
+ if (oldVisibility == GONE || newVisibility == GONE) {
+ invalidateStructure();
+ }
}
// Measurement
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index a210f0bd8689..84e86af0840d 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -55,14 +55,14 @@ import com.android.internal.R;
/**
* A widget that enables the user to select a number form a predefined range.
- * The widget presents an input filed and up and down buttons for selecting the
- * current value. Pressing/long pressing the up and down buttons increments and
- * decrements the current value respectively. Touching the input filed shows a
- * scroll wheel, tapping on which while shown and not moving allows direct edit
- * of the current value. Sliding motions up or down hide the buttons and the
- * input filed, show the scroll wheel, and rotate the latter. Flinging is
+ * The widget presents an input field and up and down buttons for selecting the
+ * current value. Pressing/long-pressing the up and down buttons increments and
+ * decrements the current value respectively. Touching the input field shows a
+ * scroll wheel, which when touched allows direct edit
+ * of the current value. Sliding gestures up or down hide the buttons and the
+ * input filed, show and rotate the scroll wheel. Flinging is
* also supported. The widget enables mapping from positions to strings such
- * that instead the position index the corresponding string is displayed.
+ * that, instead of the position index, the corresponding string is displayed.
* <p>
* For an example of using this widget, see {@link android.widget.TimePicker}.
* </p>
@@ -71,6 +71,11 @@ import com.android.internal.R;
public class NumberPicker extends LinearLayout {
/**
+ * The number of items show in the selector wheel.
+ */
+ public static final int SELECTOR_WHEEL_ITEM_COUNT = 5;
+
+ /**
* The default update interval during long press.
*/
private static final long DEFAULT_LONG_PRESS_UPDATE_INTERVAL = 300;
@@ -1137,14 +1142,17 @@ public class NumberPicker extends LinearLayout {
* items shown on the selector wheel) the selector wheel wrapping is
* enabled.
* </p>
- *
+ * <p>
+ * <strong>Note:</strong> If the number of items, i.e. the range
+ * ({@link #getMaxValue()} - {@link #getMinValue()}) is less than
+ * {@link #SELECTOR_WHEEL_ITEM_COUNT}, the selector wheel will not
+ * wrap. Hence, in such a case calling this method is a NOP.
+ * </p>
* @param wrapSelectorWheel Whether to wrap.
*/
public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
- if (wrapSelectorWheel && (mMaxValue - mMinValue) < mSelectorIndices.length) {
- throw new IllegalStateException("Range less than selector items count.");
- }
- if (wrapSelectorWheel != mWrapSelectorWheel) {
+ final boolean wrappingAllowed = (mMaxValue - mMinValue) >= mSelectorIndices.length;
+ if ((!wrapSelectorWheel || wrappingAllowed) && wrapSelectorWheel != mWrapSelectorWheel) {
mWrapSelectorWheel = wrapSelectorWheel;
updateIncrementAndDecrementButtonsVisibilityState();
}
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index bb27b73fc296..22e9ef1357e8 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -279,6 +279,7 @@ public class ShareActionProvider extends ActionProvider {
final int itemId = item.getItemId();
Intent launchIntent = dataModel.chooseActivity(itemId);
if (launchIntent != null) {
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
mContext.startActivity(launchIntent);
}
return true;
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index a10615956a20..570f0f95d603 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -102,7 +102,8 @@ public class SpellChecker implements SpellCheckerSessionListener {
mTextServicesManager = (TextServicesManager) mTextView.getContext().
getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE);
- if (!mTextServicesManager.isSpellCheckerEnabled()) {
+ if (!mTextServicesManager.isSpellCheckerEnabled()
+ || mTextServicesManager.getCurrentSpellCheckerSubtype(true) == null) {
mSpellCheckerSession = null;
} else {
mSpellCheckerSession = mTextServicesManager.newSpellCheckerSession(
@@ -341,56 +342,15 @@ public class SpellChecker implements SpellCheckerSessionListener {
final int end = editable.getSpanEnd(spellCheckSpan);
if (start < 0 || end <= start) return; // span was removed in the meantime
- // Other suggestion spans may exist on that region, with identical suggestions, filter
- // them out to avoid duplicates.
- SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class);
- final int length = suggestionSpans.length;
- for (int i = 0; i < length; i++) {
- final int spanStart = editable.getSpanStart(suggestionSpans[i]);
- final int spanEnd = editable.getSpanEnd(suggestionSpans[i]);
- if (spanStart != start || spanEnd != end) {
- // Nulled (to avoid new array allocation) if not on that exact same region
- suggestionSpans[i] = null;
- }
- }
-
final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
- String[] suggestions;
if (suggestionsCount <= 0) {
// A negative suggestion count is possible
- suggestions = ArrayUtils.emptyArray(String.class);
- } else {
- int numberOfSuggestions = 0;
- suggestions = new String[suggestionsCount];
-
- for (int i = 0; i < suggestionsCount; i++) {
- final String spellSuggestion = suggestionsInfo.getSuggestionAt(i);
- if (spellSuggestion == null) break;
- boolean suggestionFound = false;
-
- for (int j = 0; j < length && !suggestionFound; j++) {
- if (suggestionSpans[j] == null) break;
-
- String[] suggests = suggestionSpans[j].getSuggestions();
- for (int k = 0; k < suggests.length; k++) {
- if (spellSuggestion.equals(suggests[k])) {
- // The suggestion is already provided by an other SuggestionSpan
- suggestionFound = true;
- break;
- }
- }
- }
-
- if (!suggestionFound) {
- suggestions[numberOfSuggestions++] = spellSuggestion;
- }
- }
+ return;
+ }
- if (numberOfSuggestions != suggestionsCount) {
- String[] newSuggestions = new String[numberOfSuggestions];
- System.arraycopy(suggestions, 0, newSuggestions, 0, numberOfSuggestions);
- suggestions = newSuggestions;
- }
+ String[] suggestions = new String[suggestionsCount];
+ for (int i = 0; i < suggestionsCount; i++) {
+ suggestions[i] = suggestionsInfo.getSuggestionAt(i);
}
SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 04f4a83e86c3..164bc64c711f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -256,10 +256,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private float mShadowRadius, mShadowDx, mShadowDy;
- private static final int PREDRAW_NOT_REGISTERED = 0;
- private static final int PREDRAW_PENDING = 1;
- private static final int PREDRAW_DONE = 2;
- private int mPreDrawState = PREDRAW_NOT_REGISTERED;
+ private boolean mPreDrawRegistered;
private TextUtils.TruncateAt mEllipsize = null;
@@ -365,8 +362,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private SpellChecker mSpellChecker;
- private boolean mSoftInputShownOnFocus = true;
-
// The alignment to pass to Layout, or null if not resolved.
private Layout.Alignment mLayoutAlignment;
@@ -2384,29 +2379,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
- * Sets whether the soft input method will be made visible when this
- * TextView gets focused. The default is true.
- *
- * @attr ref android.R.styleable#TextView_softInputShownOnFocus
- * @hide
- */
- @android.view.RemotableViewMethod
- public final void setSoftInputShownOnFocus(boolean show) {
- mSoftInputShownOnFocus = show;
- }
-
- /**
- * Returns whether the soft input method will be made visible when this
- * TextView gets focused. The default is true.
- *
- * @attr ref android.R.styleable#TextView_softInputShownOnFocus
- * @hide
- */
- public final boolean getSoftInputShownOnFocus() {
- return mSoftInputShownOnFocus;
- }
-
- /**
* Returns the list of URLSpans attached to the text
* (by {@link Linkify} or otherwise) if any. You can call
* {@link URLSpan#getURL} on them to find where they link to
@@ -4387,26 +4359,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void registerForPreDraw() {
- final ViewTreeObserver observer = getViewTreeObserver();
-
- if (mPreDrawState == PREDRAW_NOT_REGISTERED) {
- observer.addOnPreDrawListener(this);
- mPreDrawState = PREDRAW_PENDING;
- } else if (mPreDrawState == PREDRAW_DONE) {
- mPreDrawState = PREDRAW_PENDING;
+ if (!mPreDrawRegistered) {
+ getViewTreeObserver().addOnPreDrawListener(this);
+ mPreDrawRegistered = true;
}
-
- // else state is PREDRAW_PENDING, so keep waiting.
}
/**
* {@inheritDoc}
*/
public boolean onPreDraw() {
- if (mPreDrawState != PREDRAW_PENDING) {
- return true;
- }
-
if (mLayout == null) {
assumeLayout();
}
@@ -4457,7 +4419,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
startSelectionActionMode();
}
- mPreDrawState = PREDRAW_DONE;
+ getViewTreeObserver().removeOnPreDrawListener(this);
+ mPreDrawRegistered = false;
+
return !changed;
}
@@ -4492,10 +4456,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- final ViewTreeObserver observer = getViewTreeObserver();
- if (mPreDrawState != PREDRAW_NOT_REGISTERED) {
- observer.removeOnPreDrawListener(this);
- mPreDrawState = PREDRAW_NOT_REGISTERED;
+ if (mPreDrawRegistered) {
+ getViewTreeObserver().removeOnPreDrawListener(this);
+ mPreDrawRegistered = false;
}
if (mError != null) {
@@ -4768,12 +4731,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
protected void onDraw(Canvas canvas) {
- if (mPreDrawState == PREDRAW_DONE) {
- final ViewTreeObserver observer = getViewTreeObserver();
- observer.removeOnPreDrawListener(this);
- mPreDrawState = PREDRAW_NOT_REGISTERED;
- }
-
if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
restartMarqueeIfNeeded();
@@ -5040,7 +4997,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mTextDisplayList == null || !mTextDisplayList.isValid() ||
!mTextDisplayListIsValid) {
if (mTextDisplayList == null) {
- mTextDisplayList = getHardwareRenderer().createDisplayList();
+ mTextDisplayList = getHardwareRenderer().createDisplayList("Text");
}
final HardwareCanvas hardwareCanvas = mTextDisplayList.start();
@@ -5539,7 +5496,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
&& mLayout != null && onCheckIsTextEditor()) {
InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (imm != null && mSoftInputShownOnFocus) {
+ if (imm != null) {
imm.showSoftInput(this, 0);
}
}
@@ -6795,6 +6752,12 @@ 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;
+ }
+
/**
* Returns true if anything changed.
*/
@@ -8386,20 +8349,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (touchIsFinished && (isTextEditable() || mTextIsSelectable)) {
- // Move cursor
- final int offset = getOffsetForPosition(event.getX(), event.getY());
- Selection.setSelection((Spannable) mText, offset);
-
// Show the IME, except when selecting in read-only text.
final InputMethodManager imm = InputMethodManager.peekInstance();
viewClicked(imm);
- if (!mTextIsSelectable && mSoftInputShownOnFocus) {
+ if (!mTextIsSelectable) {
handled |= imm != null && imm.showSoftInput(this, 0);
}
boolean selectAllGotFocus = 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) {
// When the cursor moves, the word that was typed may need spell check
mSpellChecker.onSelectionChanged();
@@ -9749,11 +9711,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void show() {
if (!(mText instanceof Editable)) return;
- updateSuggestions();
- mCursorWasVisibleBeforeSuggestions = mCursorVisible;
- setCursorVisible(false);
- mIsShowingUp = true;
- super.show();
+ if (updateSuggestions()) {
+ mCursorWasVisibleBeforeSuggestions = mCursorVisible;
+ setCursorVisible(false);
+ mIsShowingUp = true;
+ super.show();
+ }
}
@Override
@@ -9809,11 +9772,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
super.hide();
}
- private void updateSuggestions() {
+ private boolean updateSuggestions() {
Spannable spannable = (Spannable) TextView.this.mText;
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
final int nbSpans = suggestionSpans.length;
+ // Suggestions are shown after a delay: the underlying spans may have been removed
+ if (nbSpans == 0) return false;
mNumberOfSuggestions = 0;
int spanUnionStart = mText.length();
@@ -9839,17 +9804,34 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
String[] suggestions = suggestionSpan.getSuggestions();
int nbSuggestions = suggestions.length;
for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
- SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
- suggestionInfo.suggestionSpan = suggestionSpan;
- suggestionInfo.suggestionIndex = suggestionIndex;
- suggestionInfo.text.replace(0, suggestionInfo.text.length(),
- suggestions[suggestionIndex]);
+ String suggestion = suggestions[suggestionIndex];
+
+ boolean suggestionIsDuplicate = false;
+ for (int i = 0; i < mNumberOfSuggestions; i++) {
+ if (mSuggestionInfos[i].text.toString().equals(suggestion)) {
+ SuggestionSpan otherSuggestionSpan = mSuggestionInfos[i].suggestionSpan;
+ final int otherSpanStart = spannable.getSpanStart(otherSuggestionSpan);
+ final int otherSpanEnd = spannable.getSpanEnd(otherSuggestionSpan);
+ if (spanStart == otherSpanStart && spanEnd == otherSpanEnd) {
+ suggestionIsDuplicate = true;
+ break;
+ }
+ }
+ }
- mNumberOfSuggestions++;
- if (mNumberOfSuggestions == MAX_NUMBER_SUGGESTIONS) {
- // Also end outer for loop
- spanIndex = nbSpans;
- break;
+ if (!suggestionIsDuplicate) {
+ SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
+ suggestionInfo.suggestionSpan = suggestionSpan;
+ suggestionInfo.suggestionIndex = suggestionIndex;
+ suggestionInfo.text.replace(0, suggestionInfo.text.length(), suggestion);
+
+ mNumberOfSuggestions++;
+
+ if (mNumberOfSuggestions == MAX_NUMBER_SUGGESTIONS) {
+ // Also end outer for loop
+ spanIndex = nbSpans;
+ break;
+ }
}
}
}
@@ -9858,7 +9840,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd);
}
- // Add to dictionary item if there is a span with the misspelled flag
+ // Add "Add to dictionary" item if there is a span with the misspelled flag
if (misspelledSpan != null) {
final int misspelledStart = spannable.getSpanStart(misspelledSpan);
final int misspelledEnd = spannable.getSpanEnd(misspelledSpan);
@@ -9899,6 +9881,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mSuggestionsAdapter.notifyDataSetChanged();
+ return true;
}
private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionStart,
@@ -9916,8 +9899,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// Add the text before and after the span.
- suggestionInfo.text.insert(0, mText.toString().substring(unionStart, spanStart));
- suggestionInfo.text.append(mText.toString().substring(spanEnd, unionEnd));
+ final String textAsString = text.toString();
+ suggestionInfo.text.insert(0, textAsString.substring(unionStart, spanStart));
+ suggestionInfo.text.append(textAsString.substring(spanEnd, unionEnd));
}
@Override
@@ -10163,7 +10147,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
final boolean selectionStarted = mSelectionActionMode != null || willExtract;
- if (selectionStarted && !mTextIsSelectable && mSoftInputShownOnFocus) {
+ 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) {
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index edeb2a8d7bc1..d1aa1ce1acf3 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -142,6 +142,14 @@ public class ArrayUtils
return false;
}
+ public static long total(long[] array) {
+ long total = 0;
+ for (long value : array) {
+ total += value;
+ }
+ return total;
+ }
+
/**
* Appends an element to a copy of the array and returns the copy.
* @param array The original array, or null to represent an empty array.
diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java
index efd087193a3c..88a17e6ba259 100644
--- a/core/java/com/android/internal/util/FastMath.java
+++ b/core/java/com/android/internal/util/FastMath.java
@@ -26,8 +26,8 @@ public class FastMath {
* thought it may return slightly different results. It does not try to
* handle (in any meaningful way) NaN or infinities.
*/
- public static int round(float x) {
- long lx = (long)(x * (65536 * 256f));
- return (int)((lx + 0x800000) >> 24);
+ public static int round(float value) {
+ long lx = (long) (value * (65536 * 256f));
+ return (int) ((lx + 0x800000) >> 24);
}
}
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 3ce95e7d506a..8a8f3157feab 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -17,9 +17,9 @@
package com.android.internal.util;
import android.os.FileUtils;
+import android.util.Slog;
-import com.android.internal.util.FileRotator.Reader;
-import com.android.internal.util.FileRotator.Writer;
+import com.android.internal.util.FileRotator.Rewriter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -41,12 +41,15 @@ import libcore.io.IoUtils;
* Instead of manipulating files directly, users implement interfaces that
* perform operations on {@link InputStream} and {@link OutputStream}. This
* enables atomic rewriting of file contents in
- * {@link #combineActive(Reader, Writer, long)}.
+ * {@link #rewriteActive(Rewriter, long)}.
* <p>
* Users must periodically call {@link #maybeRotate(long)} to perform actual
* rotation. Not inherently thread safe.
*/
public class FileRotator {
+ private static final String TAG = "FileRotator";
+ private static final boolean LOGD = true;
+
private final File mBasePath;
private final String mPrefix;
private final long mRotateAgeMillis;
@@ -73,6 +76,15 @@ public class FileRotator {
}
/**
+ * External class that reads existing data from given {@link InputStream},
+ * then writes any modified data to {@link OutputStream}.
+ */
+ public interface Rewriter extends Reader, Writer {
+ public void reset();
+ public boolean shouldWrite();
+ }
+
+ /**
* Create a file rotator.
*
* @param basePath Directory under which all files will be placed.
@@ -96,6 +108,8 @@ public class FileRotator {
if (!name.startsWith(mPrefix)) continue;
if (name.endsWith(SUFFIX_BACKUP)) {
+ if (LOGD) Slog.d(TAG, "recovering " + name);
+
final File backupFile = new File(mBasePath, name);
final File file = new File(
mBasePath, name.substring(0, name.length() - SUFFIX_BACKUP.length()));
@@ -104,6 +118,8 @@ public class FileRotator {
backupFile.renameTo(file);
} else if (name.endsWith(SUFFIX_NO_BACKUP)) {
+ if (LOGD) Slog.d(TAG, "recovering " + name);
+
final File noBackupFile = new File(mBasePath, name);
final File file = new File(
mBasePath, name.substring(0, name.length() - SUFFIX_NO_BACKUP.length()));
@@ -116,26 +132,95 @@ public class FileRotator {
}
/**
- * Atomically combine data with existing data in currently active file.
- * Maintains a backup during write, which is restored if the write fails.
+ * Delete all files managed by this rotator.
*/
- public void combineActive(Reader reader, Writer writer, long currentTimeMillis)
+ public void deleteAll() {
+ final FileInfo info = new FileInfo(mPrefix);
+ for (String name : mBasePath.list()) {
+ if (!info.parse(name)) continue;
+
+ // delete each file that matches parser
+ new File(mBasePath, name).delete();
+ }
+ }
+
+ /**
+ * Process currently active file, first reading any existing data, then
+ * writing modified data. Maintains a backup during write, which is restored
+ * if the write fails.
+ */
+ public void rewriteActive(Rewriter rewriter, long currentTimeMillis)
throws IOException {
final String activeName = getActiveName(currentTimeMillis);
+ rewriteSingle(rewriter, activeName);
+ }
- final File file = new File(mBasePath, activeName);
+ @Deprecated
+ public void combineActive(final Reader reader, final Writer writer, long currentTimeMillis)
+ throws IOException {
+ rewriteActive(new Rewriter() {
+ /** {@inheritDoc} */
+ public void reset() {
+ // ignored
+ }
+
+ /** {@inheritDoc} */
+ public void read(InputStream in) throws IOException {
+ reader.read(in);
+ }
+
+ /** {@inheritDoc} */
+ public boolean shouldWrite() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public void write(OutputStream out) throws IOException {
+ writer.write(out);
+ }
+ }, currentTimeMillis);
+ }
+
+ /**
+ * Process all files managed by this rotator, usually to rewrite historical
+ * data. Each file is processed atomically.
+ */
+ public void rewriteAll(Rewriter rewriter) throws IOException {
+ final FileInfo info = new FileInfo(mPrefix);
+ for (String name : mBasePath.list()) {
+ if (!info.parse(name)) continue;
+
+ // process each file that matches parser
+ rewriteSingle(rewriter, name);
+ }
+ }
+
+ /**
+ * Process a single file atomically, first reading any existing data, then
+ * writing modified data. Maintains a backup during write, which is restored
+ * if the write fails.
+ */
+ private void rewriteSingle(Rewriter rewriter, String name) throws IOException {
+ if (LOGD) Slog.d(TAG, "rewriting " + name);
+
+ final File file = new File(mBasePath, name);
final File backupFile;
+ rewriter.reset();
+
if (file.exists()) {
// read existing data
- readFile(file, reader);
+ readFile(file, rewriter);
+
+ // skip when rewriter has nothing to write
+ if (!rewriter.shouldWrite()) return;
// backup existing data during write
- backupFile = new File(mBasePath, activeName + SUFFIX_BACKUP);
+ backupFile = new File(mBasePath, name + SUFFIX_BACKUP);
file.renameTo(backupFile);
try {
- writeFile(file, writer);
+ writeFile(file, rewriter);
// write success, delete backup
backupFile.delete();
@@ -148,11 +233,11 @@ public class FileRotator {
} else {
// create empty backup during write
- backupFile = new File(mBasePath, activeName + SUFFIX_NO_BACKUP);
+ backupFile = new File(mBasePath, name + SUFFIX_NO_BACKUP);
backupFile.createNewFile();
try {
- writeFile(file, writer);
+ writeFile(file, rewriter);
// write success, delete empty backup
backupFile.delete();
@@ -176,6 +261,8 @@ public class FileRotator {
// read file when it overlaps
if (info.startMillis <= matchEndMillis && matchStartMillis <= info.endMillis) {
+ if (LOGD) Slog.d(TAG, "reading matching " + name);
+
final File file = new File(mBasePath, name);
readFile(file, reader);
}
@@ -224,16 +311,20 @@ public class FileRotator {
if (!info.parse(name)) continue;
if (info.isActive()) {
- // found active file; rotate if old enough
- if (info.startMillis < rotateBefore) {
+ if (info.startMillis <= rotateBefore) {
+ // found active file; rotate if old enough
+ if (LOGD) Slog.d(TAG, "rotating " + name);
+
info.endMillis = currentTimeMillis;
final File file = new File(mBasePath, name);
final File destFile = new File(mBasePath, info.build());
file.renameTo(destFile);
}
- } else if (info.endMillis < deleteBefore) {
+ } else if (info.endMillis <= deleteBefore) {
// found rotated file; delete if old enough
+ if (LOGD) Slog.d(TAG, "deleting " + name);
+
final File file = new File(mBasePath, name);
file.delete();
}
diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java
new file mode 100644
index 000000000000..3dd2284a2631
--- /dev/null
+++ b/core/java/com/android/internal/util/IndentingPrintWriter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import java.io.PrintWriter;
+import java.io.Writer;
+
+/**
+ * Lightweight wrapper around {@link PrintWriter} that automatically indents
+ * newlines based on internal state. Delays writing indent until first actual
+ * write on a newline, enabling indent modification after newline.
+ */
+public class IndentingPrintWriter extends PrintWriter {
+ private final String mIndent;
+
+ private StringBuilder mBuilder = new StringBuilder();
+ private String mCurrent = new String();
+ private boolean mEmptyLine = true;
+
+ public IndentingPrintWriter(Writer writer, String indent) {
+ super(writer);
+ mIndent = indent;
+ }
+
+ public void increaseIndent() {
+ mBuilder.append(mIndent);
+ mCurrent = mBuilder.toString();
+ }
+
+ public void decreaseIndent() {
+ mBuilder.delete(0, mIndent.length());
+ mCurrent = mBuilder.toString();
+ }
+
+ @Override
+ public void println() {
+ super.println();
+ mEmptyLine = true;
+ }
+
+ @Override
+ public void write(char[] buf, int offset, int count) {
+ if (mEmptyLine) {
+ mEmptyLine = false;
+ super.print(mCurrent);
+ }
+ super.write(buf, offset, count);
+ }
+}
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index a235d9a2346f..9024d8da3798 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -387,9 +387,9 @@ public class InputConnectionWrapper implements InputConnection {
}
}
- public boolean deleteSurroundingText(int leftLength, int rightLength) {
+ public boolean deleteSurroundingText(int beforeLength, int afterLength) {
try {
- mIInputContext.deleteSurroundingText(leftLength, rightLength);
+ mIInputContext.deleteSurroundingText(beforeLength, afterLength);
return true;
} catch (RemoteException e) {
return false;
diff --git a/core/java/com/android/internal/widget/DigitalClock.java b/core/java/com/android/internal/widget/DigitalClock.java
index daefc9a3046a..af3fd425d4fd 100644
--- a/core/java/com/android/internal/widget/DigitalClock.java
+++ b/core/java/com/android/internal/widget/DigitalClock.java
@@ -228,7 +228,7 @@ public class DigitalClock extends RelativeLayout {
updateTime();
}
- private void updateTime() {
+ public void updateTime() {
mCalendar.setTimeInMillis(System.currentTimeMillis());
CharSequence newTime = DateFormat.format(mFormat, mCalendar);
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 32e733baa98a..9579bce468da 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -35,6 +35,11 @@ public class EditableInputConnection extends BaseInputConnection {
private final TextView mTextView;
+ // Keeps track of nested begin/end batch edit to ensure this connection always has a
+ // balanced impact on its associated TextView.
+ // A negative value means that this connection has been finished by the InputMethodManager.
+ private int mBatchEditNesting;
+
public EditableInputConnection(TextView textview) {
super(textview, true);
mTextView = textview;
@@ -48,19 +53,35 @@ public class EditableInputConnection extends BaseInputConnection {
}
return null;
}
-
+
@Override
public boolean beginBatchEdit() {
- mTextView.beginBatchEdit();
- return true;
+ synchronized(this) {
+ if (mBatchEditNesting >= 0) {
+ mTextView.beginBatchEdit();
+ mBatchEditNesting++;
+ return true;
+ }
+ }
+ return false;
}
-
+
@Override
public boolean endBatchEdit() {
- mTextView.endBatchEdit();
- return true;
+ synchronized(this) {
+ if (mBatchEditNesting > 0) {
+ // When the connection is reset by the InputMethodManager and finishComposingText
+ // is called, some endBatchEdit calls may still be asynchronously received from the
+ // IME. Do not take these into account, thus ensuring that this IC's final
+ // contribution to mTextView's nested batch edit count is zero.
+ mTextView.endBatchEdit();
+ mBatchEditNesting--;
+ return true;
+ }
+ }
+ return false;
}
-
+
@Override
public boolean clearMetaKeyStates(int states) {
final Editable content = getEditable();
@@ -76,7 +97,24 @@ public class EditableInputConnection extends BaseInputConnection {
}
return true;
}
-
+
+ @Override
+ public boolean finishComposingText() {
+ final boolean superResult = super.finishComposingText();
+ synchronized(this) {
+ if (mBatchEditNesting < 0) {
+ // The connection was already finished
+ return false;
+ }
+ while (mBatchEditNesting > 0) {
+ endBatchEdit();
+ }
+ // Will prevent any further calls to begin or endBatchEdit
+ mBatchEditNesting = -1;
+ }
+ return superResult;
+ }
+
@Override
public boolean commitCompletion(CompletionInfo text) {
if (DEBUG) Log.v(TAG, "commitCompletion " + text);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 905a1713add5..6893ffbaf6c5 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -404,7 +404,7 @@ public class LockPatternUtils {
saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
setLockPatternEnabled(false);
saveLockPattern(null);
- setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
setLong(PASSWORD_TYPE_ALTERNATE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
}
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index c8b725a7337a..23ee8f8ba1b0 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -757,20 +757,11 @@ public:
int start, int count, int contextCount,
jfloat x, jfloat y, int flags, SkPaint* paint) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
- contextCount, flags);
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ textArray, start, count, contextCount, flags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(textArray + start, count).string());
- return ;
+ return;
}
-#else
- value = new TextLayoutCacheValue(contextCount);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- reinterpret_cast<const UChar*>(textArray), start, count, contextCount, flags);
-#endif
doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
}
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 9bcfa5f7ad2c..376c8416c969 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -465,11 +465,10 @@ public:
jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
- TextLayoutCacheValue value(contextCount);
- TextLayoutEngine::getInstance().computeValues(&value, paint, text, start, count,
- contextCount, flags);
- const jchar* shapedGlyphs = value.getGlyphs();
- size_t glyphsCount = value.getGlyphsCount();
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, start, count, contextCount, flags);
+ const jchar* shapedGlyphs = value->getGlyphs();
+ size_t glyphsCount = value->getGlyphsCount();
memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
@@ -677,20 +676,11 @@ public:
static int breakText(JNIEnv* env, SkPaint& paint, const jchar text[],
int count, float maxWidth, jfloatArray jmeasured,
SkPaint::TextBufferDirection tbd) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(&paint, text, 0, count,
- count, paint.getFlags());
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
+ text, 0, count, count, paint.getFlags());
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text, count).string());
+ return 0;
}
-#else
- value = new TextLayoutCacheValue(count);
- TextLayoutEngine::getInstance().computeValues(value.get(), &paint,
- reinterpret_cast<const UChar*>(text), 0, count, count, paint.getFlags());
-#endif
-
SkScalar measured;
size_t bytes = paint.breakText(value->getGlyphs(), value->getGlyphsCount() << 1,
SkFloatToScalar(maxWidth), &measured, tbd);
@@ -756,19 +746,11 @@ public:
SkRect r;
SkIRect ir;
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(&paint, text, 0, count,
- count, paint.getFlags());
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
+ text, 0, count, count, paint.getFlags());
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text, count).string());
+ return;
}
-#else
- value = new TextLayoutCacheValue(count);
- TextLayoutEngine::getInstance().computeValues(value.get(), &paint,
- reinterpret_cast<const UChar*>(text), 0, count, count, paint.getFlags());
-#endif
paint.measureText(value->getGlyphs(), value->getGlyphsCount() << 1, &r);
r.roundOut(&ir);
GraphicsJNI::irect_to_jrect(ir, env, bounds);
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index 2d8385198f42..2241f6032dff 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -53,19 +53,9 @@ bool TextLayout::needsLayout(const jchar* text, jint len, jint bidiFlags) {
// a path representing the text that would have been drawn.
void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len,
jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- // Return advances from the cache. Compute them if needed
- value = TextLayoutCache::getInstance().getValue(paint, text, 0, len,
- len, bidiFlags);
-#else
- value = new TextLayoutCacheValue(len);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- reinterpret_cast<const UChar*>(text), 0, len, len, bidiFlags);
-#endif
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, 0, len, len, bidiFlags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text, len).string());
return ;
}
SkScalar x_ = SkFloatToScalar(x);
@@ -77,19 +67,9 @@ void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len,
void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start,
jint count, jint contextCount, jint dirFlags,
jfloat* resultAdvances, jfloat* resultTotalAdvance) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- // Return advances from the cache. Compute them if needed
- value = TextLayoutCache::getInstance().getValue(paint, chars, start, count,
- contextCount, dirFlags);
-#else
- value = new TextLayoutCacheValue(contextCount);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- reinterpret_cast<const UChar*>(chars), start, count, contextCount, dirFlags);
-#endif
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ chars, start, count, contextCount, dirFlags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(chars + start, count).string());
return ;
}
if (resultAdvances) {
@@ -126,20 +106,12 @@ void TextLayout::drawTextOnPath(SkPaint* paint, const jchar* text, int count,
return;
}
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, text, 0, count,
- count, bidiFlags);
-#else
- value = new TextLayoutCacheValue(count);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- reinterpret_cast<const UChar*>(text), 0, count, count, bidiFlags);
-#endif
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, 0, count, count, bidiFlags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text, count).string());
- return ;
+ return;
}
+
// Beware: this needs Glyph encoding (already done on the Paint constructor)
canvas->drawTextOnPathHV(value->getGlyphs(), value->getGlyphsCount() * 2, *path, h_, v_, *paint);
}
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 71c283a73e75..c797a73159e5 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -35,18 +35,13 @@ namespace android {
#define TYPEFACE_BENGALI "/system/fonts/Lohit-Bengali.ttf"
#define TYPEFACE_THAI "/system/fonts/DroidSansThai.ttf"
-#if USE_TEXT_LAYOUT_CACHE
-
- ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutCache);
-
-#endif
-
- ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
+ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
//--------------------------------------------------------------------------------------------------
-TextLayoutCache::TextLayoutCache() :
- mCache(GenerationCache<TextLayoutCacheKey, sp<TextLayoutCacheValue> >::kUnlimitedCapacity),
+TextLayoutCache::TextLayoutCache(TextLayoutShaper* shaper) :
+ mShaper(shaper),
+ mCache(GenerationCache<TextLayoutCacheKey, sp<TextLayoutValue> >::kUnlimitedCapacity),
mSize(0), mMaxSize(MB(DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB)),
mCacheHitCount(0), mNanosecondsSaved(0) {
init();
@@ -75,7 +70,7 @@ void TextLayoutCache::init() {
/**
* Callbacks
*/
-void TextLayoutCache::operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc) {
+void TextLayoutCache::operator()(TextLayoutCacheKey& text, sp<TextLayoutValue>& desc) {
size_t totalSizeToDelete = text.getSize() + desc->getSize();
mSize -= totalSizeToDelete;
if (mDebugEnabled) {
@@ -93,7 +88,7 @@ void TextLayoutCache::clear() {
/*
* Caching
*/
-sp<TextLayoutCacheValue> TextLayoutCache::getValue(const SkPaint* paint,
+sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint,
const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) {
AutoMutex _l(mLock);
nsecs_t startTime = 0;
@@ -105,7 +100,7 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(const SkPaint* paint,
TextLayoutCacheKey key(paint, text, start, count, contextCount, dirFlags);
// Get value from cache if possible
- sp<TextLayoutCacheValue> value = mCache.get(key);
+ sp<TextLayoutValue> value = mCache.get(key);
// Value not found for the key, we need to add a new value in the cache
if (value == NULL) {
@@ -113,10 +108,10 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(const SkPaint* paint,
startTime = systemTime(SYSTEM_TIME_MONOTONIC);
}
- value = new TextLayoutCacheValue(contextCount);
+ value = new TextLayoutValue(contextCount);
// Compute advances and store them
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+ mShaper->computeValues(value.get(), paint,
reinterpret_cast<const UChar*>(text), start, count,
size_t(contextCount), int(dirFlags));
@@ -312,31 +307,33 @@ size_t TextLayoutCacheKey::getSize() const {
/**
* TextLayoutCacheValue
*/
-TextLayoutCacheValue::TextLayoutCacheValue(size_t contextCount) :
+TextLayoutValue::TextLayoutValue(size_t contextCount) :
mTotalAdvance(0), mElapsedTime(0) {
// Give a hint for advances and glyphs vectors size
mAdvances.setCapacity(contextCount);
mGlyphs.setCapacity(contextCount);
}
-size_t TextLayoutCacheValue::getSize() const {
- return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvances.capacity() +
+size_t TextLayoutValue::getSize() const {
+ return sizeof(TextLayoutValue) + sizeof(jfloat) * mAdvances.capacity() +
sizeof(jchar) * mGlyphs.capacity();
}
-void TextLayoutCacheValue::setElapsedTime(uint32_t time) {
+void TextLayoutValue::setElapsedTime(uint32_t time) {
mElapsedTime = time;
}
-uint32_t TextLayoutCacheValue::getElapsedTime() {
+uint32_t TextLayoutValue::getElapsedTime() {
return mElapsedTime;
}
-TextLayoutEngine::TextLayoutEngine() : mShaperItemGlyphArraySize(0) {
+TextLayoutShaper::TextLayoutShaper() : mShaperItemGlyphArraySize(0) {
mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal);
mArabicTypeface = NULL;
mHebrewRegularTypeface = NULL;
mHebrewBoldTypeface = NULL;
+ mBengaliTypeface = NULL;
+ mThaiTypeface = NULL;
mFontRec.klass = &harfbuzzSkiaClass;
mFontRec.userData = 0;
@@ -355,12 +352,17 @@ TextLayoutEngine::TextLayoutEngine() : mShaperItemGlyphArraySize(0) {
mShaperItem.font->userData = &mShapingPaint;
}
-TextLayoutEngine::~TextLayoutEngine() {
- // FIXME should free fonts and caches but since this class is a singleton,
- // we don't bother at the moment
+TextLayoutShaper::~TextLayoutShaper() {
+ SkSafeUnref(mDefaultTypeface);
+ SkSafeUnref(mArabicTypeface);
+ SkSafeUnref(mHebrewRegularTypeface);
+ SkSafeUnref(mHebrewBoldTypeface);
+ SkSafeUnref(mBengaliTypeface);
+ SkSafeUnref(mThaiTypeface);
+ deleteShaperItemGlyphArrays();
}
-void TextLayoutEngine::computeValues(TextLayoutCacheValue* value, const SkPaint* paint, const UChar* chars,
+void TextLayoutShaper::computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags) {
computeValues(paint, chars, start, count, contextCount, dirFlags,
@@ -371,7 +373,7 @@ void TextLayoutEngine::computeValues(TextLayoutCacheValue* value, const SkPaint*
#endif
}
-void TextLayoutEngine::computeValues(const SkPaint* paint, const UChar* chars,
+void TextLayoutShaper::computeValues(const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags,
Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
Vector<jchar>* const outGlyphs) {
@@ -513,7 +515,7 @@ static void logGlyphs(HB_ShaperItem shaperItem) {
}
}
-void TextLayoutEngine::computeRunValues(const SkPaint* paint, const UChar* chars,
+void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars,
size_t count, bool isRTL,
Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
Vector<jchar>* const outGlyphs) {
@@ -719,7 +721,7 @@ void TextLayoutEngine::computeRunValues(const SkPaint* paint, const UChar* chars
}
-size_t TextLayoutEngine::shapeFontRun(const SkPaint* paint, bool isRTL) {
+size_t TextLayoutShaper::shapeFontRun(const SkPaint* paint, bool isRTL) {
// Reset kerning
mShaperItem.kerning_applied = false;
@@ -811,7 +813,7 @@ size_t TextLayoutEngine::shapeFontRun(const SkPaint* paint, bool isRTL) {
case HB_Script_Hebrew:
case HB_Script_Bengali:
case HB_Script_Thai:{
- const uint16_t* text16 = (const uint16_t*)mShaperItem.string;
+ const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos);
SkUnichar firstUnichar = SkUTF16_NextUnichar(&text16);
baseGlyphCount = paint->getBaseGlyphCount(firstUnichar);
break;
@@ -833,14 +835,14 @@ size_t TextLayoutEngine::shapeFontRun(const SkPaint* paint, bool isRTL) {
return baseGlyphCount;
}
-void TextLayoutEngine::ensureShaperItemGlyphArrays(size_t size) {
+void TextLayoutShaper::ensureShaperItemGlyphArrays(size_t size) {
if (size > mShaperItemGlyphArraySize) {
deleteShaperItemGlyphArrays();
createShaperItemGlyphArrays(size);
}
}
-void TextLayoutEngine::createShaperItemGlyphArrays(size_t size) {
+void TextLayoutShaper::createShaperItemGlyphArrays(size_t size) {
#if DEBUG_GLYPHS
ALOGD("Creating Glyph Arrays with size = %d", size);
#endif
@@ -858,7 +860,7 @@ void TextLayoutEngine::createShaperItemGlyphArrays(size_t size) {
mShaperItem.log_clusters = new unsigned short[size];
}
-void TextLayoutEngine::deleteShaperItemGlyphArrays() {
+void TextLayoutShaper::deleteShaperItemGlyphArrays() {
delete[] mShaperItem.glyphs;
delete[] mShaperItem.attributes;
delete[] mShaperItem.advances;
@@ -866,7 +868,7 @@ void TextLayoutEngine::deleteShaperItemGlyphArrays() {
delete[] mShaperItem.log_clusters;
}
-SkTypeface* TextLayoutEngine::getCachedTypeface(SkTypeface** typeface, const char path[]) {
+SkTypeface* TextLayoutShaper::getCachedTypeface(SkTypeface** typeface, const char path[]) {
if (!*typeface) {
*typeface = SkTypeface::CreateFromFile(path);
// CreateFromFile(path) can return NULL if the path is non existing
@@ -884,7 +886,7 @@ SkTypeface* TextLayoutEngine::getCachedTypeface(SkTypeface** typeface, const cha
return *typeface;
}
-HB_Face TextLayoutEngine::getCachedHBFace(SkTypeface* typeface) {
+HB_Face TextLayoutShaper::getCachedHBFace(SkTypeface* typeface) {
SkFontID fontId = typeface->uniqueID();
ssize_t index = mCachedHBFaces.indexOfKey(fontId);
if (index >= 0) {
@@ -900,4 +902,36 @@ HB_Face TextLayoutEngine::getCachedHBFace(SkTypeface* typeface) {
return face;
}
+TextLayoutEngine::TextLayoutEngine() {
+ mShaper = new TextLayoutShaper();
+#if USE_TEXT_LAYOUT_CACHE
+ mTextLayoutCache = new TextLayoutCache(mShaper);
+#else
+ mTextLayoutCache = NULL;
+#endif
+}
+
+TextLayoutEngine::~TextLayoutEngine() {
+ delete mTextLayoutCache;
+ delete mShaper;
+}
+
+sp<TextLayoutValue> TextLayoutEngine::getValue(const SkPaint* paint, const jchar* text,
+ jint start, jint count, jint contextCount, jint dirFlags) {
+ sp<TextLayoutValue> value;
+#if USE_TEXT_LAYOUT_CACHE
+ value = mTextLayoutCache->getValue(paint, text, start, count,
+ contextCount, dirFlags);
+ if (value == NULL) {
+ ALOGE("Cannot get TextLayoutCache value for text = '%s'",
+ String8(text + start, count).string());
+ }
+#else
+ value = new TextLayoutValue(count);
+ mShaper->computeValues(value.get(), paint,
+ reinterpret_cast<const UChar*>(text), start, count, contextCount, dirFlags);
+#endif
+ return value;
+}
+
} // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 956e8cac3dd9..7ac2f1812895 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -115,11 +115,11 @@ inline int compare_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey&
}
/*
- * TextLayoutCacheValue is the Cache value
+ * TextLayoutValue is the Cache value
*/
-class TextLayoutCacheValue : public RefBase {
+class TextLayoutValue : public RefBase {
public:
- TextLayoutCacheValue(size_t contextCount);
+ TextLayoutValue(size_t contextCount);
void setElapsedTime(uint32_t time);
uint32_t getElapsedTime();
@@ -159,72 +159,14 @@ private:
}; // TextLayoutCacheValue
/**
- * Cache of text layout information.
+ * The TextLayoutShaper is responsible for shaping (with the Harfbuzz library)
*/
-class TextLayoutCache : public OnEntryRemoved<TextLayoutCacheKey, sp<TextLayoutCacheValue> >,
- public Singleton<TextLayoutCache>
-{
+class TextLayoutShaper {
public:
- TextLayoutCache();
-
- virtual ~TextLayoutCache();
-
- bool isInitialized() {
- return mInitialized;
- }
-
- /**
- * Used as a callback when an entry is removed from the cache
- * Do not invoke directly
- */
- void operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc);
-
- sp<TextLayoutCacheValue> getValue(const SkPaint* paint, const jchar* text, jint start, jint count,
- jint contextCount, jint dirFlags);
-
- /**
- * Clear the cache
- */
- void clear();
-
-private:
- Mutex mLock;
- bool mInitialized;
-
- GenerationCache<TextLayoutCacheKey, sp<TextLayoutCacheValue> > mCache;
-
- uint32_t mSize;
- uint32_t mMaxSize;
-
- uint32_t mCacheHitCount;
- uint64_t mNanosecondsSaved;
+ TextLayoutShaper();
+ virtual ~TextLayoutShaper();
- uint64_t mCacheStartTime;
-
- RtlDebugLevel mDebugLevel;
- bool mDebugEnabled;
-
- /*
- * Class initialization
- */
- void init();
-
- /**
- * Dump Cache statistics
- */
- void dumpCacheStats();
-
-}; // TextLayoutCache
-
-/**
- * The TextLayoutEngine is responsible for shaping with Harfbuzz library
- */
-class TextLayoutEngine : public Singleton<TextLayoutEngine> {
-public:
- TextLayoutEngine();
- virtual ~TextLayoutEngine();
-
- void computeValues(TextLayoutCacheValue* value, const SkPaint* paint, const UChar* chars,
+ void computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
size_t start, size_t count, size_t contextCount, int dirFlags);
private:
@@ -292,8 +234,80 @@ private:
void createShaperItemGlyphArrays(size_t size);
void deleteShaperItemGlyphArrays();
-}; // TextLayoutEngine
+}; // TextLayoutShaper
+/**
+ * Cache of text layout information.
+ */
+class TextLayoutCache : private OnEntryRemoved<TextLayoutCacheKey, sp<TextLayoutValue> >
+{
+public:
+ TextLayoutCache(TextLayoutShaper* shaper);
+
+ ~TextLayoutCache();
+
+ bool isInitialized() {
+ return mInitialized;
+ }
+
+ /**
+ * Used as a callback when an entry is removed from the cache
+ * Do not invoke directly
+ */
+ void operator()(TextLayoutCacheKey& text, sp<TextLayoutValue>& desc);
+
+ sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
+ jint count, jint contextCount, jint dirFlags);
+
+ /**
+ * Clear the cache
+ */
+ void clear();
+
+private:
+ TextLayoutShaper* mShaper;
+ Mutex mLock;
+ bool mInitialized;
+
+ GenerationCache<TextLayoutCacheKey, sp<TextLayoutValue> > mCache;
+
+ uint32_t mSize;
+ uint32_t mMaxSize;
+
+ uint32_t mCacheHitCount;
+ uint64_t mNanosecondsSaved;
+
+ uint64_t mCacheStartTime;
+
+ RtlDebugLevel mDebugLevel;
+ bool mDebugEnabled;
+
+ /*
+ * Class initialization
+ */
+ void init();
+
+ /**
+ * Dump Cache statistics
+ */
+ void dumpCacheStats();
+
+}; // TextLayoutCache
+
+/**
+ * The TextLayoutEngine is reponsible for computing TextLayoutValues
+ */
+class TextLayoutEngine : public Singleton<TextLayoutEngine> {
+public:
+ TextLayoutEngine();
+ virtual ~TextLayoutEngine();
+
+ sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
+ jint count, jint contextCount, jint dirFlags);
+private:
+ TextLayoutCache* mTextLayoutCache;
+ TextLayoutShaper* mShaper;
+}; // TextLayoutEngine
} // namespace android
#endif /* ANDROID_TEXT_LAYOUT_CACHE_H */
diff --git a/core/jni/android_database_SQLiteCommon.cpp b/core/jni/android_database_SQLiteCommon.cpp
index a94b9d269c3d..3484467a4719 100644
--- a/core/jni/android_database_SQLiteCommon.cpp
+++ b/core/jni/android_database_SQLiteCommon.cpp
@@ -68,50 +68,53 @@ void throw_sqlite3_exception(JNIEnv* env, int errcode,
exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException";
break;
case SQLITE_CONSTRAINT:
- exceptionClass = "android/database/sqlite/SQLiteConstraintException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteConstraintException";
+ break;
case SQLITE_ABORT:
- exceptionClass = "android/database/sqlite/SQLiteAbortException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteAbortException";
+ break;
case SQLITE_DONE:
- exceptionClass = "android/database/sqlite/SQLiteDoneException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteDoneException";
+ break;
case SQLITE_FULL:
- exceptionClass = "android/database/sqlite/SQLiteFullException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteFullException";
+ break;
case SQLITE_MISUSE:
- exceptionClass = "android/database/sqlite/SQLiteMisuseException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteMisuseException";
+ break;
case SQLITE_PERM:
- exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
+ break;
case SQLITE_BUSY:
- exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
+ break;
case SQLITE_LOCKED:
- exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
+ break;
case SQLITE_READONLY:
- exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
+ break;
case SQLITE_CANTOPEN:
- exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
+ break;
case SQLITE_TOOBIG:
- exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
+ break;
case SQLITE_RANGE:
- exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
+ break;
case SQLITE_NOMEM:
- exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
+ break;
case SQLITE_MISMATCH:
- exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
+ break;
+ case SQLITE_INTERRUPT:
+ exceptionClass = "android/content/OperationCanceledException";
+ break;
default:
- exceptionClass = "android/database/sqlite/SQLiteException";
- break;
+ exceptionClass = "android/database/sqlite/SQLiteException";
+ break;
}
if (sqlite3Message != NULL && message != NULL) {
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index d0d53f6f451d..e061ac3d8e6a 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -67,8 +67,10 @@ struct SQLiteConnection {
const String8 path;
const String8 label;
+ volatile bool canceled;
+
SQLiteConnection(sqlite3* db, int openFlags, const String8& path, const String8& label) :
- db(db), openFlags(openFlags), path(path), label(label) { }
+ db(db), openFlags(openFlags), path(path), label(label), canceled(false) { }
};
// Called each time a statement begins execution, when tracing is enabled.
@@ -85,6 +87,12 @@ static void sqliteProfileCallback(void *data, const char *sql, sqlite3_uint64 tm
connection->label.string(), sql, tm * 0.000001f);
}
+// Called after each SQLite VM instruction when cancelation is enabled.
+static int sqliteProgressHandlerCallback(void* data) {
+ SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
+ return connection->canceled;
+}
+
static jint nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlags,
jstring labelStr, jboolean enableTrace, jboolean enableProfile) {
@@ -871,6 +879,24 @@ static jint nativeGetDbLookaside(JNIEnv* env, jobject clazz, jint connectionPtr)
return cur;
}
+static void nativeCancel(JNIEnv* env, jobject clazz, jint connectionPtr) {
+ SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+ connection->canceled = true;
+}
+
+static void nativeResetCancel(JNIEnv* env, jobject clazz, jint connectionPtr,
+ jboolean cancelable) {
+ SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+ connection->canceled = false;
+
+ if (cancelable) {
+ sqlite3_progress_handler(connection->db, 4, sqliteProgressHandlerCallback,
+ connection);
+ } else {
+ sqlite3_progress_handler(connection->db, 0, NULL, NULL);
+ }
+}
+
static JNINativeMethod sMethods[] =
{
@@ -923,6 +949,10 @@ static JNINativeMethod sMethods[] =
(void*)nativeExecuteForCursorWindow },
{ "nativeGetDbLookaside", "(I)I",
(void*)nativeGetDbLookaside },
+ { "nativeCancel", "(I)V",
+ (void*)nativeCancel },
+ { "nativeResetCancel", "(IZ)V",
+ (void*)nativeResetCancel },
};
#define FIND_CLASS(var, className) \
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 3f1af8645256..547607ec2947 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -157,7 +157,7 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
int frameSize = nbChannels * bytesPerSample;
size_t frameCount = buffSizeInBytes / frameSize;
- if (source >= AUDIO_SOURCE_CNT) {
+ if (uint32_t(source) >= AUDIO_SOURCE_CNT) {
ALOGE("Error creating AudioRecord: unknown source.");
return AUDIORECORD_ERROR_SETUP_INVALIDSOURCE;
}
@@ -198,7 +198,7 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
// we use a weak reference so the AudioRecord object can be garbage collected.
lpCallbackData->audioRecord_ref = env->NewGlobalRef(weak_this);
- lpRecorder->set(source,
+ lpRecorder->set((audio_source_t) source,
sampleRateInHertz,
format, // word length, PCM
channels,
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 5811dddeb3c3..e19bb38dc53d 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -188,6 +188,14 @@ static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
renderer->finish();
}
+static jint android_view_GLES20Canvas_getStencilSize(JNIEnv* env, jobject clazz) {
+ return OpenGLRenderer::getStencilSize();
+}
+
+// ----------------------------------------------------------------------------
+// Functor
+// ----------------------------------------------------------------------------
+
static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, Functor *functor) {
android::uirenderer::Rect dirty;
@@ -502,19 +510,11 @@ static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject claz
static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat x, jfloat y, int flags, SkPaint* paint) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, flags);
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, 0, count, count, flags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text, count).string());
return;
}
-#else
- value = new TextLayoutCacheValue(count);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- text, 0, count, count, flags);
-#endif
const jchar* glyphs = value->getGlyphs();
size_t glyphsCount = value->getGlyphsCount();
int bytesCount = glyphsCount * sizeof(jchar);
@@ -524,19 +524,11 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
jint start, jint count, jint contextCount, jfloat x, jfloat y,
int flags, SkPaint* paint) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, text, start, count, contextCount, flags);
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, start, count, contextCount, flags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text + start, count).string());
return;
}
-#else
- value = new TextLayoutCacheValue(count);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- text, start, count, contextCount, flags);
-#endif
const jchar* glyphs = value->getGlyphs();
size_t glyphsCount = value->getGlyphsCount();
int bytesCount = glyphsCount * sizeof(jchar);
@@ -583,20 +575,11 @@ static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
static void renderPosText(OpenGLRenderer* renderer, const jchar* text, int count,
const jfloat* positions, jint dirFlags, SkPaint* paint) {
- sp<TextLayoutCacheValue> value;
-#if USE_TEXT_LAYOUT_CACHE
- value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, dirFlags);
+ sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+ text, 0, count, count, dirFlags);
if (value == NULL) {
- ALOGE("Cannot get TextLayoutCache value for text = '%s'",
- String8(text, count).string());
return;
}
-#else
- value = new TextLayoutCacheValue(count);
- TextLayoutEngine::getInstance().computeValues(value.get(), paint,
- text, 0, count, count, dirFlags);
-#endif
-
const jchar* glyphs = value->getGlyphs();
size_t glyphsCount = value->getGlyphsCount();
if (count < int(glyphsCount)) glyphsCount = count;
@@ -643,6 +626,15 @@ static jint android_view_GLES20Canvas_getDisplayListSize(JNIEnv* env,
return displayList->getSize();
}
+static void android_view_GLES20Canvas_setDisplayListName(JNIEnv* env,
+ jobject clazz, DisplayList* displayList, jstring name) {
+ if (name != NULL) {
+ const char* textArray = env->GetStringUTFChars(name, NULL);
+ displayList->setName(textArray);
+ env->ReleaseStringUTFChars(name, textArray);
+ }
+}
+
static OpenGLRenderer* android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env,
jobject clazz) {
return new DisplayListRenderer;
@@ -833,6 +825,8 @@ static JNINativeMethod gMethods[] = {
{ "nPrepareDirty", "(IIIIIZ)V", (void*) android_view_GLES20Canvas_prepareDirty },
{ "nFinish", "(I)V", (void*) android_view_GLES20Canvas_finish },
+ { "nGetStencilSize", "()I", (void*) android_view_GLES20Canvas_getStencilSize },
+
{ "nCallDrawGLFunction", "(II)Z",
(void*) android_view_GLES20Canvas_callDrawGLFunction },
@@ -905,10 +899,14 @@ static JNINativeMethod gMethods[] = {
{ "nGetDisplayList", "(II)I", (void*) android_view_GLES20Canvas_getDisplayList },
{ "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList },
{ "nGetDisplayListSize", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListSize },
- { "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
- { "nResetDisplayListRenderer", "(I)V", (void*) android_view_GLES20Canvas_resetDisplayListRenderer },
+ { "nSetDisplayListName", "(ILjava/lang/String;)V",
+ (void*) android_view_GLES20Canvas_setDisplayListName },
{ "nDrawDisplayList", "(IIIILandroid/graphics/Rect;)Z",
(void*) android_view_GLES20Canvas_drawDisplayList },
+
+ { "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
+ { "nResetDisplayListRenderer", "(I)V", (void*) android_view_GLES20Canvas_resetDisplayListRenderer },
+
{ "nOutputDisplayList", "(II)V", (void*) android_view_GLES20Canvas_outputDisplayList },
{ "nInterrupt", "(I)V", (void*) android_view_GLES20Canvas_interrupt },
{ "nResume", "(I)V", (void*) android_view_GLES20Canvas_resume },
diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_HardwareRenderer.cpp
index 09809ecf49fb..cdcde51e9e2b 100644
--- a/core/jni/android_view_HardwareRenderer.cpp
+++ b/core/jni/android_view_HardwareRenderer.cpp
@@ -22,6 +22,8 @@
#include <EGL/egl_cache.h>
+EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
+
namespace android {
// ----------------------------------------------------------------------------
@@ -36,6 +38,12 @@ static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, job
env->ReleaseStringUTFChars(diskCachePath, cacheArray);
}
+static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz) {
+ EGLDisplay dpy = eglGetCurrentDisplay();
+ EGLSurface surf = eglGetCurrentSurface(EGL_DRAW);
+ eglBeginFrame(dpy, surf);
+}
+
// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -45,6 +53,8 @@ const char* const kClassPathName = "android/view/HardwareRenderer";
static JNINativeMethod gMethods[] = {
{ "nSetupShadersDiskCache", "(Ljava/lang/String;)V",
(void*) android_view_HardwareRenderer_setupShadersDiskCache },
+ { "nBeginFrame", "()V",
+ (void*) android_view_HardwareRenderer_beginFrame },
};
int register_android_view_HardwareRenderer(JNIEnv* env) {
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 6ffda04fa1e1..f21c6b896dea 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Verslag"</string>
<string name="wait" msgid="7147118217226317732">"Wag"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Die bladsy reageer nie meer nie."\n\n"Wil jy dit toemaak?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Program herlei"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop nou."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> is oorspronklik laat loop."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2452a4a0a291..9b32c0d35c4a 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"ይሁን"</string>
<string name="report" msgid="4060218260984795706">"ሪፖርት"</string>
<string name="wait" msgid="7147118217226317732">"ቆይ"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"ገጹ ምላሽ የማይሰጥ ሆኗል።"\n\n"ልትዘጋው ትፈልጋለህ?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"መተግበሪያ አቅጣጫው ተቀይሯል"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> እየሄደ ነው።"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> በዋናነት የተነሳው።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 4c7a316bf58d..b8cd09428fe4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"موافق"</string>
<string name="report" msgid="4060218260984795706">"إرسال تقرير"</string>
<string name="wait" msgid="7147118217226317732">"انتظار"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"أصبحت الصفحة لا تستجيب."\n\n"هل تريد إغلاقها؟"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"تمت إعادة توجيه التطبيق"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> قيد التشغيل الآن."</string>
<string name="launch_warning_original" msgid="188102023021668683">"تم تشغيل <xliff:g id="APP_NAME">%1$s</xliff:g> من الأصل."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 0b40992621f0..84793246dc94 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -27,7 +27,7 @@
<string name="terabyteShort" msgid="231613018159186962">"Тб"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Пб"</string>
<string name="fileSizeSuffix" msgid="7670819340156489359">"запаўняльнік<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
- <!-- outdated translation 6071602020171759109 --> <string name="untitled" msgid="4638956954852782576">"Безназоўны"</string>
+ <string name="untitled" msgid="4638956954852782576">"&lt;Без назвы&gt;"</string>
<string name="ellipsis" msgid="7899829516048813237">"..."</string>
<string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
<string name="emptyPhoneNumber" msgid="7694063042079676517">"(Няма нумара тэлефона)"</string>
@@ -43,9 +43,9 @@
<string name="serviceErased" msgid="1288584695297200972">"Паспяхова выдалена."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Няправільны пароль."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI завершаны."</string>
- <!-- outdated translation 5085454289896032547 --> <string name="badPin" msgid="9015277645546710014">"Стары PIN-код уведзены няправільна."</string>
- <!-- outdated translation 5702522162746042460 --> <string name="badPuk" msgid="5487257647081132201">"Няправiльны PUK-код."</string>
- <!-- outdated translation 3695902225843339274 --> <string name="mismatchPin" msgid="609379054496863419">"Уведзеныя PIN-коды не супадаюць."</string>
+ <string name="badPin" msgid="9015277645546710014">"Стары PIN-код уведзены няправільна."</string>
+ <string name="badPuk" msgid="5487257647081132201">"Няправільны PUK-код."</string>
+ <string name="mismatchPin" msgid="609379054496863419">"Уведзеныя PIN-коды не супадаюць."</string>
<string name="invalidPin" msgid="3850018445187475377">"Увядзіце PIN-код, які змяшчае ад 4 да 8 лічбаў."</string>
<string name="invalidPuk" msgid="8761456210898036513">"Увядзіце PUK з 8 лічбаў ці больш."</string>
<string name="needPuk" msgid="919668385956251611">"Ваша SIM-карта заблакавана PUK-кодам. Увядзіце PUK, каб разблакаваць карту."</string>
@@ -68,16 +68,16 @@
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Па змаўчанні ідэнтыфікатар АВН не абмежаваны. Наступны выклік: абмежаваны"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Налады ідэнтыфікатару АВН па змаўчанні: не абмяжавана. Наступны выклік: не абмежавана"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Служба не прадастаўляецца."</string>
- <!-- outdated translation 5460892159398802465 --> <string name="CLIRPermanent" msgid="3377371145926835671">"Налада ідэнтыфікатару АВН не можа быць зменена."</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"Вы не можаце змяніць налады ідэнтыфікатара абанента, якi тэлефануе."</string>
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"Абмежаваны доступ змяніўся"</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"Служба дадзеных блакуецца."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Аварыйная служба блакуецца."</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"Галасавая служба заблакаваная."</string>
- <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Усе галасавыя службы заблакаваныя."</string>
+ <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Усе галасавыя службы заблакаваны."</string>
<string name="RestrictedOnSms" msgid="8314352327461638897">"Служба SMS заблакаваная."</string>
- <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Службы перадачы голаса і дадзеных заблакаваныя."</string>
+ <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Службы перадачы голаса/дадзеных заблакаваны."</string>
<string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Службы перадачы голаса і SMS заблакаваныя."</string>
- <string name="RestrictedOnAll" msgid="2714924667937117304">"Усе службы дадзеных, галасавыя і SMS-службы заблакаваныя."</string>
+ <string name="RestrictedOnAll" msgid="5643028264466092821">"Усе службы перадачы дадзеных, галасавыя і SMS-службы заблакаваны."</string>
<string name="serviceClassVoice" msgid="1258393812335258019">"Голас"</string>
<string name="serviceClassData" msgid="872456782077937893">"Дадзеныя"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"Факс"</string>
@@ -108,27 +108,27 @@
<string name="fcComplete" msgid="3118848230966886575">"Код аб\'екта завершаны."</string>
<string name="fcError" msgid="3327560126588500777">"Праблема падлучэння ці няправільны код функцыі."</string>
<string name="httpErrorOk" msgid="1191919378083472204">"ОК"</string>
- <string name="httpError" msgid="6603022914760066338">"Памылка сеткі."</string>
- <string name="httpErrorLookup" msgid="4517085806977851374">"URL не знойдзены."</string>
- <!-- outdated translation 2781440683514730227 --> <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Схема аўтэнтыфікацыі сайта не падтрымліваецца."</string>
- <string name="httpErrorAuth" msgid="7293960746955020542">"Няўдалая праверка на сапраўднасць."</string>
+ <string name="httpError" msgid="7956392511146698522">"Адбылася памылка сеткі."</string>
+ <string name="httpErrorLookup" msgid="4711687456111963163">"Не атрымалася знайсці URL."</string>
+ <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Схема аўтэнтыфікацыі сайта не падтрымліваецца."</string>
+ <string name="httpErrorAuth" msgid="1435065629438044534">"Памылка аўтэнтыфікацыі."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"Праверка сапраўднасці праз проксі-сервер скончылася няўдала."</string>
- <string name="httpErrorConnect" msgid="7623096283505770433">"Падключэнне да сервера не ўдалося."</string>
- <string name="httpErrorIO" msgid="4270874999047767599">"Сервер не можа ўсталяваць сувязь. Паспрабуйце пазней."</string>
+ <string name="httpErrorConnect" msgid="8714273236364640549">"Немагчыма падлучыцца да сервера."</string>
+ <string name="httpErrorIO" msgid="2340558197489302188">"Немагчыма звязацца з серверам. Паўтарыце спробу пазней."</string>
<string name="httpErrorTimeout" msgid="4743403703762883954">"Час чакання злучэння з серверам скончыўся."</string>
<string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Старонка змяшчае зашмат перанакіраванняў сервера."</string>
- <!-- outdated translation 5257172771607996054 --> <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Пратакол не падтрымліваецца."</string>
- <string name="httpErrorFailedSslHandshake" msgid="3088290300440289771">"Бяспечнае злучэнне ўсталяваць не ўдалося."</string>
- <string name="httpErrorBadUrl" msgid="6088183159988619736">"Старонка не можа быць адкрыта: несапраўдны URL."</string>
- <string name="httpErrorFile" msgid="8250549644091165175">"Немагчыма атрымаць доступ да файла."</string>
- <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Запатрабаваны файл не знойдзены."</string>
+ <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Пратакол не падтрымліваецца."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Немагчыма ўсталяваць бяспечнае злучэнне."</string>
+ <string name="httpErrorBadUrl" msgid="3636929722728881972">"Немагчыма адкрыць старонку, таму што URL несапраўдны."</string>
+ <string name="httpErrorFile" msgid="2170788515052558676">"Немагчыма атрымаць доступ да файла."</string>
+ <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Немагчыма знайсці патрабаваны файл."</string>
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Апрацоўваецца занадта шмат запытаў. Паспрабуйце яшчэ раз пазней."</string>
- <string name="notification_title" msgid="1259940370369187045">"Памылка ўваходу ў сістэму для ўліковага запісу <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+ <string name="notification_title" msgid="8967710025036163822">"Памылка ўваходу ва ўлiковы запiс <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"Сінхранізацыя"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Сінхранізацыя"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Занадта шмат выдаленняў <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
- <string name="low_memory" product="tablet" msgid="2292820184396262278">"Памяць планшэта поўная! Выдаліце ​​некаторыя файлы, каб вызваліць месца."</string>
- <string name="low_memory" product="default" msgid="6632412458436461203">"Памяць тэлефона поўная! Выдаліце ​​некаторыя файлы, каб вызваліць прастору."</string>
+ <string name="low_memory" product="tablet" msgid="6494019234102154896">"Памяць планшэта поўная. Выдаліце некаторыя файлы, каб вызваліць месца."</string>
+ <string name="low_memory" product="default" msgid="3475999286680000541">"Памяць тэлефона поўная. Выдаліце ​​некаторыя файлы, каб вызваліць месца."</string>
<string name="me" msgid="6545696007631404292">"Я"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Параметры планшэта"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Параметры тэлефона"</string>
@@ -137,12 +137,15 @@
<string name="turn_off_radio" msgid="8198784949987062346">"Адключыць бесправадную сетку"</string>
<string name="screen_lock" msgid="799094655496098153">"Блакіроўка экрана"</string>
<string name="power_off" msgid="4266614107412865048">"Выключыць"</string>
+ <string name="silent_mode_silent" msgid="319298163018473078">"Званок выкл."</string>
+ <string name="silent_mode_vibrate" msgid="7072043388581551395">"Званок з вібрацыяй"</string>
+ <string name="silent_mode_ring" msgid="8592241816194074353">"Званок укл."</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Выключэнне..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшэт будзе адключаны."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ваш тэлефон будзе выключаны."</string>
- <!-- outdated translation 6656441286856415014 --> <string name="shutdown_confirm_question" msgid="2906544768881136183">"Адключыць прыладу?"</string>
+ <string name="shutdown_confirm_question" msgid="2906544768881136183">"Закрыць?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Апошнія"</string>
- <!-- outdated translation 279702952298056674 --> <string name="no_recent_tasks" msgid="8794906658732193473">"Няма апошніх прыкладанняў."</string>
+ <string name="no_recent_tasks" msgid="8794906658732193473">"Няма апошніх прыкладанняў."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Параметры планшэта"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"Параметры тэлефона"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Блакіроўка экрана"</string>
@@ -157,16 +160,16 @@
<string name="safeMode" msgid="2788228061547930246">"Бяспечны рэжым"</string>
<string name="android_system_label" msgid="6577375335728551336">"Сістэма Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Платныя паслугі"</string>
- <!-- outdated translation 8193824940620517189 --> <string name="permgroupdesc_costMoney" msgid="8596717365335027057">"Дазволіць прыкладанням рабіць рэчы, якія могуць каштаваць вам грошай."</string>
+ <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Рабіць справы, якія могуць каштаваць вам грошай."</string>
<string name="permgrouplab_messages" msgid="7521249148445456662">"Вашыя паведамленні"</string>
- <!-- outdated translation 7045736972019211994 --> <string name="permgroupdesc_messages" msgid="7821999071003699236">"Чытайце і пішыце вашыя паведамленні электроннай пошты, SMS і г. д."</string>
+ <string name="permgroupdesc_messages" msgid="7821999071003699236">"Счытваць і запісваць вашы SMS-паведамленні, паведамленні электроннай пошты і іншыя паведамленні."</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Вашая персанальная інфармацыя"</string>
<string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Прамы доступ да кантактаў і календара, якія захоўваюцца на планшэце."</string>
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Прамы доступ да кантактаў і календара, захаваных на тэлефоне."</string>
<string name="permgrouplab_location" msgid="635149742436692049">"Ваша месцазнаходжанне"</string>
- <string name="permgroupdesc_location" msgid="2430258821648348660">"Кантралюйце сваё фізічнае месцазнаходжанне"</string>
+ <string name="permgroupdesc_location" msgid="5704679763124170100">"Кантраляваць сваё фізічнае месцазнаходжанне."</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"Сеткавая сувязь"</string>
- <!-- outdated translation 5035763698958415998 --> <string name="permgroupdesc_network" msgid="4917593670797570584">"Дазволіць прыкладанням атрымліваць доступ да розных функцый сеткі."</string>
+ <string name="permgroupdesc_network" msgid="4478299413241861987">"Доступ да розных функцый сеткі."</string>
<string name="permgrouplab_accounts" msgid="3359646291125325519">"Вашыя ўліковыя запісы"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Доступ да дзеючых уліковых запісаў."</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Кіраванне апаратным забеспячэннем"</string>
@@ -176,352 +179,358 @@
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"Сістэмныя інструменты"</string>
<string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Ніжні ўзровень доступу і кіравання сістэмай."</string>
<string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Сродкі распрацоўкі"</string>
- <!-- outdated translation 9056431193893809814 --> <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Функцыі, патрэбныя толькі для распрацоўшчыкаў прыкладанняў."</string>
+ <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Функцыi, патрэбныя толькі для распрацоўшчыкаў прыкладанняў."</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Сховішча"</string>
<string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Атрымаць доступ да USB-назапашвальнiка."</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Доступ да SD-карты."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"адключаць ці змяняць радок стану"</string>
- <!-- outdated translation 1365473595331989732 --> <string name="permdesc_statusBar" msgid="8434669549504290975">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string>
+ <string name="permdesc_statusBar" msgid="8434669549504290975">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"радок стану"</string>
- <!-- outdated translation 4097605867643520920 --> <string name="permdesc_statusBarService" msgid="716113660795976060">"Дазваляе прыкладанням быць радком стану."</string>
+ <string name="permdesc_statusBarService" msgid="716113660795976060">"Дазваляе прыкладанням быць радком стану."</string>
<string name="permlab_expandStatusBar" msgid="1148198785937489264">"разгарнуць/згарнуць радок стану"</string>
- <!-- outdated translation 7088604400110768665 --> <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Дазваляе прыкладанням разгортваць або згортваць панэль стану."</string>
+ <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Дазваляе прыкладанню разгортваць ці згортваць радок стану."</string>
<string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"перахапляць выходныя выклікі"</string>
- <!-- outdated translation 2228988201852654461 --> <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"Дазваляе прыкладанням апрацоўваць выходныя выклікі і змяняць набіраны нумар. Шкоднасныя прыкладанні могуць адсочваць, перанакіроўваць ці забараняць выходныя выклікі."</string>
+ <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"Дазваляе прыкладанням апрацоўваць выходныя выклікі і змяняць набіраны нумар. Шкоднасныя прыкладаннi могуць адсочваць, перанакіроўваць ці прадухіляць выходныя выклікі."</string>
<string name="permlab_receiveSms" msgid="2697628268086208535">"атрымліваць SMS"</string>
- <!-- outdated translation 6298292335965966117 --> <string name="permdesc_receiveSms" msgid="8107887121893611793">"Дазваляе прыкладанням атрымліваць і апрацоўваць SMS. Шкоднасныя прыкладанні могуць адсочваць вашыя паведамленні або выдаляць іх, не паказваючы вам."</string>
+ <string name="permdesc_receiveSms" msgid="8107887121893611793">"Дазваляе прыкладанням атрымліваць і апрацоўваць SMS-паведамленні. Шкоднасныя прыкладанні могуць адсочваць вашыя паведамленні або выдаляць іх, не паказваючы вам."</string>
<string name="permlab_receiveMms" msgid="8894700916188083287">"атрымліваць MMS"</string>
- <!-- outdated translation 4563346832000174373 --> <string name="permdesc_receiveMms" msgid="1424805308566612086">"Дазваляе прыкладанням атрымліваць і апрацоўваць паведамленні MMS. Шкоднасныя прыкладанні могуць адсочваць вашыя паведамленні або выдаляць іх без вашага ведама."</string>
+ <string name="permdesc_receiveMms" msgid="1424805308566612086">"Дазваляе прыкладанням атрымліваць і апрацоўваць MMS-паведамленні. Шкоднасныя прыкладанні могуць адсочваць вашы паведамленні або выдаляць іх, не паказваючы вам."</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"атрымліваць экстраныя трансляцыі"</string>
- <!-- outdated translation 7118393393716546131 --> <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Дазваляе прыкладанням атрымліваць і апрацоўваць экстраныя шырокавяшчальныя паведамленні. Гэты дазвол даступны толькі для сістэмных прыкладанняў."</string>
+ <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Дазваляе прыкладанням атрымліваць і апрацоўваць экстраныя паведамленні. Гэты дазвол даступны толькі для сістэмных прыкладанняў."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"адпраўляць SMS"</string>
- <!-- outdated translation 1946540351763502120 --> <string name="permdesc_sendSms" msgid="906546667507626156">"Дазваляе прыкладанням адпраўляць SMS. Шкоднасныя прыкладанні могуць траціць вашыя грошы шляхам адпраўкі паведамленняў без пацверджання карыстальніка."</string>
+ <string name="permdesc_sendSms" msgid="906546667507626156">"Дазваляе прыкладанням дасылаць SMS-паведамленні. Шкоднасныя прыкладанні могуць каштаваць вам грошай з-за адпраўкі паведамленняў без вашага пацвярджэння."</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"адпраўляць SMS-паведамленні без пацверджання"</string>
- <!-- outdated translation 4477752891276276168 --> <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Дазваляе прыкладанням адпраўляць SMS. Шкоднасныя прыкладанні могуць спісваць вашыя грошы, адпраўляючы паведамленні без вашага пацверджання."</string>
+ <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Дазваляе прыкладанню дасылаць SMS-паведамленні. Шкоднасныя прыкладанні могуць каштаваць вам грошай з-за адпраўкі паведамленняў без вашага пацверджання."</string>
<string name="permlab_readSms" msgid="4085333708122372256">"чытаць SMS або MMS"</string>
- <!-- outdated translation 5836710350295631545 --> <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Дазваляе прыкладанням чытаць SMS, якія захоўваюцца на планшэце ці на SIM-карце. Шкоднасныя прыкладанні могуць чытаць вашыя канфідэнцыйныя паведамленні."</string>
- <!-- outdated translation 5836710350295631545 --> <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Дазваляе прыкладанням чытаць SMS, якія захоўваюцца на планшэце ці на SIM-карце. Шкоднасныя прыкладанні могуць чытаць вашыя канфідэнцыйныя паведамленні."</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Дазваляе прыкладанням чытаць SMS-паведамленні, якія захоўваюцца на планшэце ці SIM-карце. Шкоднасныя прыкладанні могуць чытаць вашы канфідэнцыйныя паведамленні."</string>
+ <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Дазваляе прыкладанню счытваць SMS-паведамленні, якія захоўваюцца ў тэлефоне або на SIM-карце. Шкоднасныя прыкладанні могуць чытаць вашы канфідэнцыйныя паведамленні."</string>
<string name="permlab_writeSms" msgid="6881122575154940744">"рэдагаваць SMS ці MMS"</string>
- <!-- outdated translation 5332124772918835437 --> <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Дазваляе прыкладанню запіс ў SMS паведамленнях, якія захоўваюцца на планшэце ці на SIM-карце. Шкоднасныя прыкладанні могуць выдаляць вашыя паведамленні."</string>
- <!-- outdated translation 5332124772918835437 --> <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Дазваляе прыкладанню запіс ў SMS паведамленнях, якія захоўваюцца на планшэце ці на SIM-карце. Шкоднасныя прыкладанні могуць выдаляць вашыя паведамленні."</string>
+ <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Дазваляе прыкладанню запісваць дадзеныя ў SMS-паведамленні, якія захоўваюцца на планшэце або на SIM-карце. Шкоднасныя прыкладанні могуць выдаляць вашы паведамленні."</string>
+ <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Дазваляе прыкладанням запісваць дадзеныя ў SMS-паведамленні, якія захоўваюцца ў тэлефоне або на SIM-карце. Шкоднасныя прыкладанні могуць выдаляць вашы паведамленні."</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"атрымліваць WAP"</string>
- <!-- outdated translation 5979623826128082171 --> <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Дазваляе прыкладанням атрымліваць і апрацоўваць WAP-паведамленні. Шкоднасныя прыкладанні могуць адсочваць вашыя паведамленні або выдаляць іх, не паказваючы вам."</string>
- <!-- outdated translation 5005277531132573353 --> <string name="permlab_getTasks" msgid="6466095396623933906">"атрымліваць запушчаныя прыкладанні"</string>
- <!-- outdated translation 7048711358713443341 --> <string name="permdesc_getTasks" msgid="6608159250520381359">"Дазваляе прыкладанням атрымліваць інфармацыю аб бягучых і нядаўна запушчаных задачах. Можа дазволіць шкоднасным прыкладаннм выяўляць асабістую інфармацыю аб іншых прыкладаннях."</string>
- <!-- outdated translation 5669588525059921549 --> <string name="permlab_reorderTasks" msgid="2018575526934422779">"змяняць парадак запуску прыкладанняў"</string>
- <!-- outdated translation 126252774270522835 --> <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Дазваляе прыкладанням перамяшчаць задачы на ​​пярэдні план і ў фон. Шкоднасныя прыкладанні могуць прымусова перамясціць сябе на ​​пярэдні план без вашага кантролю."</string>
- <!-- outdated translation 4802740047161700683 --> <string name="permlab_removeTasks" msgid="6821513401870377403">"спыненне запушчаных прыкладанняў"</string>
- <!-- outdated translation 2000332928514575461 --> <string name="permdesc_removeTasks" msgid="1000226123143185094">"Дазваляе прыкладанням выдаляць задачы і спыняць адпаведныя прыкладанні. Шкоднасныя прыкладаннi могуць паўплываць на функцыянаванне іншых прыкладанняў."</string>
- <!-- outdated translation 4339730312925176742 --> <string name="permlab_setDebugApp" msgid="3022107198686584052">"уключаць адладку прыкладанняў"</string>
- <!-- outdated translation 5584310661711990702 --> <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Дазваляе прыкладанням уключаць адладку іншых прыкладанняў. Шкоднасныя прыкладаннi могуць карыстацца гэтым, каб спыняць іншыя прыкладанні."</string>
+ <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Дазваляе прыкладанням атрымліваць і апрацоўваць WAP-паведамленні. Шкоднасныя прыкладанні могуць адсочваць вашы паведамленні або выдаляць іх, не паказваючы вам."</string>
+ <string name="permlab_getTasks" msgid="6466095396623933906">"атрымаць запушчаныя прыкладанні"</string>
+ <string name="permdesc_getTasks" msgid="6608159250520381359">"Дазваляе прыкладанням атрымліваць інфармацыю пра бягучыя і нядаўна запушчаныя заданнi. Шкоднасныя прыкладанні могуць атрымліваць асабістую інфармацыю пра іншыя прыкладаннi."</string>
+ <string name="permlab_reorderTasks" msgid="2018575526934422779">"змяніць парадак запушчаных прыкладанняў"</string>
+ <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Дазваляе прыкладанням перамяшчаць заданні на ​​пярэдні план і фон. Шкоднасныя прыкладанні могуць прымусова рабіць сябе асноўнымі без вашага ведама."</string>
+ <string name="permlab_removeTasks" msgid="6821513401870377403">"спыніць запушчаныя прыкладанні"</string>
+ <string name="permdesc_removeTasks" msgid="1394714352062635493">"Дазваляе прыкладанням выдаляць заданні і спыняць прыкладанні, якія іх выкарыстоўваюць. Шкоднасныя прыкладаннi могуць перашкодзiць працы іншых прыкладанняў."</string>
+ <string name="permlab_setDebugApp" msgid="3022107198686584052">"уключыць адладку прыкладання"</string>
+ <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Дазваляе прыкладанням уключаць адладку для іншага прыкладання. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб спыняць іншыя прыкладанні."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"змяняць налады карыстальніцкага інтэрфейса"</string>
- <!-- outdated translation 3465121501528064399 --> <string name="permdesc_changeConfiguration" msgid="4104052649900380324">"Дазваляе прыкладанням змяняць бягучую канфігурацыю, напрыклад мову i агульны памер шрыфта."</string>
+ <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Дазваляе прыкладанням змяняць бягучую канфігурацыю, напрыклад мову цi агульны памер шрыфта."</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"дазваляць рэжым \"У аўтамабілі\""</string>
- <!-- outdated translation 5673461159384850628 --> <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Дазваляе прыкладанням уключаць рэжым \"У аўтамабілі\"."</string>
+ <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Дазваляе прыкладанню ўключаць рэжым гучнай сувязi."</string>
<string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"выдаліць фонавыя працэсы"</string>
- <!-- outdated translation 2908829602869383753 --> <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Дазваляе прыкладанням спыняць фонавыя працэсы іншых прыкладанняў, нават калі памяці дастаткова."</string>
- <!-- outdated translation 1447830113260156236 --> <string name="permlab_forceStopPackages" msgid="2329627428832067700">"прымусова спыняць іншыя прыкладанні"</string>
- <!-- outdated translation 7263036616161367402 --> <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Дазваляе прыкладанню прымусова спыняць іншыя прыкладанні."</string>
- <!-- outdated translation 1804196839880393631 --> <string name="permlab_forceBack" msgid="652935204072584616">"прымусова закрываць прыкладанні"</string>
- <!-- outdated translation 6534109744159919013 --> <string name="permdesc_forceBack" msgid="3892295830419513623">"Дазваляе прыкладанням прымусова спыняць усе актыўныя працэсы і працягваць працу. Ніколі не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Дазваляе прыкладанням спыняць фонавыя працэсы іншых прыкладанняў, нават калі памяці дастаткова."</string>
+ <string name="permlab_forceStopPackages" msgid="2329627428832067700">"прымусова спыніць іншыя прыкладанні"</string>
+ <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Дазваляе прыкладанням прымусова спыняць іншыя прыкладанні."</string>
+ <string name="permlab_forceBack" msgid="652935204072584616">"прымусова закрыць прыкладанне"</string>
+ <string name="permdesc_forceBack" msgid="3892295830419513623">"Дазваляе прыкладанням прымусова закрываць любы асноўны працэс. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_dump" msgid="1681799862438954752">"атрымліваць унутраны стан сістэмы"</string>
- <!-- outdated translation 2198776174276275220 --> <string name="permdesc_dump" msgid="1778299088692290329">"Дазваляе прыкладанням атрымліваць інфармацыю аб унутраным стане сістэмы. Шкодныя прыкладанні могуць атрымлiваць шырокі спектр прыватнай і абараняемай інфармацыі, якая звычайна ніколі ім не патрабуецца."</string>
+ <string name="permdesc_dump" msgid="1778299088692290329">"Дазваляе прыкладанням атрымліваць інфармацыю аб унутраным стане сістэмы. Шкоднасныя прыкладанні могуць атрымліваць шырокі спектр прыватных дадзеных і дадзеных, прызначаных для забеспячэння бяспекі інфармацыі, якія звычайна ім не патрэбны."</string>
<string name="permlab_retrieve_window_content" msgid="8022588608994589938">"атрыманне зместу экрана"</string>
- <!-- outdated translation 3390962289797156152 --> <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Дазваляе прыкладанням атрымліваць змест актыўнага акна. Шкоднасныя прыкладаннi могуць атрымаць увесь змест акна і вывучыць увесь яго тэкст, акрамя пароляў."</string>
+ <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Дазваляе прыкладанням атрымліваць змесціва актыўнага акна. Шкоднасныя прыкладанні могуць атрымліваць усё змесціва акна і разглядаць увесь яго тэкст, акрамя пароляў."</string>
<string name="permlab_shutdown" msgid="7185747824038909016">"частковае адключэнне"</string>
<string name="permdesc_shutdown" msgid="7046500838746291775">"Спыняе дзейнасць менеджэра. Не выконвае поўнае адключэнне."</string>
<string name="permlab_stopAppSwitches" msgid="4138608610717425573">"прадухіляць пераключэнне прыкладанняў"</string>
- <!-- outdated translation 3857886086919033794 --> <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Прадухіляе карыстальнікаў ад пераходу на іншае прыкладанне."</string>
- <!-- outdated translation 7811586187574696296 --> <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"адсочваць усе запускі прыкладанняў і кіраваць iмi"</string>
- <!-- outdated translation 2149363027173451218 --> <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дазваляе прыкладанню сачыць за тым, як сістэма запускае працэсы, i кiраваць гэтым дзеяннем. Шкоднасныя прыкладанні могуць цалкам негатыўна паўсплываць на сістэму. Гэты дазвол неабходны толькі для распрацоўкі, не для звычайнага выкарыстання."</string>
+ <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Не дазваляе карыстальніку пераходзіць да іншага прыкладання."</string>
+ <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"адсочваць і кантраляваць запуск усіх прыкладанняў"</string>
+ <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дазваляе прыкладанню сачыць і кантраляваць, як сістэма запускае працэсы. Шкоднасныя прыкладанні могуць цалкам парушыць працу сістэмы. Гэты дазвол патрэбны толькі для распрацоўкі, ніколі для звычайнага выкарыстання."</string>
<string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"трансляваць паведамленні аб выдаленні пакетаў"</string>
- <!-- outdated translation 3453286591439891260 --> <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Дазваляе прыкладанням трансліраваць апавяшчэнне аб тым, што пакет прыкладання быў выдалены. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб спыніць любое іншае запушчанае прыкладанне."</string>
+ <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Дазваляе прыкладанням перадаваць апавяшчэнне, што пакет прыкладанняў быў выдалены. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб спыняць любыя іншыя запушчаныя прыкладанні."</string>
<string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"перасылаць трансляцыі, атрыманыя па SMS"</string>
- <!-- outdated translation 9122419277306740155 --> <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Дазваляе прыкладанню трансляваць апавяшчэнне, што паведамленне SMS атрыманае. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб падрабляць уваходныя паведамленні SMS."</string>
+ <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Дазваляе прыкладанням перадаваць апавяшчэнне пра атрыманне SMS-паведамлення. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб падрабляць уваходныя SMS-паведамленні."</string>
<string name="permlab_broadcastWapPush" msgid="3145347413028582371">"пасылаць сігнал WAP-PUSH-received"</string>
- <!-- outdated translation 3955303669461378091 --> <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Дазваляе прыкладанням трансляваць апавяшчэнне аб атрыманні паведамлення WAP PUSH. Шкоднасныя прыкладаннi могуць карыстацца гэтым, каб падрабляць атрыманне MMS-паведамленняў ці моўчкі мяняць змест любых вэб-старонак на шкодны."</string>
+ <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Дазваляе прыкладанням перадаваць апавяшчэнне, што паведамленне WAP PUSH не было атрымана. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб падрабляць атрыманне MMS-паведамлення або непрыкметна замяняць змесціва любой вэб-старонкі на шкоднасную версiю."</string>
<string name="permlab_setProcessLimit" msgid="2451873664363662666">"абмяжоўваць колькасць запушчаных працэсаў"</string>
- <!-- outdated translation 7824786028557379539 --> <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Дазваляе прыкладанням кантраляваць максімальную колькасць працэсаў, якія будуць працаваць. Ніколі не патрабуецца для звычайных прыкладанняў."</string>
- <!-- outdated translation 5342837862439543783 --> <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"закрываць усе фонавыя прыкладанні"</string>
- <!-- outdated translation 8773936403987091620 --> <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Дазваляе прыкладанню кантраляваць завяршэнне дзеянняў падчас іх пераходу ў фон. Ніколі не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Дазваляе прыкладанням кантраляваць максімальную колькасць запушчаных працэсаў. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"закрывае ўсе фонавыя прыкладанні"</string>
+ <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Дазваляе прыкладанням кантраляваць, ці будуць працэсы заўсёды завяршацца, як толькі яны пераходзяць у фонавы рэжым. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_batteryStats" msgid="7863923071360031652">"змяняць статыстыку батарэі"</string>
- <!-- outdated translation 5847319823772230560 --> <string name="permdesc_batteryStats" msgid="6835186932305744068">"Дазваляе мяняць сабраную статыстыку акумулятара. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_batteryStats" msgid="6835186932305744068">"Дазваляе прыкладанням змяняць сабраную статыстыку акумулятара. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_backup" msgid="470013022865453920">"кантраляваць рэзервовае капіяванне і аднаўленне сістэмы"</string>
- <!-- outdated translation 4837493065154256525 --> <string name="permdesc_backup" msgid="6912230525140589891">"Дазваляе прыкладанням кантраляваць механізм рэзервовага капіявання і аднаўлення сістэмы. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_backup" msgid="6912230525140589891">"Дазваляе прыкладанням кантраляваць рэзервовае капіяванне сістэмы і механізм аднаўлення. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"пацверджанне поўнага рэзервовага капіявання або аднаўлення"</string>
- <!-- outdated translation 9005017754175897954 --> <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Дазваляе прыкладанням запускаць інтэрфейс пацверджання поўнага рэзервовага капіявання. Выкарыстоўваецца не ўсімі прыкладаннямі."</string>
+ <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Дазваляе прыкладанням запускаць поўны інтэрфейс карыстальніка пацвярджэння рэзервавання. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"паказваць несанкцыянаваныя вокны"</string>
- <!-- outdated translation 5895082268284998469 --> <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Дазваляе ствараць вокны, прызначаныя для ўнутранай сістэмы карыстальніцкага інтэрфейса. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Дазваляе прыкладанням ствараць вокны, прызначаныя для выкарыстання ўнутраным інтэрфейсам карыстальніка сістэмы. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_systemAlertWindow" msgid="3372321942941168324">"паказваць абвесткі стану сістэмы"</string>
- <!-- outdated translation 2884149573672821318 --> <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Дазваляе прыкладанню паказваць вокны сiстэмных паведамленняў. Шкоднасныя прыкладанні могуць заняць увесь экран."</string>
+ <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Дазваляе прыкладанням паказваць вокны апавяшчэння сістэмы. Шкоднасныя прыкладанні могуць захоплiваць увесь экран."</string>
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"зменяць агульную хуткасць анімацыі"</string>
- <!-- outdated translation 7181522138912391988 --> <string name="permdesc_setAnimationScale" msgid="6505093307223395456">"Дазваляе прыкладанням у любы час мяняць агульную хуткасць анімацыі (хутчэй ці павольней)."</string>
- <!-- outdated translation 17124341698093865 --> <string name="permlab_manageAppTokens" msgid="1286505717050121370">"кіраваць меткамі прыкладанняў"</string>
- <!-- outdated translation 977127907524195988 --> <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Дазваляе прыкладанням ствараць уласныя квіткі і кіраваць імі, у абыход нармальнага Z-упарадкавання. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Дазваляе прыкладанням у любы час змяняць агульную хуткасць анімацыі (хутчэй ці павольней)."</string>
+ <string name="permlab_manageAppTokens" msgid="1286505717050121370">"кіраваць ключамі прыкладання"</string>
+ <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Дазваляе прыкладанням ствараць сваімі ўласнымі ключамі, абыходзячы іх звычайны Z-парадак. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_injectEvents" msgid="1378746584023586600">"націскаць клавішы і кнопкі кіравання"</string>
- <!-- outdated translation 7200014808195664505 --> <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Дазваляе прыкладанням ажыццяўляць свае ўласныя працэсы ўводу (націску клавіш і г. д.) для іншых прыкладанняў. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб атрымаць кантроль над планшэтам."</string>
- <!-- outdated translation 7200014808195664505 --> <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Дазваляе прыкладанням ажыццяўляць свае ўласныя працэсы ўводу (націску клавіш і г. д.) для іншых прыкладанняў. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб атрымаць кантроль над планшэтам."</string>
+ <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Дазваляе прыкладанням ажыццяўляць свае ўласныя падзеі ўводу (націску клавіш і г.д.) для іншых прыкладанняў. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб захапіць кіраванне планшэтам."</string>
+ <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Дазваляе прыкладанню ажыццяўляць свае ўласныя падзеі ўводу (націску клавіш і г. д.) для іншых прыкладанняў. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб захапіць кіраванне тэлефонам."</string>
<string name="permlab_readInputState" msgid="469428900041249234">"запісваць, што вы друкуеце, і дзеянні, якія вы прадпрымаеце"</string>
- <!-- outdated translation 5132879321450325445 --> <string name="permdesc_readInputState" msgid="8387754901688728043">"Дазваляе прыкладанням праглядаць клавішы, якія вы націскаеце, нават пры ўзаемадзеянні з іншым прыкладаннем (напрыклад, пры ўводзе пароля). Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_readInputState" msgid="8387754901688728043">"Дазваляе прыкладанням адсочваць клавішы, якія вы націскаеце, нават падчас узаемадзеяння з іншым прыкладаннем (напрыклад, пры ўводзе пароля). Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"звязацца з метадам уводу"</string>
- <!-- outdated translation 3734838321027317228 --> <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дазваляе ўладальніку звязвацца з інтэрфейсам верхняга ўзроўню метадам уводу. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню метада ўводу. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"звязаць з тэкставай службай"</string>
- <!-- outdated translation 172508880651909350 --> <string name="permdesc_bindTextService" msgid="8151968910973998670">"Дазваляе ўладальніку звязвацца з інтэрфейсам верхняга ўзроўню тэкставай паслугі (напрыклад, SpellCheckerService). Ніколі не патрабуецца звычайным прыкладанням."</string>
+ <string name="permdesc_bindTextService" msgid="8151968910973998670">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню тэкставай паслугі (напрыклад, SpellCheckerService). Ніколі не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"звязвацца з VPN сэрвісам"</string>
- <!-- outdated translation 6011554199384584151 --> <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Дазваляе ўладальніку звязвацца з інтэрфейсам VPN службы вышэйшага ўзроўню. Не патрэбна для звычайных праграм."</string>
+ <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Дазваляе ўладальніку звязвацца з інтэрфейсам службы VPN вышэйшага ўзроўню. Не патрэбна для звычайных прыкладанняў."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"прывязаць да шпалер"</string>
- <!-- outdated translation 5287754520361915347 --> <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Дазваляе ўладальніку ўсталёўваць прывязку да інтэрфейсу шпалер верхняга ўзроўню. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Дазваляе ўладальніку ўсталёўваць прывязку да інтэрфейсу шпалер верхняга ўзроўню. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"прывязаць да службы віджэту"</string>
- <!-- outdated translation 2930855984822926963 --> <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дазваляе ўладальніку прывязаць верхні ўзровень інтэрфейсу службы віджэта. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню службы віджэта. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"узаемадзейнічаць з адміністратарам прылады"</string>
- <!-- outdated translation 8714424333082216979 --> <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Дазваляе ўладальніку адпраўляць намеры да адміністратара прылады. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Дазваляе ўладальніку адпраўляць намеры да адміністратара прылады. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"змяняць арыентацыю экрана"</string>
- <!-- outdated translation 6335814461615851863 --> <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дазваляе прыкладанням мяняць арыентацыю экрана ў любы час. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_setOrientation" msgid="3046126619316671476">"Дазваляе прыкладанням змяняць паварот экрана ў любы час. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"змена хутк. перамяшч. ўказ."</string>
- <!-- outdated translation 137436038503379864 --> <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дазваляе прыкладанням у любы момант мяняць хуткасць перамяшчэння ўказальніка мышы ці трэкпаду. Не патрабуецца для звычайных прыкладанняў."</string>
- <!-- outdated translation 4255467255488653854 --> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"адпраўляць сігналы Linux да прыкладанняў"</string>
- <!-- outdated translation 3565530463215015289 --> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дазваляе прыкладанням запытваць адпраўку прадстаўленага сігналу да ўсіх пастаянных працэсаў."</string>
- <!-- outdated translation 8659652042401085862 --> <string name="permlab_persistentActivity" msgid="8841113627955563938">"прымусіць прыкладанне працаваць заўсёды"</string>
- <!-- outdated translation 5037199778265006008 --> <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Дазваляе прыкладанням рабіць свае часткі ўстойлівымі, каб сістэма не магла выкарыстоўваць іх для іншых прыкладанняў."</string>
- <!-- outdated translation 3343439331576348805 --> <string name="permlab_deletePackages" msgid="184385129537705938">"выдаляць прыкладанні"</string>
- <!-- outdated translation 3634943677518723314 --> <string name="permdesc_deletePackages" msgid="7411480275167205081">"Дазваляе прыкладанням выдаляць пакеты Android. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб выдаляць важныя прыкладанні."</string>
- <!-- outdated translation 2192134353540277878 --> <string name="permlab_clearAppUserData" msgid="274109191845842756">"выдаляць дадзеныя іншых прыкладанняў"</string>
- <!-- outdated translation 7546345080434325456 --> <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Дазваляе прыкладанням выдаляць дадзеныя карыстальніка."</string>
- <!-- outdated translation 1518556602634276725 --> <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"выдаляць кэш іншых прыкладанняў"</string>
- <!-- outdated translation 2283074077168165971 --> <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Дазваляе прыкладанням выдаляць файлы кэша."</string>
- <!-- outdated translation 4799785352306641460 --> <string name="permlab_getPackageSize" msgid="7472921768357981986">"мераць месца для захоўвання прыкладання"</string>
- <!-- outdated translation 5557253039670753437 --> <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Дазваляе прыкладанням атрымліваць свой код, дадзеныя і аб\'ём кэш-памяці"</string>
- <!-- outdated translation 335800214119051089 --> <string name="permlab_installPackages" msgid="2199128482820306924">"непасрэдна ўсталёўваць прыкладанні"</string>
- <!-- outdated translation 526669220850066132 --> <string name="permdesc_installPackages" msgid="5628530972548071284">"Дазваляе прыкладанням усталёўваць новыя або абноўленыя пакеты Android. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб дадаваць новыя прыкладанні з дазволамі высокага ўзроўню."</string>
- <!-- outdated translation 4747698311163766540 --> <string name="permlab_clearAppCache" msgid="7487279391723526815">"выдаляць усе дадзеныя кэша прыкладання"</string>
- <!-- outdated translation 3097119797652477973 --> <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Дазваляе прыкладанню вызваліць прастору на планшэце, выдаліўшы файлы з каталогу кэша прыкладання. Доступ да сістэмных працэсаў звычайна вельмі абмежаваны."</string>
- <!-- outdated translation 3097119797652477973 --> <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Дазваляе прыкладанню вызваліць прастору на планшэце, выдаліўшы файлы з каталогу кэша прыкладання. Доступ да сістэмных працэсаў звычайна вельмі абмежаваны."</string>
- <!-- outdated translation 728454979946503926 --> <string name="permlab_movePackage" msgid="3289890271645921411">"Перамяшчэнне рэсурсаў прыкладання"</string>
- <!-- outdated translation 6323049291923925277 --> <string name="permdesc_movePackage" msgid="319562217778244524">"Дазваляе прыкладанню перамяшчаць рэсурсы прыкладання з унутранай памяці на знешні носьбіт і наадварот."</string>
+ <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Дазваляе прыкладанням змяняць хуткасць курсору мышы або трэкпада ў любы час. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"адправіць сігналы Linux да прыкладанняў"</string>
+ <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Дазваляе прыкладанням запытваць адпраўку падаваемага сігнала для ўсiх пастаянных працэсаў."</string>
+ <string name="permlab_persistentActivity" msgid="8841113627955563938">"прымусіць прыкладанне працаваць заўсёды"</string>
+ <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Дазваляе прыкладанням рабіць свае часткі пастаяннымі, каб сістэма не магла выкарыстоўваць iх для іншых прыкладанняў."</string>
+ <string name="permlab_deletePackages" msgid="184385129537705938">"выдаліць прыкладанні"</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"Дазваляе прыкладанню выдаляць пакеты Android. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб выдаляць важныя прыкладанні."</string>
+ <string name="permlab_clearAppUserData" msgid="274109191845842756">"выдаліць дадзеныя іншых прыкладанняў"</string>
+ <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Дазваляе прыкладанням выдаляць дадзеныя карыстальніка."</string>
+ <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"выдаліць кэш-памяць іншых прыкладанняў"</string>
+ <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Дазваляе прыкладанню выдаляць файлы кэш-памяці."</string>
+ <string name="permlab_getPackageSize" msgid="7472921768357981986">"вымерыць прастору для захоўвання прыкладання"</string>
+ <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Дазваляе прыкладанням атрымліваць яго код, дадзеныя і аб\'ём кэш-памяці"</string>
+ <string name="permlab_installPackages" msgid="2199128482820306924">"усталяваць прыкладанні непасрэдна"</string>
+ <string name="permdesc_installPackages" msgid="5628530972548071284">"Дазваляе прыкладанням ксталёўваць новыя або абноўленыя пакеты Android. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб дадаваць новыя прыкладаннi з дазволамі адвольнай ступені."</string>
+ <string name="permlab_clearAppCache" msgid="7487279391723526815">"выдаліць усе дадзеныя з кэш-памяці прыкладання"</string>
+ <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Дазваляе прыкладанню вызваляць памяць планшэту, выдаляючы файлы ў каталогу кэш-памяці прыкладання. Як правіла, доступ да сістэмных працэсаў вельмі абмежаваны."</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Дазваляе прыкладанням вызваляць памяць тэлефона, выдаляючы файлы з каталогу кэш-памяці прыкладання. Доступ да сістэмных працэсаў, як правіла, вельмі абмежаваны."</string>
+ <string name="permlab_movePackage" msgid="3289890271645921411">"перамясціць рэсурсы прыкладання"</string>
+ <string name="permdesc_movePackage" msgid="319562217778244524">"Дазваляе прыкладанням перамяшчаць рэсурсы прыкладання з унутраных на знешнія носьбіты і наадварот."</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"чытаць канфідэнцыйныя дадзеныя дзённiка"</string>
- <!-- outdated translation 4077356893924755294 --> <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Дазваляе прыкладанням чытаць розныя файлы журналаў сістэмы. Такiм чынам можна выявiць агульную інфармацыю аб тым, што вы робіце з планшэтам, якая патэнцыйна змяшчае асабістыя або канфiдэнцыйныя звесткi."</string>
- <!-- outdated translation 4077356893924755294 --> <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дазваляе прыкладанням чытаць розныя файлы журналаў сістэмы. Такiм чынам можна выявiць агульную інфармацыю аб тым, што вы робіце з планшэтам, якая патэнцыйна змяшчае асабістыя або канфiдэнцыйныя звесткi."</string>
+ <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Дазваляе прыкладанням счытваць розныя файлы сiстэмнай гiсторыi. Такiм чынам, можна выявiць агульную інфармацыю пра тое, што вы робіце з планшэтам, у тым ліку, магчыма, асабістыя або канфiдэнцыйныя звесткi."</string>
+ <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дазваляе прыкладанню счытваць розныя сістэмныя файлы гiсторый. Гэта дазваляе атрымліваць агульную інфармацыю аб тым, як выкарыстоўваецца тэлефон, у тым ліку, магчыма, асабістую або прыватную інфармацыю."</string>
+ <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"для прайгравання выкарыстоўваць любы мультымедыйны дэкодэр"</string>
+ <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Дазваляе прыкладанням выкарыстоўваць любы ўсталяваны iнструмент для мультымедыйнага дэкадавання, каб прайграць."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"чытаць/запісваць на дыягнастычныя рэсурсы"</string>
- <!-- outdated translation 3121238373951637049 --> <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дазваляе прыкладанням счытваць і запісваць любы рэсурс, які належыць дыягнастычнай групе, напрыклад файлы распрацоўшчыка. Патэнцыйна гэта можа паўплываць на стабільнасць і бяспеку сістэмы. Гэта павінна выкарыстоўвацца ТОЛЬКІ для апаратнай дыягностыкі вытворцам або аператарам."</string>
- <!-- outdated translation 79425198834329406 --> <string name="permlab_changeComponentState" msgid="6335576775711095931">"уключаць або адключаць кампаненты прыкладання"</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дазваляе прыкладанню ўключаць ці адключаць кампанент іншага прыкладання. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў тэлефона. Трэба захоўваць асцярожнасць з гэтым дазволам, таму што гэта можа прывесці кампаненты прыкладання да непрыдатнасці, непаслядоўнасці або няўстойлівасці."</string>
- <!-- outdated translation 4647419365510068321 --> <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дазваляе прыкладанню ўключаць ці адключаць кампанент іншага прыкладання. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў тэлефона. Трэба захоўваць асцярожнасць з гэтым дазволам, таму што гэта можа прывесці кампаненты прыкладання да непрыдатнасці, непаслядоўнасці або няўстойлівасці."</string>
- <!-- outdated translation 3393305202145172005 --> <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"выбіраць пажаданыя праграмы"</string>
- <!-- outdated translation 760008293501937546 --> <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дазваляе прыкладанням змяняць вашы выбраныя прыкладанні. Гэта можа дазволіць шкоднасным прыкладанням незаўважна мяняць прыкладанні, якія запускаюцца, падмяняць існуючыя прыкладанні для збору вашых канфідэнцыйных дадзеных."</string>
+ <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дазваляе прыкладанням счытваць і запісваць любы рэсурс, які належыць дыягнастычнай групе, напрыклад файлы распрацоўшчыка ў тэчцы /dev. Патэнцыйна гэта можа паўплываць на стабільнасць і бяспеку сістэмы. Гэта павінна выкарыстоўвацца ТОЛЬКІ для апаратнай дыягностыкі вытворцам або аператарам."</string>
+ <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>
+ <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"усталяваць пажаданыя прыкладанні"</string>
+ <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дазваляе прыкладанням змяняць вашы пажаданыя прыкладанні. Шкоднасныя прыкладанні могуць непрыкметна змяняць запушчаныя прыкладанні, падмяняючы існуючыя прыкладанні, каб збiраць вашы асабістыя дадзеныя."</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"змена глабальных параметраў сістэмы"</string>
- <!-- outdated translation 838789419871034696 --> <string name="permdesc_writeSettings" msgid="7775723441558907181">"Дазваляе прыкладанням змяняць налады сістэмы. Шкодныя прыкладанні могуць пашкодзіць канфігурацыю сістэмы."</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"Дазваляе прыкладаннем змяняць дадзеныя налад сістэмы. Шкоднасныя прыкладанні могуць пашкодзіць канфігурацыю вашай сістэмы."</string>
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"змяняць параметры бяспекі сістэмы"</string>
- <!-- outdated translation 5497873143539034724 --> <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Дазваляе прыкладанням мяняць параметры бяспекі сістэмы. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Дазваляе прыкладанням змяняць дадзеныя параметраў бяспекі сістэмы. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_writeGservices" msgid="2149426664226152185">"змяняць карту службаў Google"</string>
- <!-- outdated translation 6602362746516676175 --> <string name="permdesc_writeGservices" msgid="1287309437638380229">"Дазваляе прыкладанням змяняць карту службаў Google. Не для выкарыстання звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_writeGservices" msgid="1287309437638380229">"Дазваляе прыкладанням змяняць карту службаў Google. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"аўтаматычна запускаць пры загрузцы"</string>
- <!-- outdated translation 7530977064379338199 --> <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Дазваляе прыкладанням запускаць саміх сябе, як толькі сістэма цалкам загрузіцца. Гэта можа зрабіць загрузку планшэта больш павольнай і дазволіць прыкладанню запаволіць увесь планшэт, заўсёды працуючы."</string>
- <!-- outdated translation 7530977064379338199 --> <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Дазваляе прыкладанням запускаць саміх сябе, як толькі сістэма цалкам загрузіцца. Гэта можа зрабіць загрузку планшэта больш павольнай і дазволіць прыкладанню запаволіць увесь планшэт, заўсёды працуючы."</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Дазваляе прыкладанню самастойна запускацца, як толькі сістэма будзе цалкам загружана. Гэта можа павялічыць час запуску планшэту і дазволіць прыкладанню запаволіць увесь планшэт, прымушаючы яго працаваць заўсёды."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Дазваляе прыкладанням самастойна запускацца, як толькі сістэма будзе цалкам запушчана. Гэта можа павялічыць час запуску тэлефону і дазволіць прыкладанню запаволіць увесь тэлефон, прымушаючы яго працаваць заўсёды."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"адпраўляць нетэрмiновую рассылку"</string>
- <!-- outdated translation 6322249605930062595 --> <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Дазваляе прыкладанням адпраўляць прыдаткі да трансляцый, якія застаюцца пасля заканчэння трансляцыі. Шкоднасныя прыкладанні могуць зрабіць работу планшэта павольнай або нестабільнай, прымушаючы яго выкарыстоўваць занадта вялікі аб\'ём памяці."</string>
- <!-- outdated translation 6322249605930062595 --> <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Дазваляе прыкладанням адпраўляць прыдаткі да трансляцый, якія застаюцца пасля заканчэння трансляцыі. Шкоднасныя прыкладанні могуць зрабіць работу планшэта павольнай або нестабільнай, прымушаючы яго выкарыстоўваць занадта вялікі аб\'ём памяці."</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Дазваляе прыкладанням дасылаць далейшыя звязаныя перадачы, якія застаюцца пасля заканчэння асноўнай перадачы. Шкоднасныя прыкладанні могуць зрабіць працу планшэта павольнай або няўстойлівай, прымушаючы яго выкарыстоўваць занадта шмат памяці."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Дазваляе прыкладанню дасылаць далейшыя звязаныя перадачы, якія застаюцца пасля заканчэння асноўнай перадачы. Шкоднасныя прыкладанні могуць зрабіць працу тэлефона павольнай або няўстойлівай, прымушаючы яго выкарыстоўваць занадта шмат памяці."</string>
<string name="permlab_readContacts" msgid="6219652189510218240">"чытаць кантактныя дадзеныя"</string>
- <!-- outdated translation 7596158687301157686 --> <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Дазваляе прыкладанням счытваць усе кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб адпраўляць вашыя дадзеныя іншым асобам."</string>
- <!-- outdated translation 7596158687301157686 --> <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Дазваляе прыкладанням счытваць усе кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб адпраўляць вашыя дадзеныя іншым асобам."</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Дазваляе прыкладанням счытваць усе кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб адпраўляць дадзеныя іншым людзям."</string>
+ <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Дазваляе прыкладанням счытваць усе кантакты (адрасы), якія захоўваюцца на вашым тэлефоне. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб адпраўляць дадзеныя іншым людзям."</string>
<string name="permlab_writeContacts" msgid="644616215860933284">"запісваць кантактныя дадзеныя"</string>
- <!-- outdated translation 7782689510038568495 --> <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Дазваляе прыкладанням змяняць кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб сцерці або змяніць вашыя кантактныя дадзеныя."</string>
- <!-- outdated translation 7782689510038568495 --> <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Дазваляе прыкладанням змяняць кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб сцерці або змяніць вашыя кантактныя дадзеныя."</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Дазваляе прыкладанням змяняць кантакты (адрасы), якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэтую магчымасць для выдалення або змены кантактных дадзеных."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Дазваляе прыкладанням змяняць кантакты (адрасы), якія захоўваюцца на вашым тэлефоне. Шкоднасныя прыкладанні могуць выкарыстоўваць гэту магчымасць для выдалення або змены кантактных дадзеных."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"чытаць дадзеныя вашага профілю"</string>
- <!-- outdated translation 6335739730324727203 --> <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Дазваляе прыкладанням счытваць персанальныя дадзеныя профілю, якія захоўваюцца на вашай прыладзе (напрыклад, вашыя імя і кантактную інфармацыю). Гэта азначае, што прыкладанне можа ідэнтыфікаваць вас і адправіць інфармацыю аб вашым профілі іншым асобам."</string>
+ <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Дазваляе прыкладанням счытваць асабістую інфармацыю ў профілях, якая захоўваецца на вашай прыладзе, напрыклад, ваша імя і кантактную інфармацыю. Гэта азначае, што прыкладанне можа ідэнтыфікаваць вас і адправіць інфармацыю вашага профілю трэцім асобам."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"увядзіце дадзеныя вашага профілю"</string>
- <!-- outdated translation 6431297330378229453 --> <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Дазваляе прыкладанням змяняць або дадаваць персанальныя дадзеныя профілю, якія захоўваюцца на вашай прыладзе (напрыклад, вашыя імя і кантактную інфармацыю). Гэта азначае, што іншыя прыкладанні могуць ідэнтыфікаваць вас і адправіць інфармацыю аб вашым профілі іншым асобам."</string>
+ <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Дазваляе прыкладанням змяняць ці дадаваць асабістую інфармацыю профіляў, захаваных на прыладзе, напрыклад ваша імя і кантактную інфармацыю. Такім чынам, іншыя прыкладанні могуць ідэнтыфікаваць вас і адпраўляць інфармацыю вашага профіля трэцім асобам."</string>
<string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"чытаць мой паток абнаўленняў"</string>
- <!-- outdated translation 1300659548047580769 --> <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Дазваляе прыкладанням атрымліваць доступ да абнаўленняў вашых сяброў i сiнхранiзаваць гэтыя звесткi. З дапамогай шкоднасных прыкладанняў хтосьцi можа атрымаць доступ да вашай асабiстай перапiскi з сябрамi ў сацыяльных сетках."</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Дазваляе прыкладанням атрымліваць доступ і сінхранізаваць абнаўленнi ад вас i вашых сяброў у сацыяльных сетках. З дапамогай шкоднасных прыкладанняў хтосьцi можа чытаць вашу асабiстую перапiску з сябрамі ў сацыяльных сетках."</string>
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"запісаць у мой паток абнаўленняў"</string>
- <!-- outdated translation 8649864102944627446 --> <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Дазваляе прыкладанням публiкаваць абнаўленнi вашых сяброў з сацыяльных сетак. З дапамогай шкоднасных прыкладанняў хтосьцi можа падрабляць абнаўленнi ад вашых сяброў i, напрыклад, збiраць вашы канфiдэнцыйныя звесткi."</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Дазваляе прыкладанням адлюстроўваць абнаўленнi ад вашых сяброў у сацыяльных сетках. З дапамогай шкоднасных прыкладанняў хтосьцi можа прыкінуцца вашым сябрам, каб выкрасцi паролi i iншыя канфiдэнцыйныя звесткi."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"чытаць падзеі календара, а таксама прыватную інфармацыю"</string>
- <!-- outdated translation 5665520896961671949 --> <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Дазваляе прыкладанням счытваць усе падзеі календара, захаваныя на планшэце, у тым ліку падзеі сяброў і калегаў. З дапамогай гэтага дазволу шкоднасныя прыкладанні могуць здабываць персанальную інфармацыю з гэтых календароў без ведама ўладальнікаў."</string>
- <!-- outdated translation 5665520896961671949 --> <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Дазваляе прыкладанням счытваць усе падзеі календара, захаваныя на планшэце, у тым ліку падзеі сяброў і калегаў. З дапамогай гэтага дазволу шкоднасныя прыкладанні могуць здабываць персанальную інфармацыю з гэтых календароў без ведама ўладальнікаў."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Дазваляе прыкладанню счытваць усе мерапрыемствы календара, захаваныя на планшэце, у тым ліку мерапрыемствы сяброў і калег. Шкоднасныя прыкладанні могуць атрымліваць асабістую інфармацыю з гэтых календароў без ведама ўладальнікаў."</string>
+ <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Дазваляе прыкладанню счытваць усе мерапрыемствы календара, захаваныя на вашым тэлефоне, у тым ліку мерапрыемствы сяброў і калег. Шкоднасныя прыкладаннi могуць атрымліваць асабістую інфармацыю з гэтых календароў без ведама ўладальнікаў."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"дадаваць ці змяняць падзеі календара і адпраўляць электронную пошту да гасцей без ведама ўладальнікаў"</string>
- <!-- outdated translation 5368129321997977226 --> <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Дазваляе прыкладанням адпраўляць запрашэнні на мерапрыемствы ад iмя ўладальніка календара і дадаваць, выдаляць, змяняць падзеі, якія можна змяняць на прыладзе, у тым ліку падзеі сяброў або калегаў. З дапамогай гэтага дазволу шкоднасныя прыкладанні могуць рассылаць спам , які выглядае як прыбыўшы ад уладальніка календара, змяняць падзеі без ведама ўладальнікаў або дадаваць падробленыя падзеі."</string>
+ <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Дазваляе прыкладанням адпраўляць запрашэнні на мерапрыемствы ў якасці ўладальніка календара і дадаваць, выдаляць, рэдагаваць мерапрыемствы, якія можна змяняць на прыладзе, у тым ліку мерапрыемствы сяброў або калег. Шкоднасныя прыкладанні могуць адпраўляць паведамленні-спам, якія зыходзяць ад уладальніка календара, змяняць мерапрыемствы без ведама ўладальнікаў або дадаваць падробленыя мерапрыемствы."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"макет крыніц месцазнаходжання для тэставання"</string>
- <!-- outdated translation 7648286063459727252 --> <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Стварыць макет крыніц месцазнаходжанняў для тэставання. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для змены месцазнаходжання і/або статусу, атрыманых з рэальных сістэм пазіцыявання, напрыклад з GPS або сеткі правайдэраў мабільнай сувязі."</string>
+ <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Дазваляе прыкладанням ствараць макет крыніц месцазнаходжання для тэставання. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб змяняць месцазнаходжанне і/або статус, паведамляемы рэальнымі крыніцамі месцазнаходжання, напрыклад, GPS або правайдэрамі сеткі."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"доступ да дадатковых камандаў пастаўшчыка месцазнаходжання"</string>
- <!-- outdated translation 1948144701382451721 --> <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Доступ да дадатковых каманд пастаўшчыка месцазнаходжання. Шкоднасныя прыкладанні могуць карыстацца гэтым, каб умешвацца ў працу GPS і іншых крыніц месцазнаходжання."</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Дазваляе прыкладанням атрымліваць доступ да дадатковых каманд пастаўшчыка месца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб умешвацца ў працу GPS або іншых крыніц месцазнаходжання."</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"дазвол на ўсталяванне пастаўшчыка месцазнаходжання"</string>
- <!-- outdated translation 5449175116732002106 --> <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Стварыць макет крыніц месца для тэставання. Шкоднае праграмнае забеспячэнне можа выкарыстаць гэта, каб змяніць месцазнаходжанне і/або статус, атрыманы з рэальных сістэм пазіцыянавання, напрыклад з GPS або сеткі правайдэраў мабільнай сувязі, або можа вызначаць ваша месцазнаходжанне і перадаваць звесткі на вонкавыя прылады."</string>
+ <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Стварае макет крыніц месцазнаходжання для тэставання. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб змяняць месцазнаходжанне і/або статус, які перадаюць рэальныя крыніцы месцазнаходжання, напрыклад GPS або пастаўшчыкі паслуг сеткі, ці кантраляваць вашае месцазнаходжанне і перадаваць яго на знешнюю крыніцу."</string>
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"дакладнае (GPS) месцазнаходжанне"</string>
- <!-- outdated translation 243973693233359681 --> <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Доступ да дакладных крыніц месцаў (напрыклад, да глабальнай сістэмы пазіцыянавання на планшэце), калі такія маюцца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб вызначыць, дзе вы знаходзіцеся, і могуць спажываць дадатковую магутнасць батарэі."</string>
- <!-- outdated translation 243973693233359681 --> <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Доступ да дакладных крыніц месцаў (напрыклад, да глабальнай сістэмы пазіцыянавання на планшэце), калі такія маюцца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб вызначыць, дзе вы знаходзіцеся, і могуць спажываць дадатковую магутнасць батарэі."</string>
+ <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Дазволіць доступ да сістэм дакладнага пазіцыянавання на планшэце, напрыклад да GPS, там, дзе гэта магчыма. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта для вызначэння вашага месцазнаходжання, а таксама могуць дадаткова спажываць магутнасць акумулятару."</string>
+ <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Дазволіць доступ да сістэм дакладнага пазіцыянавання на тэлефоне, напрыклад да GPS, там, дзе гэта магчыма. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта для вызначэння вашага месцазнаходжання, а таксама могуць дадаткова спажываць магутнасць акумулятару."</string>
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"прыблізнае (заснаванае на дадзеных сеткі) месцазнаходжанне"</string>
- <!-- outdated translation 3704633168985466045 --> <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Доступ да грубых крыніц месца (напрыклад, да базы дадзеных сотавай сеткі), каб вызначыць прыблізнае месцазнаходжанне планшэту, калі такія маюцца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб прыкладна вызначыць, дзе вы знаходзіцеся."</string>
- <!-- outdated translation 3704633168985466045 --> <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Доступ да грубых крыніц месца (напрыклад, да базы дадзеных сотавай сеткі), каб вызначыць прыблізнае месцазнаходжанне планшэту, калі такія маюцца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб прыкладна вызначыць, дзе вы знаходзіцеся."</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Атрымаць доступ да прыблізных крыніц месцазнаходжання (напрыклад, да базы дадзеных сотавай сеткі), каб вызначыць прыблізнае месцазнаходжанне планшэта, калі такія маюцца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб прыкладна вызначаць, дзе вы знаходзіцеся."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Каб вызначыць прыблізнае месцазнаходжанне тэлефона, атрымайце доступ да прыблізных крыніц месцазнаходжання (напрыклад, да базы дадзеных сотавай сеткі), калі такія маюцца. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб прыкладна вызначаць, дзе вы."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"доступ да SurfaceFlinger"</string>
- <!-- outdated translation 6805241830020733025 --> <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Дазваляе прыкладанням выкарыстоўваць нізкаўзроўневыя функцыі SurfaceFlinger."</string>
+ <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Дазваляе прыкладанням выкарыстоўваць нізкаўзроўневыя функцыі SurfaceFlinger."</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"чытаць буфер кадраў"</string>
- <!-- outdated translation 7530020370469942528 --> <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Дазваляе прыкладанню чытаць змесціва буфера кадраў."</string>
+ <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Дазваляе прыкладанням счытваць змесціва буферу кадра."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"змяняць налады аудыё"</string>
- <!-- outdated translation 5793461287365991922 --> <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Дазваляе прыкладанням змяняць глабальныя налады аудыё, напрыклад гучнасць і маршрутызацыю."</string>
+ <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Дазваляе прыкладанням змяняць глабальныя налады аудыё, напрыклад гук і маршрутызацыю."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"запісваць аўдыё"</string>
- <!-- outdated translation 6493228261176552356 --> <string name="permdesc_recordAudio" msgid="2387462233976248635">"Дае прыкладанням доступ да шляха запісу аўдыё."</string>
+ <string name="permdesc_recordAudio" msgid="2387462233976248635">"Дазваляе прыкладанням атрымліваць доступ да шляху аудыёзапісу."</string>
<string name="permlab_camera" msgid="3616391919559751192">"рабіць фатаграфіі і відэа"</string>
- <!-- outdated translation 6004878235852154239 --> <string name="permdesc_camera" msgid="1507407407002492176">"Дазваляе прыкладанням здымаць фатаграфіі і відэа з дапамогай камеры. Гэта дазваляе прыкладанням ў любы час збіраць выявы, якія бачыць камера."</string>
+ <string name="permdesc_camera" msgid="1507407407002492176">"Дазваляе прыкладанням рабiць фатаграфіі і відэа з камеры. Гэта дазваляе прыкладанням у любы час збіраць выявы, якія \"бачыць\" камера."</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"цалкам адключыць планшэт"</string>
<string name="permlab_brick" product="default" msgid="8337817093326370537">"цалкам адключаць тэлефон"</string>
- <!-- outdated translation 7379164636920817963 --> <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Дазваляе прыкладанням цалкам адключаць планшэт. Гэта вельмі небяспечна."</string>
- <!-- outdated translation 7379164636920817963 --> <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Дазваляе прыкладанням цалкам адключаць планшэт. Гэта вельмі небяспечна."</string>
+ <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Дазваляе прыкладанням цалкам адключаць планшэт. Гэта вельмі небяспечна."</string>
+ <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Дазваляе прыкладанням цалкам адключаць тэлефон. Гэта вельмі небяспечна."</string>
<string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"прымусовая перазагрузка планшэта"</string>
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"прымусова перазагружаць тэлефон"</string>
- <!-- outdated translation 4555793623560701557 --> <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Дазваляе прыкладанню прымусова перазагрузіць планшэт."</string>
- <!-- outdated translation 4555793623560701557 --> <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Дазваляе прыкладанню прымусова перазагрузіць планшэт."</string>
+ <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Дазваляе прыкладанням прымусова перазагружаць планшэт."</string>
+ <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Дазваляе прыкладанням прымусова перазагружаць тэлефон."</string>
<string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"уключэнне і адключэнне файлавых сістэм"</string>
- <!-- outdated translation 6253263792535859767 --> <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Дазваляе прыкладанням уключаць і адключаць файлавыя сістэмы для падлучэння зменных назапашвальнікаў."</string>
+ <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Дазваляе прыкладанням падключаць і адключаць файлавыя сістэмы для здымных назапашвальнікаў."</string>
<string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"фарматаваць знешнія назапашвальнікі"</string>
- <!-- outdated translation 574060044906047386 --> <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Дазваляе прыкладанням фарматаваць здымныя назапашвальнiкi."</string>
+ <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Дазваляе прыкладанням фарматаваць здымны назапашвальнiк."</string>
<string name="permlab_asec_access" msgid="3411338632002193846">"атрымаць інфармацыю аб унутранай памяці"</string>
- <!-- outdated translation 8820326551687285439 --> <string name="permdesc_asec_access" msgid="3094563844593878548">"Дазваляе прыкладанню атрымліваць інфармацыю аб унутранай памяці."</string>
+ <string name="permdesc_asec_access" msgid="3094563844593878548">"Дазваляе прыкладанню атрымліваць інфармацыю пра ўнутраную памяць."</string>
<string name="permlab_asec_create" msgid="6414757234789336327">"стварыць унутраную памяць"</string>
- <!-- outdated translation 2621346764995731250 --> <string name="permdesc_asec_create" msgid="4558869273585856876">"Дазваляе прыкладанню ствараць унутраную памяць."</string>
+ <string name="permdesc_asec_create" msgid="4558869273585856876">"Дазваляе прыкладанням ствараць унутраную памяць."</string>
<string name="permlab_asec_destroy" msgid="526928328301618022">"знішчыць унутраную памяць"</string>
- <!-- outdated translation 2746706889208066256 --> <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Дазваляе прыкладанню знішчаць унутраную памяць."</string>
- <!-- outdated translation 2456287623689029744 --> <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"падключыць/адключыць унутраную памяць"</string>
- <!-- outdated translation 5934375590189368200 --> <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Дазваляе прыкладанню падключаць/адключаць унутраную памяць."</string>
+ <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Дазваляе прыкладанням выдаляць унутраную памяць."</string>
+ <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"падключэнне/адключэнне ўнутранай памяці"</string>
+ <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Дазваляе прыкладанням падлучаць i адлучаць унутраную памяць."</string>
<string name="permlab_asec_rename" msgid="7496633954080472417">"перайменаваць унутраную памяць"</string>
- <!-- outdated translation 2152829985238876790 --> <string name="permdesc_asec_rename" msgid="1794757588472127675">"Дазваляе праграмам змяняць імя ўнутранай памяці."</string>
+ <string name="permdesc_asec_rename" msgid="1794757588472127675">"Дазваляе прыкладанням змяняць імя ўнутранай памяці."</string>
<string name="permlab_vibrate" msgid="7768356019980849603">"кіраваць вібрацыяй"</string>
- <!-- outdated translation 2886677177257789187 --> <string name="permdesc_vibrate" msgid="6284989245902300945">"Дазваляе прыкладанням кіраваць вібрацыяй."</string>
+ <string name="permdesc_vibrate" msgid="6284989245902300945">"Дазваляе прыкладанням кіраваць вібрацыяй."</string>
<string name="permlab_flashlight" msgid="2155920810121984215">"кіраваць ўспышкай"</string>
- <!-- outdated translation 6433045942283802309 --> <string name="permdesc_flashlight" msgid="6522284794568368310">"Дазваляе прыкладанню кіраваць ліхтарыкам."</string>
+ <string name="permdesc_flashlight" msgid="6522284794568368310">"Дазваляе прыкладанню кіраваць ліхтарыкам."</string>
<string name="permlab_manageUsb" msgid="1113453430645402723">"кіраваць спісам пажаданых і дазволеных USB-прылад"</string>
- <!-- outdated translation 6148489202092166164 --> <string name="permdesc_manageUsb" msgid="7776155430218239833">"Дазваляе выкарыстоўваць праграму для кіравання спісам пажаданых і дазволеных USB-прылад."</string>
+ <string name="permdesc_manageUsb" msgid="7776155430218239833">"Дазваляе прыкладанням кіраваць наладамі і дазволамі USB-прылад."</string>
<string name="permlab_accessMtp" msgid="4953468676795917042">"рэалізаваць пратакол MTP"</string>
<string name="permdesc_accessMtp" msgid="6532961200486791570">"Дазваляе атрымаць доступ да драйвер ядра MTP, каб рэалізаваць USB-пратакол MTP."</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"тэставаць апаратнае забеспячэнне"</string>
- <!-- outdated translation 3668894686500081699 --> <string name="permdesc_hardware_test" msgid="6597964191208016605">"Дазваляе прыкладанням кіраваць рознымі перыферыйнымі прыладамі для тэставання абсталявання."</string>
+ <string name="permdesc_hardware_test" msgid="6597964191208016605">"Дазваляе прыкладанням кіраваць рознымі перыферыйнымі прыладамі для тэставання апаратнага абсталявання."</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"непасрэдна набіраць тэлефонныя нумары"</string>
- <!-- outdated translation 3369867353692722456 --> <string name="permdesc_callPhone" msgid="6396463004110544744">"Дазваляе прыкладанням выклікаць тэлефонныя нумары без вашага ўмяшальніцтва. Шкодныя праграмы могуць рабіць непрадугледжаныя званкі за ваш кошт. Звярніце ўвагу: гэта не дазваляе прыкладанням выклікаць нумары экстраных службаў."</string>
+ <string name="permdesc_callPhone" msgid="6396463004110544744">"Дазваляе прыкладанням выклікаць тэлефонныя нумары без вашага ведама. Шкоднасныя прыкладанні могуць прывесці да з\'яўлення нечаканых выклікаў у вашым рахунку за паслугі тэлефоннай сувязі. Звярніце ўвагу, што гэты дазвол не дазваляе прыкладанню выклікаць экстраныя нумары."</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"непасрэдна выклікаць любыя тэлефонныя нумары"</string>
- <!-- outdated translation 244405067160028452 --> <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Дазваляе прыкладанням тэлефанаваць на любы нумар, у тым лiку на нумары экстраных служб, без вашага ўмяшальніцтва. Шкодныя праграмы могуць рабіць непатрэбныя і незаконныя выклікі аварыйных службаў."</string>
+ <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Дазваляе прыкладанню тэлефанаваць на любы тэлефонны нумар, у тым лiку на экстраныя нумары, без вашага ведама. Шкоднасныя прыкладанні могуць рабіць непатрэбныя і незаконныя экстраныя выклікі."</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"непасрэдна пачаць наладу CDMA-планшэта"</string>
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"непасрэдна запускаць налады тэлефона CDMA"</string>
- <!-- outdated translation 6457447676108355905 --> <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Дазваляе прыкладанням запускаць падрыхтоўку CDMA. Шкоднасныя прыкладанні могуць без неабходнасці пачаць падрыхтоўку CDMA"</string>
+ <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Дазваляе прыкладанням запускаць рэзервы CDMA. Шкоднасныя прыкладанні могуць запускаць залішнія рэзервы CDMA."</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"кіраваць абвесткамі абнаўлення месцазнаходжання"</string>
- <!-- outdated translation 2300018303720930256 --> <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Дазваляе ўключаць/выключаць абнаўленнi апавяшчэнняў аб месцазнаходжанні праз радыё. Не для выкарыстання звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Дазваляе прыкладанням уключаць i адключаць апавяшчэннi аб абнаўленні месцазнаходжання ад радыё. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_checkinProperties" msgid="7855259461268734914">"атрымліваць доступ да ўласцівасцяў праверкі"</string>
- <!-- outdated translation 7150307006141883832 --> <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Дазваляе счытваць і запісваць уласцівасці, загружаныя службай рэгістрацыі. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Дазваляе прыкладанням сытваць/запісваць доступ да ўласцівасцяў, запампаваных службай праверкі. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_bindGadget" msgid="776905339015863471">"выбіраць віджэты"</string>
- <!-- outdated translation 2098697834497452046 --> <string name="permdesc_bindGadget" msgid="8261326938599049290">"Дазваляе прыкладанням паведамляць сістэме, якія прыкладанні могуць выкарыстоўваць віджэты. З гэтым дазволам яны могуць даваць іншым прыкладанням доступ да персанальных дадзеных. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_bindGadget" msgid="8261326938599049290">"Дазваляе прыкладанням паведамляць сістэме, якая віджэты могуць быць выкарыстаны пэўнымі прыкладаннямі. Прыкладанне з гэтым дазволам можа прадастаўляць доступ да персанальных дадзеных іншым прыкладанням. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"змяняць стан тэлефона"</string>
- <!-- outdated translation 3302284561346956587 --> <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Дазваляе прыкладанням кіраваць тэлефоннымі функцыямі прылады. Прыкладанні з гэтым дазволам могуць пераключаць сеткі, уключаць і адключаць радыё на тэлефоне і г. д., нават не паведамляючы пра гэта."</string>
+ <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Дазваляе прыкладанням кіраваць тэлефоннымі функцыямі прылады. Прыкладанне з гэтым дазволам можа пераключаць сеткі, уключаць і выключаць радыё на тэлефоне і г. д., нават не паведамляючы пра гэта."</string>
<string name="permlab_readPhoneState" msgid="2326172951448691631">"чытаць стан тэлефона і ідэнтыфікацыйныя дадзеныя"</string>
- <!-- outdated translation 188877305147626781 --> <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Дазваляе прыкладанням атрымліваць доступ да функцый тэлефона прылады. Прыкладанні з гэтым дазволам могуць вызначыць нумар тэлефона і серыйны нумар гэтага тэлефона, актыўнасць выкліка, нумар выкліканага абанента і таму падобнае."</string>
+ <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Дазваляе прыкладанням атрымліваць доступ да тэлефонных функцый прылады. Прыкладанне з гэтым дазволам можа вызначаць нумар тэлефона і серыйны нумар гэтага тэлефона ці актыўны выклік, нумар выкліканага абанента і г. д."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"прадухіліць планшэт ад пераходу ў рэжым сну"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"забараняць тэлефону пераходзіць ў рэжым сну"</string>
- <!-- outdated translation 4032181488045338551 --> <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дазваляе прыкладанню прадухіліць планшэт ад пераходу ў рэжым сну."</string>
- <!-- outdated translation 4032181488045338551 --> <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Дазваляе прыкладанню прадухіліць планшэт ад пераходу ў рэжым сну."</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Дазваляе прыкладанням прадухіляць пераход планшэта ў рэжым сну."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Дазваляе прыкладанням прадухіляць тэлефон ад пераходу ў рэжым сну."</string>
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Уключыць або выключыць планшэт"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"уключаць або выключаць тэлефон"</string>
- <!-- outdated translation 3853773100100451905 --> <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Дазваляе прыкладанням уключаць або выключаць планшэт"</string>
- <!-- outdated translation 3853773100100451905 --> <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Дазваляе прыкладанням уключаць або выключаць планшэт"</string>
+ <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Дазваляе прыкладанням уключаць ці адключаць планшэт."</string>
+ <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Дазваляе прыкладанням уключаць або адключаць тэлефон."</string>
<string name="permlab_factoryTest" msgid="3715225492696416187">"запусціць у рэжыме заводскага тэставання"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Запуск у якасці нізкаўзроўневага тэсты вытворцы, што дазваляе атрымаць поўны доступ да абсталявання планшэта. Даступна, толькі калі планшэт працуе ў рэжыме тэставання вытворцы."</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Запусціць як нізкаўзроўневы тэст вытворцы, што дазваляе атрымаць поўны доступ да абсталявання тэлефона. Даступна, толькі калі прылада працуе ў рэжыме тэста вытворцы."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"усталёўваць шпалеры"</string>
- <!-- outdated translation 6417041752170585837 --> <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Дазваляе прыкладанням усталёўваць сiстэмныя шпалеры."</string>
+ <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Дазваляе прыкладанням ксталёўваць сiстэмныя шпалеры."</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"усталёўваць падказкі памераў шпалер"</string>
- <!-- outdated translation 6019479164008079626 --> <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Дазваляе прыкладанням задаваць падказкі па памеру сістэмных шпалераў."</string>
+ <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Дазваляе прыкладанням задаваць падказкі па памеры сістэмных шпалер."</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"скідаць сістэму да завадскіх наладаў"</string>
- <!-- outdated translation 5033465107545174514 --> <string name="permdesc_masterClear" msgid="3665380492633910226">"Дазваляе прыкладанням рабіць поўнае скіданне да завадскіх налад. Пры гэтым выдаляюцца ўсе дадзеныя, канфігурацыя і ўсталяваныя прыкладанні."</string>
+ <string name="permdesc_masterClear" msgid="3665380492633910226">"Дазваляе прыкладанню цалкам скідваць сістэму да заводскіх налад, выдаляючы ўсе дадзеныя, налады і ўсталяваныя прыкладанні."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"задаць час"</string>
- <!-- outdated translation 209693136361006073 --> <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Дазваляе прыкладанню змяняць час на планшэце."</string>
- <!-- outdated translation 209693136361006073 --> <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Дазваляе прыкладанню змяняць час на планшэце."</string>
+ <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Дазваляе прыкладанням змяняць час на гадзінніку планшэта."</string>
+ <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Дазваляе прыкладаннМ змяняць час на гадзінніку тэлефона."</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"усталёўваць часавы пояс"</string>
- <!-- outdated translation 2522877107613885139 --> <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Дазваляе прыкладанню змяняць гадзінны пояс планшэта."</string>
- <!-- outdated translation 2522877107613885139 --> <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Дазваляе прыкладанню змяняць гадзінны пояс планшэта."</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Дазваляе прыкладанням змяняць гадзінны пояс планшэта."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Дазваляе прыкладанню змяняць гадзінны пояс тэлефона."</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"выступаць у якасці службы AccountManagerService"</string>
- <!-- outdated translation 6056903274106394752 --> <string name="permdesc_accountManagerService" msgid="2684502137670299915">"Дазваляе прыкладанням тэлефанаваць на AccountAuthenticators"</string>
+ <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Дазваляе прыкладанням тэлефанаваць на AccountAuthenticators."</string>
<string name="permlab_getAccounts" msgid="4549918644233460103">"выяўляць вядомыя ўліковыя запісы"</string>
- <!-- outdated translation 857622793935544694 --> <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Дазваляе прыкладанням атрымліваць спіс уліковых запісаў, якія ёсць на планшэце."</string>
- <!-- outdated translation 857622793935544694 --> <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Дазваляе прыкладанням атрымліваць спіс уліковых запісаў, якія ёсць на планшэце."</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Дазваляе прыкладанню атрымліваць спіс уліковых запісаў, вядомых планшэту."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Дазваляе прыкладанню атрымліваць спіс уліковых запісаў, вядомых тэлефону."</string>
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"выступаць у якасці аўтэнтыфікатара ўліковага запісу"</string>
- <!-- outdated translation 4006839406474208874 --> <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Дазваляе прыкладанню выкарыстоўваць магчымасці сродку праверкі сапраўднасці ўліковых запісаў AccountManager, у тым ліку ствараць уліковыя запісы, атрымліваць і наладжваць паролі для іх."</string>
+ <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Дазваляе прыкладанням выкарыстоўваць магчымасці сродку праверкі сапраўднасці ўліковых запісаў AccountManager, у тым ліку ствараць уліковыя запісы, атрымліваць і наладжваць паролі для іх."</string>
<string name="permlab_manageAccounts" msgid="4440380488312204365">"кіраванне спісам уліковых запісаў"</string>
- <!-- outdated translation 8804114016661104517 --> <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Дазваляе прыкладанням выконваць такія аперацыі, як дадаванне і выдаленне ўліковых запісаў альбо выдаленне іх пароляў."</string>
+ <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Дазваляе прыкладанням выконваць даданне і выдаленне ўліковых запісаў або выдаленне іх пароляў."</string>
<string name="permlab_useCredentials" msgid="6401886092818819856">"выкарыстоўваць уліковыя дадзеныя ўліковага запісу"</string>
- <!-- outdated translation 7416570544619546974 --> <string name="permdesc_useCredentials" msgid="7984227147403346422">"Дазваляе прыкладанню запытваць ключы аўтэнтыфікацыі."</string>
+ <string name="permdesc_useCredentials" msgid="7984227147403346422">"Дазваляе прыкладанням запытваць ключы аўтэнтыфікаціі."</string>
<string name="permlab_accessNetworkState" msgid="6865575199464405769">"праглядаць стан сеткі"</string>
- <!-- outdated translation 558721128707712766 --> <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Дазваляе прыкладанням праглядаць стан усіх сетак."</string>
+ <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Дазваляе прыкладанню праглядаць стан усіх сетак."</string>
<string name="permlab_createNetworkSockets" msgid="9121633680349549585">"поўны доступ да інтэрнэту"</string>
- <!-- outdated translation 4593339106921772192 --> <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Дазваляе прыкладанням ствараць сеткавыя злучальнікі."</string>
+ <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Дазваляе прыкладанню ствараць сеткавыя сокеты."</string>
<string name="permlab_writeApnSettings" msgid="505660159675751896">"змяняць/перахопліваць сеткавыя налады і трафік"</string>
- <!-- outdated translation 2369786339323021771 --> <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Дазваляе прыкладанням змяняць налады сеткі, перахапляць і правяраць увесь сеткавы трафік, напрыклад для змены проксі і порта любога APN. Шкоднасныя прыкладанні могуць адсочваць, перанакіроўваць або змяняць сеткавыя пакеты без вашага ведама."</string>
+ <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Дазваляе прыкладанням змяняць налады сеткі, перахапляць і правяраць увесь сеткавы трафік, напрыклад для змены проксі-сервера і порта любога APN. Шкоднасныя прыкладанні могуць адсочваць, перанакіроўваць або змяняць сеткавыя пакеты без вашага ведама."</string>
<string name="permlab_changeNetworkState" msgid="958884291454327309">"змяніць падлучэнне да сеткі"</string>
- <!-- outdated translation 4199958910396387075 --> <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Дазваляе прыкладанням змяняць стан сеткавага падключэння."</string>
- <!-- outdated translation 2702121155761140799 --> <string name="permlab_changeTetherState" msgid="5952584964373017960">"Змяняць падлучэнне да мадэму"</string>
- <!-- outdated translation 8905815579146349568 --> <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Дазваляе прыкладанню змяняць стан прывязанага сеткавага падключэння."</string>
+ <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Дазваляе прыкладанням змяняць стан сеткавага падключэння."</string>
+ <string name="permlab_changeTetherState" msgid="5952584964373017960">"змяніць прывязку да падлучэння"</string>
+ <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Дазваляе прыкладанням змяняць стан прывязкі да сеткі."</string>
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"змяняць налады выкарыстання фонавых дадзеных"</string>
- <!-- outdated translation 1001482853266638864 --> <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Дазваляе прыкладанням мяняць налады фонавай перадачы дадзеных."</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Дазваляе прыкладанням змяняць налады выкарыстання зыходных дадзеных."</string>
<string name="permlab_accessWifiState" msgid="8100926650211034400">"праглядаць стан Wi-Fi"</string>
- <!-- outdated translation 485796529139236346 --> <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Дазваляе прыкладанням праглядаць інфармацыю аб стане Wi-Fi."</string>
+ <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Дазваляе прыкладанням праглядаць інфармацыю аб стане Wi-Fi."</string>
<string name="permlab_changeWifiState" msgid="7280632711057112137">"змяняць стан Wi-Fi"</string>
- <!-- outdated translation 2950383153656873267 --> <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Дазваляе прыкладанням падключацца да кропак доступу Wi-Fi і адключацца ад іх, а таксама ўносіць змены ў наладжаныя сеткі Wi-Fi."</string>
+ <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Дазваляе прыкладанням падлучацца і адключацца ад кропак доступу Wi-Fi і ўносіць змяненні ў наладжаныя сеткі Wi-Fi."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"дазваляе прыём Wi-Fi Multicast"</string>
- <!-- outdated translation 8199464507656067553 --> <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Дазваляе прыкладанням атрымліваць пакеты, не напраўленыя непасрэдна на прыладу. Гэта можа быць карысна пры выяўленні блізкіх паслуг. Гэта выкарыстоўвае больш магутнасцяў, чым рэжым нешматадрасных перадач."</string>
- <!-- outdated translation 1092209628459341292 --> <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"кіраванне bluetooth"</string>
- <!-- outdated translation 3511795757324345837 --> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Дазваляе прыкладанню наладжваць лакальны планшэт Bluetooth, а таксама вызначаць і падключацца да выдаленых прылад."</string>
- <!-- outdated translation 3511795757324345837 --> <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Дазваляе прыкладанню наладжваць лакальны планшэт Bluetooth, а таксама вызначаць і падключацца да выдаленых прылад."</string>
+ <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Дазваляе прыкладаннямм атрымліваць пакеты, якія не былі адрасаваня непасрэдна вашай прыладзе. Гэта можа быць карысна пры выяўленні службаў, даступных побач. У гэтым рэжыме выкарыстоўваецца больш энергіі, чым у рэжыме аднаадраснай перадачы."</string>
+ <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"адмiнiстраванне Bluetooth"</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Дазваляе прыкладанням наладжваць лакальны планшэт Bluetooth, выяўляць і падлучаць выдаленыя прылады."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Дазваляе прыкладанням наладжваць лакальны тэлефон Bluetooth, а таксама знаходзіць выдаленыя прылады i падлучацца да ix."</string>
+ <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Прагляд стану WiMAX"</string>
+ <string name="permdesc_accessWimaxState" msgid="5914958077555177749">"Дазваляе прыкладанням праглядаць інфармацыю пра стан WiMAX."</string>
+ <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Змяніць стан WiMAX"</string>
+ <string name="permdesc_changeWimaxState" msgid="3328853825006455912">"Дазваляе прыкладанням падключацца і адключацца ад сеткі WiMAX."</string>
<string name="permlab_bluetooth" msgid="8361038707857018732">"ствараць злучэнні Bluetooth"</string>
- <!-- outdated translation 4191941825910543803 --> <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Дазваляе прыкладанню праглядаць канфігурацыю лакальнага планшэта Bluetooth, а таксама ствараць і прымаць падключэнні да спалучаных прылад."</string>
- <!-- outdated translation 4191941825910543803 --> <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Дазваляе прыкладанню праглядаць канфігурацыю лакальнага планшэта Bluetooth, а таксама ствараць і прымаць падключэнні да спалучаных прылад."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Дазваляе прыкладанню праглядаць канфігурацыю лакальнага планшэту Bluetooth, а таксама здзяйсняць і прымаць злучэнні са спалучанымі прыладамі."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Дазваляе прыкладанню праглядаць канфігурацыю лакальнага тэлефона Bluetooth, а таксама здзяйсняць і прымаць злучэнні са спалучанымі прыладамі."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"кантроль Near Field Communication"</string>
- <!-- outdated translation 9171401851954407226 --> <string name="permdesc_nfc" msgid="7120611819401789907">"Дазваляе прыкладанню звязвацца з тэгамі, карткамі і чытачамі Near Field Communication (NFC)."</string>
+ <string name="permdesc_nfc" msgid="7120611819401789907">"Дазваляе прыкладаннzv спалучацца з тэгамі, картамі і счытваючымі прыладамі Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="4977406164311535092">"адключаць блакаванне клавіятуры"</string>
- <!-- outdated translation 3189763479326302017 --> <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Дазваляе прыкладанням адключаць блакіроўку клавіятуры і абарону паролем. Добры прыклад гэтага — адключэнне блакіроўкі тэлефона пры атрыманні ўваходнага выкліка тэлефона, паўторнае ўключэнне блакіроўкі клавіятуры, калі выклік завершаны."</string>
+ <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Дазваляе прыкладанням адключаць блакаванне клавіятуры і любыя сродкі абароны, звязаныя з паролем. Прыкладам гэтага з\'яўляецца адключэнне тэлефонам блакавання клавіятуры пры атрыманні ўваходнага выкліку і паўторнае ўключэнне блакавання клавіятуры, калі выклік завершаны."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"чытаць параметры сінхранізацыі"</string>
- <!-- outdated translation 5315925706353341823 --> <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Дазваляе прыкладанням счытваць налады сінхранізацыі (напрыклад, ці ўключана сінхранізацыя для кантактаў)."</string>
+ <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Дазваляе прыкладанням змяняць налады сінхранізацыі, напрыклад, ці будзе сінхранізацыя ўключана для прыкладання People."</string>
<string name="permlab_writeSyncSettings" msgid="6297138566442486462">"запісваць параметры сінхранізацыі"</string>
- <!-- outdated translation 2498201614431360044 --> <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Дазваляе прыкладанням мяняць налады сінхранізацыі, напрыклад дазвол сінхранізацыі для Кантактаў."</string>
+ <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Дазваляе прыкладанню змяняць налады сінхранізацыі, напрыклад, ці будзе сінхранізацыя ўключана для прыкладання People."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"чытаць статыстыку сінхранізацыі"</string>
- <!-- outdated translation 7511448343374465000 --> <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Дазваляе прыкладанням счытваць статыстыку сінхранізацыі, напрыклад гісторыю здзейсненых сінхранізацый."</string>
+ <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Дазваляе прыкладанню счытваць статыстыку сінхранізацыі, напрыклад гісторыю здзейсненых сінхранізацый."</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"чытаць падпісаныя каналы"</string>
- <!-- outdated translation 3622200625634207660 --> <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Дазваляе прыкладанням атрымліваць інфармацыю аб сінхранізацыі бягучых каналаў."</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Дазваляе прыкладанням атрымліваць інфармацыю пра каналы, якія сінхранізуюцца ў бягучы момант."</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"запісваць каналы, на якія ёсць падпіска"</string>
- <!-- outdated translation 8121607099326533878 --> <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Дазваляе прыкладанням змяняць бягучыя сінхранізуемыя каналы. Гэта можа дазволіць шкоднасным прыкладанням змяняць сінхранізаваныя каналы."</string>
- <!-- outdated translation 432535716804748781 --> <string name="permlab_readDictionary" msgid="8410247960433376352">"чытаць карыстальніцкі слоўнік"</string>
- <!-- outdated translation 1082972603576360690 --> <string name="permdesc_readDictionary" msgid="8977815988329283705">"Дазваляе прыкладанням счытваць любыя прыватныя словы, імёны і фразы, якія карыстальнік можа захоўваць у карыстальніцкім слоўніку."</string>
- <!-- outdated translation 6703109511836343341 --> <string name="permlab_writeDictionary" msgid="2296383164914812772">"пісаць у карыстальніцкі слоўнік"</string>
- <!-- outdated translation 2241256206524082880 --> <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дазваляе прыкладанням запісваць новыя словы ў слоўнік карыстальніка."</string>
+ <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Дазваляе прыкладанням змяняць бягучыя каналы сінхранізавання. Шкоднасныя прыкладанні могуць змяняць вашы каналы сінхранізацыi."</string>
+ <string name="permlab_readDictionary" msgid="8410247960433376352">"чытаць карыстальніцкі слоўнік"</string>
+ <string name="permdesc_readDictionary" msgid="8977815988329283705">"Дазваляе прыкладанню счытваць любыя прыватныя словы, імёны і фразы, якія карыстальнік можа захоўваць у карыстальніцкім слоўніку."</string>
+ <string name="permlab_writeDictionary" msgid="2296383164914812772">"запісаць у карыстальніцкі слоўнік"</string>
+ <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дазваляе прыкладанням запісваць новыя словы ў карыстальніцкі слоўнік."</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"змяніць/выдаліць змесціва USB-назапашвальнiка"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"змяняць/выдаляць змесціва SD-карты"</string>
- <!-- outdated translation 6594393334785738252 --> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дазваляе прыкладанню запісваць дадзеныя на USB-назапашвальнiк."</string>
- <!-- outdated translation 6594393334785738252 --> <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дазваляе прыкладанню запісваць дадзеныя на USB-назапашвальнiк."</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дазваляе прыкладаням выконваць запіс ва USB-назапашвальнік."</string>
+ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дазваляе прыкладанням запісваць на SD-карту."</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змяніць/выдаліць унутраныя носьбіты змесціва"</string>
- <!-- outdated translation 8232008512478316233 --> <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дазваляе прыкладанням змяняць змесціва ўнутранага сховішча інфармацыі."</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дазваляе прыкладанням змяняць змесціва ўнутранай памяці."</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"доступ да файлавай сістэмы кэша"</string>
- <!-- outdated translation 1624734528435659906 --> <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Дазваляе прыкладанням чытаць і запісваць дадзеныя ў файлавую сістэму кэша."</string>
+ <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Дазваляе прыкладанню счытваць і выконваць запіс у файлавую сістэму кэш-памяці."</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"рабіць/прымаць iнтэрнэт-выклікі"</string>
- <!-- outdated translation 6320376185606661843 --> <string name="permdesc_use_sip" msgid="4717632000062674294">"Дазваляе прыкладанню выкарыстоўваць службу SIP, каб рабіць/прымаць iнтэрнэт-выклікі."</string>
+ <string name="permdesc_use_sip" msgid="4717632000062674294">"Дазваляе прыкладанням выкарыстоўваць службу SIP, каб прымаць/рабіць Інтэрнэт-выклікі."</string>
<string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"чытаць дадзеныя выкарыстання сеткі"</string>
- <!-- outdated translation 6040738474779135653 --> <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Дазваляе прыкладанням чытаць дадзеныя дзённiка выкарыстання для пэўных сетак і прыкладанняў."</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Дазваляе прыкладанню счытваць дадзеныя аб гісторыі выкарыстання сеткі для пэўных сетак і прыкладанняў."</string>
<string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"кіраванне палітыкай сеткі"</string>
- <!-- outdated translation 3723795285132803958 --> <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Дазваляе прыкладанням кіраваць сеткавымі палітыкамі і вызначаць правілы для прыкладанняў."</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Дазваляе прыкладаннм кіраваць сеткавымі палітыкамі і вызначаць правілы пэўных прыкладанняў."</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"змяніць улік выкарыстання сеткі"</string>
- <!-- outdated translation 8702285686629184404 --> <string name="permdesc_modifyNetworkAccounting" msgid="8553240749784321765">"Дазваляе мадыфікаваць улік выкарыстання сеткі прыкладаннямі. Не для выкарыстання звычайнымі прыкладаннямі."</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дазваляе прыкладанням змяняць метад уліку выкарыстання сеткі прыкладаннямі. Не для выкарыстання звычайнымі прыкладаннямі."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
- <string name="policydesc_limitPassword" msgid="9083400080861728056">"Кіраванне даўжынёй і колькасцю знакаў на экране разблакоўкі пароляў"</string>
+ <string name="policydesc_limitPassword" msgid="3252114203919510394">"Кіраванне даўжынёй і колькасцю знакаў у паролі разблакоўкі экрана."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Сачыць за спробамі разблакоўкі экрана"</string>
- <!-- outdated translation 933601759466308092 --> <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Сачыць за колькасцю няправільных спроб уводу пароляў пры разблакоўцы экрана і блакаваць планшэт або сціраць ўсе дадзеныя на планшэце, калі ўводзіцца занадта шмат няправільных пароляў"</string>
- <!-- outdated translation 933601759466308092 --> <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Сачыць за колькасцю няправільных спроб уводу пароляў пры разблакоўцы экрана і блакаваць планшэт або сціраць ўсе дадзеныя на планшэце, калі ўводзіцца занадта шмат няправільных пароляў"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць планшэт або сціраць усе дадзеныя на ім, калі няправільны пароль набраны занадта шмат разоў."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Сачыць за колькасцю няправільных набраных пароляў падчас разблакоўкі экрана і блакаваць тяэлефон або сціраць усе дадзеныя на ім, калі набрана занадта шмат няправільных пароляў."</string>
<string name="policylab_resetPassword" msgid="2620077191242688955">"Змяненне паролю разблакоўкі экрана"</string>
- <string name="policydesc_resetPassword" msgid="5391240616981297361">"Змяненне паролю разблакоўкі экрана"</string>
+ <string name="policydesc_resetPassword" msgid="605963962301904458">"Змяніць пароль разблакоўкі экрана."</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Заблакаваць экран"</string>
- <string name="policydesc_forceLock" msgid="5696964126226028442">"Кіраванне часам і спосабам блакоўкі экрана"</string>
+ <string name="policydesc_forceLock" msgid="1141797588403827138">"Кіраванне часам і спосабам блакавання экрана"</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"Сцерці ўсе дадзеныя"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Сцерці дадзеныя планшэта без папярэджання, выканаўшы скід налад дадзеных"</string>
- <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Сцерці дадзеныя тэлефона без папярэджання, выканаўшы скід налад дадзеных"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Выдаліць дадзеныя з планшэта без папярэджання, выканаўшы скід налад."</string>
+ <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Выдаліць дадзеныя з тэлефона без папярэджання, выканаўшы скід налад."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Усталяваць глабальны проксі прылады"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Усталяваць глабальны проксі-cервер прылады, які будзе выкарыстоўвацца, калі палітыка актыўная. Толькі першы адміністратар прылады ўсталёўвае эфектыўныя глабальныя проксі-серверы."</string>
<string name="policylab_expirePassword" msgid="885279151847254056">"Нал. тэрм. дз. пар. блак. экр."</string>
- <string name="policydesc_expirePassword" msgid="4844430354224822074">"Кантраляваць, як часта трэба мяняць пароль для блакавання экрана"</string>
+ <string name="policydesc_expirePassword" msgid="1729725226314691591">"Кіраваць частатой змены паролю для блакавання экрана."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"Усталяваць шыфраванне сховішча."</string>
- <!-- outdated translation 2504984732631479399 --> <string name="policydesc_encryptedStorage" msgid="8877192718681120469">"Патрабаваць шыфраванне захаваных дадзеных прыкладання"</string>
+ <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Запыт на шыфраванне захаваных дадзеных прыкладанняў."</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"Адключыць камеры"</string>
- <string name="policydesc_disableCamera" msgid="5680054212889413366">"Забарона выкарыстання ўсіх камер прылады"</string>
+ <string name="policydesc_disableCamera" msgid="2306349042834754597">"Забараніць выкарыстанне ўсіх камер прылады."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Галоўная старонка"</item>
<item msgid="869923650527136615">"Мабільны"</item>
@@ -635,14 +644,14 @@
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Галоўная старонка"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Працоўны"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Іншае"</string>
- <!-- outdated translation 3731488827218876115 --> <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Увядзіце PIN-код"</string>
- <!-- outdated translation 5965173481572346878 --> <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Увядзіце PUK і новы PIN-код"</string>
+ <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Увядзіце PIN-код"</string>
+ <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Увядзіце PUK-код і новы PIN-код"</string>
<string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK"</string>
- <!-- outdated translation 2987350144349051286 --> <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новы PIN-код"</string>
- <!-- outdated translation 7906561917570259833 --> <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Дакраніцеся, каб увесці пароль"</font></string>
- <!-- outdated translation 9138158344813213754 --> <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Увядзіце пароль для разблакавання"</string>
- <!-- outdated translation 638347075625491514 --> <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Увядзіце PIN-код для разблакоўкі"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Няправільны PIN-код"</string>
+ <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Новы PIN-код"</string>
+ <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Дакраніцеся, каб увесці пароль"</font></string>
+ <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Увядзіце пароль для разблакавання"</string>
+ <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Каб разблакаваць, увядзіце PIN-код"</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Няправільны PIN-код."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"Каб разблакаваць, націсніце \"Меню\", затым 0."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Нумар экстранай службы"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Не абслугоўваецца"</string>
@@ -653,8 +662,9 @@
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"Экстраны выклік"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Вярнуцца да выкліку"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Правільна!"</string>
- <!-- outdated translation 4817583279053112312 --> <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Паспрабуйце яшчэ раз"</string>
- <!-- outdated translation 6237443657358168819 --> <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Паспрабуйце яшчэ раз"</string>
+ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Паспрабуйце яшчэ раз"</string>
+ <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Паўтарыце спробу"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Перавышана максімальная колькасць спроб разблакоўкі праз Фэйскантроль"</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Зарадка, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_charged" msgid="4938930459620989972">"Зараджаны."</string>
<string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
@@ -662,9 +672,9 @@
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Няма SIM-карты."</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Няма SIM-карты ў планшэце."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"У тэлефоне няма SIM-карты."</string>
- <!-- outdated translation 8874620818937719067 --> <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Устаўце SIM-карту."</string>
- <!-- outdated translation 7138450788301444298 --> <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-карта адсутнічае ці не чытаецца. Устаўце SIM-карту."</string>
- <!-- outdated translation 1631853574702335453 --> <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Вашая SIM-картка поўнасцю адключаная."\n"Звярніцеся да пастаўшчыка паслуг мабільнай сувязі, каб атрымаць іншую SIM-карту."</string>
+ <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Усталюйце SIM-карту."</string>
+ <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM-карта адсутнічае ці не чытаецца. Устаўце SIM-карту."</string>
+ <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Ваша SIM-карта была адключана назаўсёды."\n" Звяжыцеся з аператарам бесправадной сувязі, каб атрымаць іншую SIM-карту."</string>
<string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Кнопка папярэдняй кампазiцыi"</string>
<string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка наступнай кампазiцыi"</string>
<string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"Кнопка паўзы"</string>
@@ -673,19 +683,14 @@
<string name="emergency_calls_only" msgid="6733978304386365407">"Толькі экстраныя выклікі"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Сетка заблакаваная"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-карта заблакавана PUK-кодам."</string>
- <!-- outdated translation 635967534992394321 --> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Глядзіце Інструкцыю карыстальніка або звяжыцеся са службай падтрымкі."</string>
+ <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Глядзіце \"Інструкцыю для карыстальніка\" або звяжыцеся са службай тэхнiчнай падтрымкі."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM-карта заблакаваная."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Разблакаванне SIM-карты..."</string>
- <!-- no translation found for lockscreen_too_many_failed_attempts_dialog_message (6481623830344107222) -->
- <skip />
- <!-- no translation found for lockscreen_too_many_failed_password_attempts_dialog_message (2725973286239344555) -->
- <skip />
- <!-- no translation found for lockscreen_too_many_failed_pin_attempts_dialog_message (6216672706545696955) -->
- <skip />
- <!-- no translation found for lockscreen_failed_attempts_almost_glogin (9191611984625460820) -->
- <skip />
- <!-- no translation found for lockscreen_failed_attempts_almost_glogin (2590227559763762751) -->
- <skip />
+ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Вы няправільна ўвялі пароль пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Вы няправільна ўвялі PIN-код пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n"Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакаваць планшэт з дапамогай уваходу ў Google."\n\n" Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Вы няправільна ўвялі графічны ключ разблакавання пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакаваць тэлефон з дапамогай уваходу ў Google."\n\n" Паўтарыце спробу праз наступную колькасць секунд: <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Вы няправільна спрабавалі разблакаваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спробаў (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Вы няправільна спрабавалі разблакаваць планшэт некалькi разоў (<xliff:g id="NUMBER_0">%d</xliff:g>). Пасля яшчэ некалькiх спробаў (<xliff:g id="NUMBER_1">%d</xliff:g>) ён будзе скінуты да заводскіх налад i карыстальнiцкiя дадзеныя будуць згубленыя."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Вы няправільна спрабавалі разблакаваць планшэт некалькi разоў (<xliff:g id="NUMBER">%d</xliff:g>). Цяпер ён будзе скінуты да заводскіх налад."</string>
@@ -693,14 +698,14 @@
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Паўтарыце спробу праз <xliff:g id="NUMBER">%d</xliff:g> с."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Забылі ўзор?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Разблакаванне ўліковага запісу"</string>
- <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Занадта шмат спробаў узору!"</string>
- <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Каб разблакаваць, увайдзіце праз уліковы запіс Google"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Занадта шмат спроб паўтарыць шаблон!"</string>
+ <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Каб разблакаваць, увайдзіце ў свой уліковы запіс Google."</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Імя карыстальніка (электронная пошта)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Пароль"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Увайсці"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Няправільнае імя карыстальніка ці пароль."</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Забыліся на імя карыстальніка або пароль?"\n"Наведайце"<b>"google.com/accounts/recovery"</b></string>
- <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Праверка..."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Забыліся на імя карыстальніка або пароль?"\n"Наведайце "<b>"google.com/accounts/recovery"</b></string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Праверка..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Разблакаваць"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Гук уключаны"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Гук выключаны"</string>
@@ -717,14 +722,13 @@
<string name="factorytest_not_system" msgid="4435201656767276723">"Дзеянне FACTORY_TEST падтрымліваецца толькі для пакетаў, усталяваных на шляху /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"Пакет, які выконвае дзеянне FACTORY_TEST, не знойдзены."</string>
<string name="factorytest_reboot" msgid="6320168203050791643">"Перазагрузіць"</string>
- <string name="js_dialog_title" msgid="8143918455087008109">"Старонка з адрасам \"<xliff:g id="TITLE">%s</xliff:g>\" кажа:"</string>
+ <string name="js_dialog_title" msgid="1987483977834603872">"На старонцы з адрасам <xliff:g id="TITLE">%s</xliff:g> вызначана:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
- <!-- no translation found for js_dialog_before_unload (730366588032430474) -->
- <skip />
+ <string name="js_dialog_before_unload" msgid="730366588032430474">"Пакiнуць гэту старонку?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Націсніце \"OK\", каб працягнуць, або \"Адмена\", каб застацца на бягучай старонцы."</string>
<string name="save_password_label" msgid="6860261758665825069">"Пацвердзіць"</string>
- <!-- outdated translation 1068216937244567247 --> <string name="double_tap_toast" msgid="2729045387923870404">"Падказка: націсніце двойчы, каб павялічыць або паменшыць."</string>
- <string name="autofill_this_form" msgid="1272247532604569872">"Аўтазапаўненне"</string>
- <string name="setup_autofill" msgid="8154593408885654044">"Усталёўка аўтазапаўнення"</string>
+ <string name="double_tap_toast" msgid="4595046515400268881">"Падказка: двойчы націсніце, каб павялічыць або паменшыць."</string>
+ <string name="autofill_this_form" msgid="4616758841157816676">"Аўтазапаўненне"</string>
+ <string name="setup_autofill" msgid="7103495070180590814">"Усталяванне аўтазапаўнення"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -742,25 +746,25 @@
<string name="autofill_area" msgid="3547409050889952423">"Плошча"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Эмірат"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"чытаць гісторыю браўзэра і закладак"</string>
- <!-- outdated translation 4981489815467617191 --> <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Дазваляе прыкладанням счытваць усе URL, якія наведвалiся з браўзэра, а таксама ўсе закладкi."</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Дазваляе прыкладанням счытваць усе URL, якія наведвалiся з браўзэра, а таксама ўсе закладкi браўзэра."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"пісаць гісторыю браўзэра і закладак"</string>
- <!-- outdated translation 7193514090469945307 --> <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Дазваляе прыкладанням змяняць гісторыю браўзэра або закладкі, якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэтую магчымасць, каб выдаляць або змяняць дадзеныя вашага браўзэра."</string>
- <!-- outdated translation 7193514090469945307 --> <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Дазваляе прыкладанням змяняць гісторыю браўзэра або закладкі, якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэтую магчымасць, каб выдаляць або змяняць дадзеныя вашага браўзэра."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Дазваляе прыкладанням змяняць гісторыю браўзэра або закладкі, якія захоўваюцца на планшэце. Шкоднасныя прыкладанні могуць выкарыстоўваць гэту магчымасць для выдалення або змены дадзеных вашага браўзэра."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Дазваляе прыкладанням змяняць гісторыю браўзэра або закладак, захаваных у тэлефоне. Шкоднасныя прыкладанні могуць выкарыстоўваць гэту магчымасць для выдалення або змены дадзеных вашага браўзэра."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"Усталяваць сігнал у будзільніку"</string>
- <!-- outdated translation 5966966598149875082 --> <string name="permdesc_setAlarm" msgid="316392039157473848">"Дазваляе прыкладанням задаваць сігнал усталяванага прыкладання будзільніка. Пэўныя прыкладанні будзільніка не могуць рэалізаваць гэтую функцыю."</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"Дазваляе прыкладанню ўсталёўваць сігнал на ўсталяваным прыкладанні будзільніка. Пэўныя прыкладанні будзільніка не могуць рэалізоўваць гэтую магчымасць."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"дадаць галасавое паведамленне"</string>
- <!-- outdated translation 4828507394878206682 --> <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дазваляе праграме дадаваць паведамленні ў паштовую скрыню галасавых паведамленняў."</string>
- <!-- outdated translation 4715212655598275532 --> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Змяніць дазволы геапазіцыянавання для браўзэра"</string>
- <!-- outdated translation 4011908282980861679 --> <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дазваляе прыкладанням змяняць дазволы геалакацыі браўзэра. Шкодныя прыкладанні могуць карыстацца гэтым, каб дазваляць адпраўку інфармацыі аб месцазнаходжанні адвольным вэб-сайтам."</string>
+ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Дазваляе прыкладанням дадаваць паведамленні ў вашу скрыню галасавой пошты."</string>
+ <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"змяніць дазволы геапазіцыянавання для браўзэра"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дазваляе прыкладанням змяняць дазволы геалакацыі браўзэра. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб дазваляць адпраўку інфармацыі аб месцазнаходжанні выпадковым вэб-сайтам."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"верыфікаваць пакеты"</string>
- <!-- outdated translation 6033195477325381106 --> <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Дазваляе прыкладанням правяраць магчымасць усталёўкі пакету."</string>
+ <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Дазваляе прыкладанням правяраць магчымасць усталявання пакету."</string>
<string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"прывязаць да верыфікатару пакету"</string>
- <!-- outdated translation 2409521927385789318 --> <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Дазваляе ўладальніку рабіць запыты верыфікатараў пакету. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Дазваляе ўладальніку рабіць запыты верыфікатараў пакету. Не патрабуецца для звычайных прыкладанняў."</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>
<string name="save_password_never" msgid="8274330296785855105">"Ніколі"</string>
- <!-- outdated translation 5661861460947222274 --> <string name="open_permission_deny" msgid="7374036708316629800">"У вас няма дазволу адкрываць гэтую старонку."</string>
+ <string name="open_permission_deny" msgid="7374036708316629800">"У вас няма дазволу на адкрыццё гэтай старонкі."</string>
<string name="text_copied" msgid="4985729524670131385">"Тэкст скапіяваны ў буфер абмену."</string>
<string name="more_item_label" msgid="4650918923083320495">"Больш"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Меню+"</string>
@@ -859,9 +863,9 @@
<string name="weeks" msgid="6509623834583944518">"тыд."</string>
<string name="year" msgid="4001118221013892076">"год"</string>
<string name="years" msgid="6881577717993213522">"г."</string>
- <!-- outdated translation 3359437293118172396 --> <string name="VideoView_error_title" msgid="5927895235831021723">"Немагчыма прайграць відэа"</string>
- <!-- outdated translation 897920883624437033 --> <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Гэтае відэа не падыходзіць для патокавай перадачы на ​​гэтую прыладу."</string>
- <!-- outdated translation 710301040038083944 --> <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"На жаль, гэтае відэа не можа быць прайграна."</string>
+ <string name="VideoView_error_title" msgid="3534509135438353077">"Праблема з відэа"</string>
+ <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Відэа не падыходзіць для патокавай перадачы на ​​гэту прыладу."</string>
+ <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Немагчыма прайграць гэта відэа."</string>
<string name="VideoView_error_button" msgid="2822238215100679592">"ОК"</string>
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="7245353528818587908">"апоўдні"</string>
@@ -877,7 +881,7 @@
<string name="replace" msgid="5781686059063148930">"Замяніць..."</string>
<string name="delete" msgid="6098684844021697789">"Выдаліць"</string>
<string name="copyUrl" msgid="2538211579596067402">"Скапіяваць URL"</string>
- <!-- outdated translation 6738556348861347240 --> <string name="selectTextMode" msgid="1018691815143165326">"Вылучыць тэкст..."</string>
+ <string name="selectTextMode" msgid="1018691815143165326">"Выбраць тэкст"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Вылучэнне тэксту"</string>
<string name="addToDictionary" msgid="9090375111134433012">"дадаць у слоўнік"</string>
<string name="deleteText" msgid="7070985395199629156">"выдаліць"</string>
@@ -891,57 +895,52 @@
<string name="yes" msgid="5362982303337969312">"ОК"</string>
<string name="no" msgid="5141531044935541497">"Адмяніць"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Увага"</string>
- <!-- outdated translation 1760724998928255250 --> <string name="loading" msgid="7933681260296021180">"Загрузка..."</string>
+ <string name="loading" msgid="7933681260296021180">"Загрузка..."</string>
<string name="capital_on" msgid="1544682755514494298">"Уключыць"</string>
<string name="capital_off" msgid="6815870386972805832">"Адключана"</string>
<string name="whichApplication" msgid="4533185947064773386">"Завяршыць дзеянне з дапамогай"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Выкарыстоўваць па змаўчанні для гэтага дзеяння."</string>
- <!-- outdated translation 4815455344600932173 --> <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ачысціць налады па змаўчанні ў меню \"Налады &gt; Прыкладанні &gt; Кіраванне прыкладаннямі."</string>
- <string name="chooseActivity" msgid="1009246475582238425">"Выберыце дзеянне."</string>
- <!-- outdated translation 7892597146032121735 --> <string name="chooseUsbActivity" msgid="6894748416073583509">"Выберыце праграму для USB-прылады"</string>
- <!-- outdated translation 1691104391758345586 --> <string name="noApplications" msgid="2991814273936504689">"Ніякае прыкладанне не можа выканаць гэтае дзеянне."</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ачысціць па змаўчанні ў раздзеле \"Налады сістэмы &gt; Прыкладанні &gt; Спампаваныя\"."</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"Выберыце дзеянне"</string>
+ <string name="chooseUsbActivity" msgid="6894748416073583509">"Выберыце прыкладанне для USB-прылады"</string>
+ <string name="noApplications" msgid="2991814273936504689">"Няма прыкладанняў, якія могуць выконваць гэты працэс."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"На жаль, прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> спынілася."</string>
<string name="aerr_process" msgid="4507058997035697579">"На жаль, працэс <xliff:g id="PROCESS">%1$s</xliff:g> спыніўся."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
- <!-- no translation found for anr_activity_application (1904477189057199066) -->
- <skip />
- <!-- no translation found for anr_activity_process (5776209883299089767) -->
- <skip />
- <!-- no translation found for anr_application_process (8941757607340481057) -->
- <skip />
- <!-- no translation found for anr_process (6513209874880517125) -->
- <skip />
+ <string name="anr_activity_application" msgid="1904477189057199066">"Прыкладанне <xliff:g id="APPLICATION">%2$s</xliff:g> не адказвае."\n\n"Закрыць яго?"</string>
+ <string name="anr_activity_process" msgid="5776209883299089767">"Працэс <xliff:g id="ACTIVITY">%1$s</xliff:g> не адказвае."\n\n"Закрыць яго?"</string>
+ <string name="anr_application_process" msgid="8941757607340481057">"Прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> не адказвае. Закрыць яго?"</string>
+ <string name="anr_process" msgid="6513209874880517125">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> не адказвае."\n\n"Закрыць яго?"</string>
<string name="force_close" msgid="8346072094521265605">"ОК"</string>
<string name="report" msgid="4060218260984795706">"Справаздача"</string>
<string name="wait" msgid="7147118217226317732">"Чакаць"</string>
- <!-- outdated translation 8323761616052121936 --> <string name="launch_warning_title" msgid="1547997780506713581">"Прыкладанне перанакіраванае"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Старонка не адказвае на запыты."\n\n"Закрыць яе?"</string>
+ <string name="launch_warning_title" msgid="1547997780506713581">"Прыкл. перанакіраванае"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g> зараз запушчанае."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g> запушчанае."</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"Шкала"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"Заўсёды паказваць"</string>
- <!-- outdated translation 2953716574198046484 --> <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Каб зноў уключыць, перайдзіце ў Налады &gt; Прыкладанні &gt; Кіраванне прыкладаннямі."</string>
- <!-- no translation found for smv_application (3307209192155442829) -->
- <skip />
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Зноў уключыце гэта ў раздзеле \"Сістэмныя налады &gt; Прыкладанні &gt; Спампаваныя\"."</string>
+ <string name="smv_application" msgid="3307209192155442829">"Прыкладанне <xliff:g id="APPLICATION">%1$s</xliff:g> (працэс <xliff:g id="PROCESS">%2$s</xliff:g>) парушыла ўласную палітыку StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Працэс <xliff:g id="PROCESS">%1$s</xliff:g> парушыў уласную палітыку StrictMode."</string>
- <!-- outdated translation 378740715658358071 --> <string name="android_upgrading_title" msgid="1584192285441405746">"Абнаўленне Android..."</string>
- <!-- no translation found for android_upgrading_apk (7904042682111526169) -->
- <skip />
- <!-- outdated translation 7959542881906488763 --> <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск прыкладанняў."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Абнаўленне Android..."</string>
+ <string name="android_upgrading_apk" msgid="7904042682111526169">"Аптымізацыя прыкладання <xliff:g id="NUMBER_0">%1$d</xliff:g> з <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Запуск прыкладанняў."</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Завяршэнне загрузкі."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"Прыкладанне \"<xliff:g id="APP">%1$s</xliff:g>\" запушчанае"</string>
- <!-- outdated translation 2423977499339403402 --> <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Выберыце, каб пераключыцца да прыкладання"</string>
- <!-- outdated translation 1135403633766694316 --> <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Пераключыць прыкладанні?"</string>
- <!-- outdated translation 4592075610079319667 --> <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Ужо запушчана іншае прыкладанне, якое павінна быць спыненае перад запускам новага."</string>
+ <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Націсніце, каб перайсці да прыкладання"</string>
+ <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Пераключыць прыкладанні?"</string>
+ <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Ужо запушчана іншае прыкладанне, якое павінна быць спынена перад запускам новага."</string>
<string name="old_app_action" msgid="493129172238566282">"Вярнуцца да <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <!-- outdated translation 942967900237208466 --> <string name="old_app_description" msgid="2082094275580358049">"Не запускайце новае прыкладанне."</string>
+ <string name="old_app_description" msgid="2082094275580358049">"Не запускайце новыя прыкладанні."</string>
<string name="new_app_action" msgid="5472756926945440706">"Запусціць <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <!-- outdated translation 6830398339826789493 --> <string name="new_app_description" msgid="1932143598371537340">"Спыніць старое прыкладанне, не захоўваючы яго."</string>
- <string name="sendText" msgid="5132506121645618310">"Выберыце дзеянне для тэксту"</string>
+ <string name="new_app_description" msgid="1932143598371537340">"Спыніць старыя прыкладанні без захавання."</string>
+ <string name="sendText" msgid="5209874571959469142">"Выберыце дзеянне для тэкста"</string>
<string name="volume_ringtone" msgid="6885421406845734650">"Гучнасць званка"</string>
<string name="volume_music" msgid="5421651157138628171">"Гучнасць прайгравальніка"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Прайграваецца праз Bluetooth"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"Выбрана ціхая мелодыя"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Усталяваны ціхі рэжым"</string>
<string name="volume_call" msgid="3941680041282788711">"Гучнасць падчас размовы"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"Гучнасць Bluetooth падчас выкліку"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Гучнасць будзільніка"</string>
@@ -965,30 +964,35 @@
<item quantity="one" msgid="1634101450343277345">"Адкрытая сетка Wi-Fi даступная"</item>
<item quantity="other" msgid="7915895323644292768">"Даступны адкрытыя сеткі Wi-Fi"</item>
</plurals>
- <string name="wifi_available_sign_in" msgid="9157196203958866662">"Уваход у сетку Wi-Fi"</string>
+ <string name="wifi_available_sign_in" msgid="4029489716605255386">"Увайдзіце ў сетку Wi-Fi"</string>
<!-- no translation found for wifi_available_sign_in_detailed (6797764740339907572) -->
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Немагчыма падключыцца да Wi-Fi"</string>
- <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" дрэннае падключэнне да Інтэрнэту."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" дрэннае падключэнне да Інтэрнэту."</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
- <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Пачаць работу Wi-Fi Direct. Гэта адключыць Wi-Fi кліента/кропку доступу."</string>
- <string name="wifi_p2p_failed_message" msgid="1820097493844848281">"Немагчыма запусціць Wi-Fi Direct"</string>
- <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"Запыт злучэння Wi-Fi Direct ад <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Націсніце \"ОК\", каб прыняць."</string>
- <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Запыт злучэння Wi-Fi Direct ад <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Увядзіце PIN-код для працягу."</string>
- <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Для працягу настройкі злучэння неабходна ўвесці PIN-код WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> на аднарангавай прыладзе <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g>"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Пачаць работу Wi-Fi Direct. Гэта адключыць кліента або кропку доступу Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Немагчыма запусціць Wi-Fi Direct."</string>
+ <string name="accept" msgid="1645267259272829559">"Прыняць"</string>
+ <string name="decline" msgid="2112225451706137894">"Адхіліць"</string>
+ <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Запрашэнне адпраўлена"</string>
+ <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Запрашэнне далучыцца"</string>
+ <string name="wifi_p2p_from_message" msgid="570389174731951769">"Ад:"</string>
+ <string name="wifi_p2p_to_message" msgid="248968974522044099">"Каму:"</string>
+ <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Увядзіце патрэбны PIN-код:"</string>
+ <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-код"</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct уключаны"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Дакраніцеся, каб наладзіць"</string>
<string name="select_character" msgid="3365550120617701745">"Уставіць сімвал"</string>
- <!-- outdated translation 7630529934366549163 --> <string name="sms_control_default_app_name" msgid="3058577482636640465">"Невядомае прыкладанне"</string>
+ <string name="sms_control_default_app_name" msgid="3058577482636640465">"Невядомае прыкладанне"</string>
<string name="sms_control_title" msgid="7296612781128917719">"Адпраўка SMS"</string>
- <!-- outdated translation 1289331457999236205 --> <string name="sms_control_message" msgid="4073755190243093924">"Адпраўляецца вялікая колькасць SMS. Выберыце \"OK\", каб працягнуць, ці \"Адмена\", каб спыніць адпраўку."</string>
+ <string name="sms_control_message" msgid="4073755190243093924">"Адпраўляецца вялікая колькасць SMS-паведамленняў. Націсніце \"OK\", каб працягнуць, ці \"Адмена\", каб спыніць адпраўку."</string>
<string name="sms_control_yes" msgid="2532062172402615953">"ОК"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Адмяніць"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-карта выдаленая"</string>
<string name="sim_removed_message" msgid="2333164559970958645">"Мабільная сетка будзе недаступная да перазагрузкі з дзеючай SIM-картай."</string>
<string name="sim_done_button" msgid="827949989369963775">"Гатова"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM-карта дадазеная"</string>
- <string name="sim_added_message" msgid="1209265974048554242">"Для доступу да мабільнай сеткі неабходна перазагрузіць прыладу."</string>
+ <string name="sim_added_message" msgid="6599945301141050216">"Перазагрузіце прыладу, каб атрымаць доступ да мабільнай сеткі."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"Перазапусціць"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Усталяваць час"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Усталяваць дату"</string>
@@ -997,40 +1001,40 @@
<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>
- <string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-назапашвальнік"</string>
+ <string name="usb_storage_activity_title" msgid="4465055157209648641">"Унiверсальны USB-назапашвальнік"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB падлучаны"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Вы падключыліся да кампутара праз USB. Націсніце кнопку ніжэй, калі вы хочаце капіраваць файлы з кампутара і USB-назапашвальнiка Android."</string>
- <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Вы падключыліся да кампутара праз USB. Націсніце кнопку ніжэй, калі хочаце капіяваць файлы з кампутара і вашай SD-карты Android."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Вы падлучаны да камп\'ютара праз USB. Націсніце на кнопку ніжэй, калі жадаеце капіраваць файлы з камп\'ютара на USB-назапашвальнік прылады Android і наадварот."</string>
+ <string name="usb_storage_message" product="default" msgid="805351000446037811">"Вы падключыліся да камп\'ютара праз USB. Націсніце на кнопку ніжэй, калі вы жадаеце скапіраваць файлы з камп\'ютара на SD-карту прылады Android і наадварот."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Уключыць USB-назапашвальнiк"</string>
- <string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Праблема з выкарыстаннем USB-назапашвальнiка для прылады захоўвання дадзеных USB."</string>
- <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Праблема з выкарыстаннем SD-карты для USB-назапашвальнiка дадзеных."</string>
+ <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Паўстала праблема з выкарыстаннем USB-назапашвальнiка ва ўнiверсальным USB-назапашвальнiку."</string>
+ <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Паўстала праблема выкарыстання SD-карты ва ўнiверсальным USB-назапашвальнiку."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB падключаны"</string>
- <string name="usb_storage_notification_message" msgid="7380082404288219341">"Выберыце файлы для капіявання паміж тэлефонам і кампутарам."</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Дакраніцеся, каб капіяваць файлы з камп\'ютара цi на яго."</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Выключыць USB-назапашвальнiк"</string>
- <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Выберыце, каб адключыць гэты USB-назапашвальнiк."</string>
+ <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Націсніце, каб адключыць USB-назапашвальнік."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"USB-назапашвальнік выкарыстоўваецца"</string>
- <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"Перш чым адключыць USB-назпашвальнiк, пераканайцеся, што вы адключылі (...выцягнулі...) USB-назапашвальнiк Android з кампутара."</string>
- <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"Перш чым адключыць USB-назапашвальнік, пераканайцеся, што SD-карта Android адключана ад кампутара."</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Перш чым адключыць USB-назапашвальнік, адключыце(\"вымiце\") USB-назапашвальнік прылады Android ад камп\'ютара."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Перш чым адключыць USB-назапашвальнік, адключыце(\"вымiце\") SD-карту вашай прылады Android з камп\'ютара."</string>
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Адключыць USB-назапашвальнiк"</string>
- <string name="usb_storage_stop_error_message" msgid="143881914840412108">"Праблема адключэння USB-назапашвальнiка. Пераканайцеся ў тым, што вы адлучылі хост USB, а затым паўтарыце спробу."</string>
+ <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Памылка адключэння USB-назапашвальніка. Пераканайцеся, што вы адключылі хост USB, а потым паўтарыце спробу."</string>
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Падключыць USB-назапашвальнiк"</string>
- <!-- outdated translation 3202838234780505886 --> <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"Калі вы падлучыце USB-назапашвальнік, некаторыя прыкладанні, якія вы выкарыстоўваеце, спыняцца і могуць быць недаступныя, пакуль USB-назапашвальнік не будзе адключаны."</string>
+ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Калі вы ўключыце USB-назапашвальнік, некаторыя прыкладанні, якія вы выкарыстоўваеце, спыняцца і могуць быць недаступныя, пакуль USB-назапашвальнік не будзе адключаны."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Памылка працы USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ОК"</string>
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Падлучана як медыя-прылада"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Падключаны як камера"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Падлучаны як усталявальнік"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Падключаны да USB-прылады"</string>
- <string name="usb_notification_message" msgid="4447869605109736382">"Націсніце, каб убачыць параметры USB"</string>
- <!-- outdated translation 7980995592595097841 --> <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Фарматаваць USB-назапашвальнiк"</string>
- <!-- outdated translation 7980995592595097841 --> <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Фарматаваць USB-назапашвальнiк"</string>
- <!-- outdated translation 8296908079722897772 --> <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Фарматаваць USB-назапашвальнiк, выдаліўшы ўсе файлы, якія захоўваюцца там? Адмянiць нельга"</string>
- <!-- outdated translation 8296908079722897772 --> <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Фарматаваць USB-назапашвальнiк, выдаліўшы ўсе файлы, якія захоўваюцца там? Адмянiць нельга"</string>
+ <string name="usb_notification_message" msgid="2290859399983720271">"Націсніце, каб убачыць іншыя параметры USB."</string>
+ <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Фарматаваць USB-назапашвальнiк?"</string>
+ <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Фарматаваць SD-карту?"</string>
+ <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Усе файлы, якія захоўваюцца на вашым USB-назапашвальніку, будуць выдалены. Гэта дзеянне не можа быць адменена."</string>
+ <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Усе дадзеныя на карце будуць страчаны."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Фармат"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Прылада адладкі USB падключана"</string>
- <!-- outdated translation 8592219392855947984 --> <string name="adb_active_notification_message" msgid="1016654627626476142">"Гэты кіёск абсталяваны Nexus S."</string>
- <!-- outdated translation 6865512749462072765 --> <string name="select_input_method" msgid="4653387336791222978">"Выберыце метад уводу"</string>
- <!-- outdated translation 6324843080254191535 --> <string name="configure_input_methods" msgid="9091652157722495116">"Налада метадаў уводу"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Націсніце, каб адключыць адладку USB."</string>
+ <string name="select_input_method" msgid="4653387336791222978">"Выберыце метад уводу"</string>
+ <string name="configure_input_methods" msgid="9091652157722495116">"Наладзіць метады ўводу"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string>
@@ -1039,12 +1043,12 @@
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Праверка на наяўнасць памылак."</string>
<string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Пусты USB-назапашвальнiк"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Пустая SD-карта"</string>
- <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"USB-назапашвальнiк пусты або файлавая сістэма не падтрымліваецца."</string>
- <string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"SD-карта пустая, або файлавая сістэма не падтрымліваецца."</string>
+ <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB-назапашвальнік пусты або мае файлавую сістэму, якая не падтрымліваецца."</string>
+ <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD-карта пустая або мае файлавую сістэму, якая не падтрымліваецца."</string>
<string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Пашкоджаны USB-назапашвальнiк"</string>
<string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"SD-карта пашкоджаная"</string>
- <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="529021299294450667">"USB-назапашвальнiк пашкоджаны. Магчыма, вам прыйдзецца яго перафарматаваць."</string>
- <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"SD-карта пашкоджаная. Магчыма, вам прыйдзецца перафарматаваць яе."</string>
+ <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB-назапашвальнік пашкоджаны. Паспрабуйце адфарматаваць яго."</string>
+ <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD-карта пашкоджана. Паспрабуйце адфарматаваць яе."</string>
<string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB-назапашвальнiк нечакана быў выдалены"</string>
<string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD-карта была нечакана выдалена"</string>
<string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Адключыце USB-назапашвальнiк, перш чым выцягваць яго, каб пазбегнуць страты дадзеных."</string>
@@ -1057,13 +1061,13 @@
<string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD-карта выдаленая"</string>
<string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB-назапашвальнiк выдалены. Уставіць новыя носьбіты."</string>
<string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD-карта выдаленая. Устаўце новую."</string>
- <string name="activity_list_empty" msgid="4168820609403385789">"Няма адпаведных дзеянняў"</string>
+ <string name="activity_list_empty" msgid="1675388330786841066">"Адпаведныя дзеянні не знойдзены."</string>
<string name="permlab_pkgUsageStats" msgid="8787352074326748892">"абнавіць статыстыку выкарыстання кампанентаў"</string>
- <!-- outdated translation 891553695716752835 --> <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Дазваляе мяняць сабраную статыстыку выкарыстання кампанента. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
- <!-- outdated translation 1660908117394854464 --> <string name="permlab_copyProtectedData" msgid="4341036311211406692">"Дазваляе выклікаць службы кантэйнера па змаўчанні для капіявання змесціва. Не выкарыстоўваецца звычайнымi прыкладаннямi."</string>
- <!-- outdated translation 537780957633976401 --> <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дазваляе выклікаць службы кантэйнера па змаўчанні для капіявання змесціва. Не выкарыстоўваецца звычайнымi прыкладаннямi."</string>
- <!-- outdated translation 1311810005957319690 --> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Націсніце двойчы, каб кіраваць маштабаваннем"</string>
- <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Памылка ўключэння віджэту"</string>
+ <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Дазваляе прыкладанням змяняць сабраную статыстыку выкарыстання кампанентаў. Не для выкарыстання звычайнымі прыкладаннямі."</string>
+ <string name="permlab_copyProtectedData" msgid="4341036311211406692">"капіяваць змесціва"</string>
+ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Дазваляе прыкладанням выклікаць службу захавання па змаўчанні для капіявання змесціва. Не выкарыстоўваецца звычайнымі прыкладаннямі."</string>
+ <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Двойчы дакраніцеся, каб змянiць маштаб"</string>
+ <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Немагчыма дадаць віджэт."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Пачаць"</string>
<string name="ime_action_search" msgid="658110271822807811">"Пошук"</string>
<string name="ime_action_send" msgid="2316166556349314424">"Адправіць"</string>
@@ -1073,37 +1077,37 @@
<string name="ime_action_default" msgid="2840921885558045721">"Выканаць"</string>
<string name="dial_number_using" msgid="5789176425167573586">"Набраць нумар"\n"з выкарыстаннем <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="4947405226788104538">"Стварыць кантакт"\n"з дапамогай<xliff:g id="NUMBER">%s</xliff:g>"</string>
- <!-- outdated translation 6824538733852821001 --> <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Гэтыя адно або некалькі прыкладанняў пытаюцца дазволу на доступ да вашага ўліковага запісу цяпер і ў будучыні."</string>
+ <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Гэтыя адно або некалькі прыкладанняў запытваюць дазвол на доступ да вашага ўліковага запісу цяпер і ў будучыні."</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Дазволіць гэты запыт?"</string>
- <string name="grant_permissions_header_text" msgid="2722567482180797717">"Запыт на доступ"</string>
+ <string name="grant_permissions_header_text" msgid="6874497408201826708">"Запыт на доступ"</string>
<string name="allow" msgid="7225948811296386551">"Дазволіць"</string>
<string name="deny" msgid="2081879885755434506">"Забараніць"</string>
- <string name="permission_request_notification_title" msgid="5390555465778213840">"Запытаны дазвол"</string>
- <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Запытаны дазвол"\n"для ўліковага запісу<xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+ <string name="permission_request_notification_title" msgid="6486759795926237907">"Дазвол запытаны"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Запытаны дазвол"\n"для ўліковага запісу <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"Метад уводу"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Сінхранізацыя"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Спецыяльныя магчымасці"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Шпалеры"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Змена шпалер"</string>
- <string name="vpn_title" msgid="8219003246858087489">"VPN актываваны."</string>
+ <string name="vpn_title" msgid="19615213552042827">"VPN актываваны"</string>
<string name="vpn_title_long" msgid="6400714798049252294">"VPN актывуецца прыкладаннем <xliff:g id="APP">%s</xliff:g>"</string>
- <string name="vpn_text" msgid="1610714069627824309">"Націсніце, каб кіраваць сеткай."</string>
- <string name="vpn_text_long" msgid="4907843483284977618">"Падлучаны да <xliff:g id="SESSION">%s</xliff:g>. Націсніце, каб кiраваць сеткай."</string>
+ <string name="vpn_text" msgid="3011306607126450322">"Дакраніцеся, каб кіраваць сеткай."</string>
+ <string name="vpn_text_long" msgid="6407351006249174473">"Падлучаны да сеанса \"<xliff:g id="SESSION">%s</xliff:g>\". Дакраніцеся, каб кiраваць сеткай."</string>
<string name="upload_file" msgid="2897957172366730416">"Выберыце файл"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Файл не выбраны"</string>
<string name="reset" msgid="2448168080964209908">"Скінуць"</string>
<string name="submit" msgid="1602335572089911941">"Перадаць"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Рэжым \"У машыне\" ўключаны"</string>
- <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Выберыце, каб выйсці з рэжыму \"Ў аўтамабілі\"."</string>
+ <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Дакраніцеся, каб выйсці з рэжыму \"Штурман\"."</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"USB-мадэм або кропка доступу Wi-Fi актыўныя"</string>
- <string name="tethered_notification_message" msgid="3067108323903048927">"Націсніце, каб змяніць налады"</string>
+ <string name="tethered_notification_message" msgid="6857031760103062982">"Націсніце, каб наладзіць."</string>
<string name="back_button_label" msgid="2300470004503343439">"Назад"</string>
<string name="next_button_label" msgid="1080555104677992408">"Далей"</string>
<string name="skip_button_label" msgid="1275362299471631819">"Прапусціць"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"Інтэнсіўнае выкарыстанне перадачы дадзеных праз мабільную сетку"</string>
- <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Націсніце, каб даведацца больш аб выкарыстанні перадачы дадзеных праз мабільную сетку"</string>
+ <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Націсніце, каб атрымаць дадатковыя звесткі аб выкарыстанні мабiльнай перадачы дадзеных."</string>
<string name="throttled_notification_title" msgid="6269541897729781332">"Ліміт мабільнай перадачы дадзеных перавышаны"</string>
- <string name="throttled_notification_message" msgid="4712369856601275146">"Націсніце, каб даведацца больш аб выкарыстанні перадачы дадзеных праз мабільную сетку"</string>
+ <string name="throttled_notification_message" msgid="5443457321354907181">"Націсніце, каб атрымаць дадатковыя звесткі аб выкарыстанні мабiльнай перадачы дадзеных."</string>
<string name="no_matches" msgid="8129421908915840737">"Няма супадзенняў"</string>
<string name="find_on_page" msgid="1946799233822820384">"Знайсці на старонцы"</string>
<plurals name="matches_found">
@@ -1111,10 +1115,10 @@
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> з <xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Гатова"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Адключэнне USB-назапашвальнiка..."</string>
- <string name="progress_unmounting" product="default" msgid="5556813978958789471">"Адключэнне SD-карты..."</string>
- <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Ачышчэнне USB-назапашвальнiка..."</string>
- <string name="progress_erasing" product="default" msgid="2115214724367534095">"Ачышчэнне SD-карты..."</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Адключэнне USB-назапашвальнiка..."</string>
+ <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Адключэнне SD-карты..."</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Выдаленне дадзеных з USB-назапашвальнiка..."</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"Выдаленне дадзеных з SD-карты..."</string>
<string name="format_error" product="nosdcard" msgid="6299769563624776948">"Немагчыма ачысцiць USB-назапашвальнік."</string>
<string name="format_error" product="default" msgid="7315248696644510935">"Немагчыма ачысцiць SD-карту."</string>
<string name="media_bad_removal" msgid="7960864061016603281">"SD-карта была вынутая да адключэння"</string>
@@ -1133,17 +1137,17 @@
<string name="gpsVerifYes" msgid="2346566072867213563">"Так"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"Не"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"Выдаліць перавышаны ліміт"</string>
- <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Ёсць выдаленыя элементы (<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>) для тыпу сiнхранiзацыi <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, уліковы запіс <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Што вы хочаце зрабіць?"</string>
- <string name="sync_really_delete" msgid="8933566316059338692">"Выдаліць элементы."</string>
- <string name="sync_undo_deletes" msgid="8610996708225006328">"Скасаваць выдаленне."</string>
- <string name="sync_do_nothing" msgid="8717589462945226869">"Нічога зараз не рабіць."</string>
- <!-- outdated translation 4191313562041125787 --> <string name="choose_account_label" msgid="5655203089746423927">"Выберыце ўліковы запіс"</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Выдалена элементаў для тыпу сінхранiзацыi \"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>\": <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Уліковы запіс <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Што вы жадаеце зрабіць?"</string>
+ <string name="sync_really_delete" msgid="2572600103122596243">"Выдаліць элементы."</string>
+ <string name="sync_undo_deletes" msgid="2941317360600338602">"Скасаваць выдаленні"</string>
+ <string name="sync_do_nothing" msgid="3743764740430821845">"Нічога зараз не рабіць"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"Выберыце ўліковы запіс"</string>
<string name="add_account_label" msgid="2935267344849993553">"Дадаць уліковы запіс"</string>
- <string name="choose_account_text" msgid="6891230675141555481">"Які ўліковы запіс вы хацелі б выкарыстоўваць?"</string>
+ <string name="choose_account_text" msgid="6303348737197849675">"Які ўліковы запіс вы жадаеце выкарыстоўваць?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Дадаць уліковы запіс"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Інкрэмент"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Дэкрэмент"</string>
- <string name="number_picker_increment_scroll_mode" msgid="1343063395404990189">"Націсніце і ўтрымлівайце кнопку <xliff:g id="VALUE">%s</xliff:g>."</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Націсніце і ўтрымлівайце <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перасуньце палец уверх, каб павялiчыць адрэзак, або ўніз, каб паменшыць."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На хвiлiну больш"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На хвiлiну менш"</string>
@@ -1172,10 +1176,10 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Змена рэжыму"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <!-- outdated translation 4540794444768613567 --> <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Выберыце прыкладанне"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Выберыце прыкладанне"</string>
<string name="shareactionprovider_share_with" msgid="806688056141131819">"Апублікаваць з дапамогай"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Адправiць з дапамогай прыкладання <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
- <!-- outdated translation 7311938669217173870 --> <string name="content_description_sliding_handle" msgid="415975056159262248">"Ручка для перасоўвання. Націсніце і ўтрымлівайце."</string>
+ <string name="content_description_sliding_handle" msgid="415975056159262248">"Ручка для перасоўвання. Націсніце і ўтрымлівайце."</string>
<string name="description_direction_up" msgid="1983114130441878529">"Уверх да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_down" msgid="4294993639091088240">"Уніз да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="6814008463839915747">"Улева да <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1185,29 +1189,29 @@
<string name="description_target_silent" msgid="893551287746522182">"Ціхі рэжым"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Гук уключаны"</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"Прагартайце, каб разблакаваць."</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Каб праслухаць паролi, падключыце гарнiтуру."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Каб праслухаць паролi, падключыце гарнiтуру."</string>
<string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Кропка."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Перайсці да пачатковай старонкі"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Перайсці ўверх"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Больш налад"</string>
- <string name="storage_internal" msgid="7556050805474115618">"Унутраная памяць"</string>
- <string name="storage_sd_card" msgid="8921771478629812343">"SD-карта"</string>
+ <string name="storage_internal" msgid="4891916833657929263">"Унутраная памяць"</string>
+ <string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
<string name="storage_usb" msgid="3017954059538517278">"USB-назапашвальнік"</string>
- <string name="extract_edit_menu_button" msgid="302060189057163906">"Рэдагаваць..."</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"Рэдагаваць"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Папярэджанне выкарыстання дадзеных"</string>
- <string name="data_usage_warning_body" msgid="7217480745540055170">"Дакраніцеся, каб прагледзець выкарыстанне і налады"</string>
+ <string name="data_usage_warning_body" msgid="2814673551471969954">"Дакраніцеся, каб прагледзець гісторыю выкарыстання і налады."</string>
<string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Перадача дадз. 2G-3G выключана"</string>
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Перадача дадзеных 4G выключана"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мабільная перадача дадз. выкл."</string>
<string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Перад. дадз. Wi-Fi адключаная"</string>
- <string name="data_usage_limit_body" msgid="4313857592916426843">"Націсніце, каб уключыць"</string>
+ <string name="data_usage_limit_body" msgid="3317964706973601386">"Націсніце, каб уключыць."</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Перавышаны ліміт 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Перавышаны ліміт дадзеных 4G"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Перавышаны ліміт мабільных дадзеных"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Перав. ліміт па дадзеным Wi-Fi"</string>
- <string name="data_usage_limit_snoozed_body" msgid="2932736326652880660">"<xliff:g id="SIZE">%s</xliff:g> звыш устаноўленай мяжы"</string>
+ <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Аб\'ём <xliff:g id="SIZE">%s</xliff:g> перавышае устаноўл. мяжу."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Зыходныя дадзеныя абмежаваныя"</string>
- <string name="data_usage_restricted_body" msgid="5087354814839059798">"Націсніце, каб зняць абмежаванне"</string>
+ <string name="data_usage_restricted_body" msgid="6741521330997452990">"Націсніце, каб зняць абмежаванне."</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Сертыфікат бяспекі"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Гэты сертыфікат сапраўдны."</string>
<string name="issued_to" msgid="454239480274921032">"Выдадзены:"</string>
@@ -1222,9 +1226,12 @@
<string name="fingerprints" msgid="4516019619850763049">"Адбіткі пальцаў:"</string>
<string name="sha256_fingerprint" msgid="4391271286477279263">"Адбітак пальцаў SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Адбіткі пальцаў SHA-1:"</string>
- <!-- outdated translation 180268188117163072 --> <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Глядзець усе..."</string>
- <!-- outdated translation 3325054276356556835 --> <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Выберыце дзеянне"</string>
- <!-- outdated translation 1791316789651185229 --> <string name="share_action_provider_share_with" msgid="5247684435979149216">"Апублікаваць праз..."</string>
+ <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Прагледзець усё"</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Выберыце працэс"</string>
+ <string name="share_action_provider_share_with" msgid="5247684435979149216">"Апублікаваць з дапамогай"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Прылада заблакаваная."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
+ <string name="sending" msgid="3245653681008218030">"Адпраўка..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
+ <string name="SetupCallDefault" msgid="5834948469253758575">"Прыняць выклік?"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 8cc9ba3cd79c..6bec103442d7 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Подаване на сигнал"</string>
<string name="wait" msgid="7147118217226317732">"Изчакване"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Страницата не отговаря."\n\n"Искате ли да я затворите?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Приложението се пренасочи"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Първоначално бе стартирано: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4f2aef880f66..8dced70dcf0f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"D\'acord"</string>
<string name="report" msgid="4060218260984795706">"Informe"</string>
<string name="wait" msgid="7147118217226317732">"Espera"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"La pàgina ha deixat de respondre."\n\n"Vols tancar-la?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicació redirigida"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> es va iniciar originalment."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index bfcf23f8a596..e21de4b556ce 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Nahlásit"</string>
<string name="wait" msgid="7147118217226317732">"Počkat"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Stránka nereaguje."\n\n"Chcete ji zavřít?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Přesměrování aplikace"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Je spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Původně byla spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 67b24bc4850d..1175cbbe2033 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -140,7 +140,7 @@
<string name="silent_mode_silent" msgid="319298163018473078">"Ringeren er deaktiveret"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"Ringervibrering"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"Ringeren er aktiveret"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"Lukker ned ..."</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"Lukker ned..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Din tabletcomputer slukkes nu."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Din telefon slukkes nu."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Vil du slukke?"</string>
@@ -881,7 +881,7 @@
<string name="replace" msgid="5781686059063148930">"Erstat..."</string>
<string name="delete" msgid="6098684844021697789">"Slet"</string>
<string name="copyUrl" msgid="2538211579596067402">"Kopier webadresse"</string>
- <string name="selectTextMode" msgid="1018691815143165326">"Marker tekst"</string>
+ <string name="selectTextMode" msgid="1018691815143165326">"Markér tekst"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstmarkering"</string>
<string name="addToDictionary" msgid="9090375111134433012">"føj til ordbog"</string>
<string name="deleteText" msgid="7070985395199629156">"slet"</string>
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Rapporter"</string>
<string name="wait" msgid="7147118217226317732">"Vent"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Siden svarer ikke."\n\n"Vil du lukke den?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Appen er omdirigeret"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører nu."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> blev oprindeligt åbnet."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 7c8532328cc5..953897ce07de 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -684,7 +684,7 @@
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Netzwerk gesperrt"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"PUK-Sperre auf SIM"</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Weitere Informationen erhalten Sie im Nutzerhandbuch oder beim Kundendienst."</string>
- <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Bitte PIN eingeben"</string>
+ <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"PIN eingeben"</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-Karte wird entsperrt..."</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Sie haben Ihr Entsperrungsmuster <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch gezeichnet. "\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Sie haben Ihr Passwort <xliff:g id="NUMBER_0">%d</xliff:g>-mal falsch eingegeben."\n\n"Bitte versuchen Sie es in <xliff:g id="NUMBER_1">%d</xliff:g> Sekunden noch einmal."</string>
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Bericht"</string>
<string name="wait" msgid="7147118217226317732">"Warten"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Die Seite reagiert nicht mehr."\n\n"Möchten Sie die Seite schließen?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"App umgeleitet"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird jetzt ausgeführt."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> wurde ursprünglich gestartet."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index aa07f3b7594d..458517ccdc3d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"ΟΚ"</string>
<string name="report" msgid="4060218260984795706">"Αναφορά"</string>
<string name="wait" msgid="7147118217226317732">"Αναμονή"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Η σελίδα δεν ανταποκρίνεται πια."\n\n"Θέλετε να την κλείσετε;"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Ανακατεύθυνση εφαρμογής"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται τώρα."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Έγινε εκκίνηση πρώτα της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index c1f1b401710d..d48f54418fa4 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Report"</string>
<string name="wait" msgid="7147118217226317732">"Wait"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"The page has become unresponsive."\n\n"Do you want to close it?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"App redirected"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is now running."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was originally launched."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index c7f86d091979..c66dc8ef0267 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -86,8 +86,8 @@
<string name="serviceClassDataSync" msgid="7530000519646054776">"Sincronización"</string>
<string name="serviceClassPacket" msgid="6991006557993423453">"Paquete"</string>
<string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
- <string name="roamingText0" msgid="7170335472198694945">"Indicador de roaming encendido"</string>
- <string name="roamingText1" msgid="5314861519752538922">"Indicador de roaming apagado"</string>
+ <string name="roamingText0" msgid="7170335472198694945">"Indicador de roaming activado"</string>
+ <string name="roamingText1" msgid="5314861519752538922">"Indicador de roaming desactivado"</string>
<string name="roamingText2" msgid="8969929049081268115">"Indicador de roaming titilando"</string>
<string name="roamingText3" msgid="5148255027043943317">"Fuera del vecindario"</string>
<string name="roamingText4" msgid="8808456682550796530">"Fuera de construcción"</string>
@@ -97,8 +97,8 @@
<string name="roamingText8" msgid="5989569778604089291">"Roaming: socio premium"</string>
<string name="roamingText9" msgid="7969296811355152491">"Roaming: funcionalidad de servicio completa"</string>
<string name="roamingText10" msgid="3992906999815316417">"Roaming: funcionalidad de servicio parcial"</string>
- <string name="roamingText11" msgid="4154476854426920970">"Banner de roaming encendido"</string>
- <string name="roamingText12" msgid="1189071119992726320">"Banner de roaming apagado"</string>
+ <string name="roamingText11" msgid="4154476854426920970">"Banner de roaming activado"</string>
+ <string name="roamingText12" msgid="1189071119992726320">"Banner de roaming desactivado"</string>
<string name="roamingTextSearching" msgid="8360141885972279963">"Buscando servicio"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: no se ha remitido"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -128,13 +128,13 @@
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronización"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Demasiadas eliminaciones de <xliff:g id="CONTENT_TYPE">%s</xliff:g>"</string>
<string name="low_memory" product="tablet" msgid="6494019234102154896">"Se ha agotado el espacio de almacenamiento de la tableta. Elimina algunos archivos para liberar espacio."</string>
- <string name="low_memory" product="default" msgid="3475999286680000541">"Se ha agotado el espacio de almacenamiento del teléfono. Elimina algunos archivos para liberar espacio."</string>
+ <string name="low_memory" product="default" msgid="3475999286680000541">"Se ha agotado el espacio de almacenamiento del dispositivo. Elimina algunos archivos para liberar espacio."</string>
<string name="me" msgid="6545696007631404292">"Yo"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opciones de tablet"</string>
- <string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones de teléfono"</string>
+ <string name="power_dialog" product="default" msgid="1319919075463988638">"Opciones de dispositivo"</string>
<string name="silent_mode" msgid="7167703389802618663">"Modo silencioso"</string>
- <string name="turn_on_radio" msgid="3912793092339962371">"Encender el teléfono inalámbrico"</string>
- <string name="turn_off_radio" msgid="8198784949987062346">"Apagar el teléfono inalámbrico"</string>
+ <string name="turn_on_radio" msgid="3912793092339962371">"Activar conexión inalámbrica"</string>
+ <string name="turn_off_radio" msgid="8198784949987062346">"Desactivar conexión inalámbrica"</string>
<string name="screen_lock" msgid="799094655496098153">"Bloqueo de pantalla"</string>
<string name="power_off" msgid="4266614107412865048">"Apagar"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"Timbre desactivado"</string>
@@ -142,30 +142,30 @@
<string name="silent_mode_ring" msgid="8592241816194074353">"Timbre activado"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Apagando…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tu tablet se apagará."</string>
- <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Tu teléfono se apagará."</string>
+ <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Tu dispositivo se apagará."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"¿Deseas apagarlo?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"No hay aplicaciones recientes."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"Opciones de tablet"</string>
- <string name="global_actions" product="default" msgid="2406416831541615258">"Opciones de teléfono"</string>
+ <string name="global_actions" product="default" msgid="2406416831541615258">"Opciones de dispositivo"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Bloqueo de pantalla"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Apagar"</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modo silencioso"</string>
- <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"El sonido está Apagado"</string>
- <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El sonido está Encendido"</string>
+ <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"El sonido está Desactivado"</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"El sonido está Activado"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modo avión"</string>
- <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"El modo avión está Encendido"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"El modo avión está Apagado"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"El modo avión está Activado"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"El modo avión está Desactivado"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servicios que te cuestan dinero"</string>
<string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Permite que las aplicaciones realicen actividades con cargo."</string>
<string name="permgrouplab_messages" msgid="7521249148445456662">"Tus mensajes"</string>
- <string name="permgroupdesc_messages" msgid="7821999071003699236">"Lee y escribe tus SMS, mensajes de correo electrónico y otros mensajes."</string>
+ <string name="permgroupdesc_messages" msgid="7821999071003699236">"Lee y escribe tus SMS, mensajes de correo y otros mensajes."</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Tu información personal"</string>
- <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Acceso directo a los contactos y calendario guardados en tu teléfono."</string>
- <string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Acceso directo a tus contactos y calendario guardado en el teléfono."</string>
+ <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Acceso directo a los contactos y calendario guardados en tu dispositivo."</string>
+ <string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Acceso directo a tus contactos y calendario guardado en el dispositivo."</string>
<string name="permgrouplab_location" msgid="635149742436692049">"Tu ubicación"</string>
<string name="permgroupdesc_location" msgid="5704679763124170100">"Controlar tu ubicación física"</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"Comunicación de red"</string>
@@ -173,7 +173,7 @@
<string name="permgrouplab_accounts" msgid="3359646291125325519">"Tus cuentas"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Acceder a las cuentas disponibles."</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controles de hardware"</string>
- <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Acceso directo al hardware en el teléfono."</string>
+ <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Acceso directo al hardware en el dispositivo."</string>
<string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Llamadas telefónicas"</string>
<string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Controlar, grabar y procesar llamadas telefónicas."</string>
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"Herramientas del sistema"</string>
@@ -203,10 +203,10 @@
<string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Permite que la aplicación envíe mensajes SMS. Las aplicaciones maliciosas pueden generar gastos a causa del envío de mensajes sin tu confirmación."</string>
<string name="permlab_readSms" msgid="4085333708122372256">"leer SMS o MMS"</string>
<string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Permite que la aplicación lea mensajes SMS almacenados en tu tableta o tarjeta SIM. Las aplicaciones maliciosas pueden leer tus mensajes confidenciales."</string>
- <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Permite que la aplicación lea mensajes SMS almacenados en tu teléfono o tarjeta SIM. Las aplicaciones maliciosas pueden leer tus mensajes confidenciales."</string>
+ <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Permite que la aplicación lea mensajes SMS almacenados en tu dispositivo o tarjeta SIM. Las aplicaciones maliciosas pueden leer tus mensajes confidenciales."</string>
<string name="permlab_writeSms" msgid="6881122575154940744">"editar SMS o MMS"</string>
<string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Permite que la aplicación escriba en mensajes SMS almacenados en tu tableta o tarjeta SIM. Las aplicaciones maliciosas pueden eliminar tus mensajes."</string>
- <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Permite que la aplicación escriba en mensajes SMS almacenados en tu teléfono o tarjeta SIM. Las aplicaciones maliciosas pueden eliminar tus mensajes."</string>
+ <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Permite que la aplicación escriba en mensajes SMS almacenados en tu dispositivo o tarjeta SIM. Las aplicaciones maliciosas pueden eliminar tus mensajes."</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"recibir WAP"</string>
<string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Permite que la aplicación reciba y procese mensajes WAP. Las aplicaciones maliciosas pueden controlar tus mensajes o eliminarlos sin mostrártelos."</string>
<string name="permlab_getTasks" msgid="6466095396623933906">"recuperar aplicaciones en ejecución"</string>
@@ -215,11 +215,11 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permite que la aplicación mueva tareas al primero o segundo plano. Las aplicaciones maliciosas pueden forzar su paso al primer plano sin que tú las controles."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"detener las aplicaciones en ejecución"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Permite que la aplicación elimine tareas y cierre sus aplicaciones. Las aplicaciones malintencionadas pueden usar este permiso para interferir en el comportamiento de otras aplicaciones."</string>
- <string name="permlab_setDebugApp" msgid="3022107198686584052">"habilitar depuración de aplicación"</string>
+ <string name="permlab_setDebugApp" msgid="3022107198686584052">"activar depuración de aplicación"</string>
<string name="permdesc_setDebugApp" msgid="4474512416299013256">"Permite que la aplicación active la depuración de otra aplicación. Las aplicaciones malintencionadas pueden usar este permiso para interrumpir la ejecución de otras aplicaciones."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"cambiar tu configuración de la interfaz de usuario"</string>
<string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Permite que la aplicación cambie la configuración actual como, por ejemplo, la configuración regional o el tamaño de fuente general."</string>
- <string name="permlab_enableCarMode" msgid="5684504058192921098">"habilitar el modo de auto"</string>
+ <string name="permlab_enableCarMode" msgid="5684504058192921098">"activar el modo de auto"</string>
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite que la aplicación habilite el modo coche."</string>
<string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"eliminar los procesos de fondo"</string>
<string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Permite que la aplicación elimine procesos de otras aplicaciones que se ejecutan en segundo plano, aunque haya suficiente memoria."</string>
@@ -263,7 +263,7 @@
<string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Permite que la aplicación cree y administre sus propios tokens al ignorar su orden z normal. Las aplicaciones normales no deben utilizar este permiso."</string>
<string name="permlab_injectEvents" msgid="1378746584023586600">"presionar teclas y botones de control"</string>
<string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Permite que la aplicación ofrezca sus propios eventos de entrada (pulsaciones de teclas, etc.) a otras aplicaciones. Las aplicaciones maliciosas pueden utilizar este permiso para controlar la tableta."</string>
- <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Permite que la aplicación ofrezca sus propios eventos de entrada (pulsaciones de teclas, etc.) a otras aplicaciones. Las aplicaciones maliciosas pueden utilizar este permiso para controlar el teléfono."</string>
+ <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Permite que la aplicación ofrezca sus propios eventos de entrada (pulsaciones de teclas, etc.) a otras aplicaciones. Las aplicaciones maliciosas pueden utilizar este permiso para controlar el dispositivo."</string>
<string name="permlab_readInputState" msgid="469428900041249234">"grabar tu tipo y las medidas que tomes"</string>
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permite que la aplicación observe las teclas que presionas, incluso al interactuar con otra aplicación (como cuando escribes una contraseña). Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a un método de entrada"</string>
@@ -298,19 +298,19 @@
<string name="permdesc_installPackages" msgid="5628530972548071284">"Permite que la aplicación instale paquetes de Android nuevos o actualizados. Las aplicaciones maliciosas pueden utilizar este permiso para agregar nuevas aplicaciones con permisos arbitrarios potentes."</string>
<string name="permlab_clearAppCache" msgid="7487279391723526815">"eliminar todos los datos de caché de la aplicación"</string>
<string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Permite que la aplicación libere almacenamiento en la tableta al eliminar archivos en el directorio caché de la aplicación. El acceso al proceso del sistema suele ser muy restringido."</string>
- <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Permite que la aplicación libere espacio de almacenamiento en el teléfono al eliminar archivos en el directorio caché de la aplicación. El acceso al proceso del sistema suele ser muy restringido."</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Permite que la aplicación libere espacio de almacenamiento en el dispositivo al eliminar archivos en el directorio caché de la aplicación. El acceso al proceso del sistema suele ser muy restringido."</string>
<string name="permlab_movePackage" msgid="3289890271645921411">"mover recursos de la aplicación"</string>
<string name="permdesc_movePackage" msgid="319562217778244524">"Permite que la aplicación traslade recursos de la aplicación de medios internos a medios externos y viceversa."</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"lee los datos confidenciales del registro"</string>
<string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permite que la aplicación lea diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con la tableta, lo que podría incluir información personal o privada."</string>
- <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que la aplicación lea los diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con el teléfono, que puede incluir información personal o privada."</string>
+ <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que la aplicación lea los diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con el dispositivo, que puede incluir información personal o privada."</string>
<string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Usar cualquier decodificador de medios para la reproducción"</string>
<string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Permite que la aplicación use cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"leer y escribir a recursos dentro del grupo de diagnóstico"</string>
<string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar la seguridad y estabilidad del sistema. SOLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
<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 inhabilitar 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 inhabilitar funciones importantes del teléfono. 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="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>
<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>
@@ -321,16 +321,16 @@
<string name="permdesc_writeGservices" msgid="1287309437638380229">"Permite que la aplicación modifique el mapa de servicios de Google. Las aplicaciones normales no deben utilizar este permiso."</string>
<string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"ejecutar automáticamente al iniciar"</string>
<string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Permite que la aplicación se inicie en cuanto el sistema haya finalizado la inicialización. Esto puede ocasionar que la tableta tarde más en inicializarse y que la aplicación ralentice el funcionamiento general de la tableta al estar en ejecución constante."</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permite que la aplicación se inicie en cuanto el sistema haya finalizado la inicialización. Esto puede ocasionar que el teléfono tarde más en inicializarse y que la aplicación ralentice el funcionamiento general del teléfono al estar en ejecución constante."</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permite que la aplicación se inicie en cuanto el sistema haya finalizado la inicialización. Esto puede ocasionar que el dispositivo tarde más en inicializarse y que la aplicación ralentice el funcionamiento general del dispositivo al estar en ejecución constante."</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar emisiones pegajosas"</string>
<string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Permite que la aplicación envíe transmisiones persistentes que permanecen luego de que finaliza la transmisión. Las aplicaciones maliciosas pueden hacer que la tableta funcione más lentamente o de manera inestable al forzarla a utilizar mucha memoria."</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Permite que la aplicación envíe transmisiones persistentes que permanecen luego de que finaliza la transmisión. Las aplicaciones maliciosas pueden hacer que el teléfono funcione más lento o de manera inestable al forzarlo a utilizar mucha memoria."</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Permite que la aplicación envíe transmisiones persistentes que permanecen luego de que finaliza la transmisión. Las aplicaciones maliciosas pueden hacer que el dispositivo funcione más lento o de manera inestable al forzarlo a utilizar mucha memoria."</string>
<string name="permlab_readContacts" msgid="6219652189510218240">"leer datos de contacto"</string>
<string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Permite que la aplicación lea todos los datos de contacto (direcciones) almacenados en tu tableta. Las aplicaciones maliciosas pueden usar este permiso para enviar tus datos a otras personas."</string>
- <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Permite que la aplicación lea todos los datos de contacto (direcciones) almacenados en tu teléfono. Las aplicaciones maliciosas pueden utilizar este permiso para enviar tus datos a otro teléfono."</string>
+ <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Permite que la aplicación lea todos los datos de contacto (direcciones) almacenados en tu dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para enviar tus datos a otro dispositivo."</string>
<string name="permlab_writeContacts" msgid="644616215860933284">"escribir datos de contacto"</string>
<string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Permite que la aplicación modifique la información de contacto (dirección) almacenada en tu tableta. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar tu información de contacto."</string>
- <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Permite que la aplicación modifique la información de contacto (dirección) almacenada en tu teléfono. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar tu información de contacto."</string>
+ <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Permite que la aplicación modifique la información de contacto (dirección) almacenada en tu dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar tu información de contacto."</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"Leer tus datos de perfil"</string>
<string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Permite que la aplicación lea la información de perfil almacenada en tu dispositivo, como tu nombre e información de contacto. Esto significa que la aplicación puede identificarte y enviar tu información de perfil a otros."</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"Escrib. en datos de tu perfil"</string>
@@ -341,8 +341,8 @@
<string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Permite que la aplicación muestre las actualizaciones sociales de tus amigos. Las aplicaciones maliciosas pueden usar este permiso para hacerse pasar por un amigo y engañarte para que reveles contraseñas u otros datos confidenciales."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"Leer eventos de calendario e información confidencial"</string>
<string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Permite que la aplicación lea todos los eventos del calendario almacenados en tu tableta, incluidos los de amigos o compañeros de trabajo. Las aplicaciones maliciosas pueden extraer información personal de esos calendarios sin que los propietarios lo sepan."</string>
- <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Permite que la aplicación lea todos los eventos del calendario almacenados en tu teléfono, incluidos los de amigos o compañeros de trabajo. Las aplicaciones maliciosas pueden extraer información personal de esos calendarios sin que los propietarios lo sepan."</string>
- <string name="permlab_writeCalendar" msgid="8438874755193825647">"Agregar o modificar los eventos de calendario y enviar un correo electrónico a los invitados sin que los propietarios lo sepan"</string>
+ <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Permite que la aplicación lea todos los eventos del calendario almacenados en tu dispositivo, incluidos los de amigos o compañeros de trabajo. Las aplicaciones maliciosas pueden extraer información personal de esos calendarios sin que los propietarios lo sepan."</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"Agregar o modificar los eventos de calendario y enviar un correo a los invitados sin que los propietarios lo sepan"</string>
<string name="permdesc_writeCalendar" msgid="2243771395254848873">"Permite que la aplicación envíe invitaciones a eventos como propietario del calendario, y que agregue, elimine y cambie eventos que puedes modificar en tu dispositivo, incluidos los de tus amigos o compañeros de trabajo. Las aplicaciones maliciosas pueden enviar correos electrónicos de spam que aparenten provenir de propietarios de calendarios, modificar eventos sin que el propietario lo sepa o agregar eventos falsos."</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"crear fuentes de ubicación de prueba"</string>
<string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Permite que la aplicación cree fuentes de ubicación simuladas para pruebas. Las aplicaciones maliciosas pueden utilizar este permiso para anular la ubicación o el estado que devuelven las fuentes de ubicación actuales, como los proveedores de GPS o redes."</string>
@@ -352,10 +352,10 @@
<string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Crear fuentes de ubicación simuladas para pruebas. Las aplicaciones maliciosas pueden utilizar esta opción para anular la ubicación o el estado que devuelven las fuentes de ubicación reales, como los proveedores de GPS o redes, o para monitorear e informar tu ubicación a una fuente externa."</string>
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"ubicación precisa (GPS)"</string>
<string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Permite acceder a las fuentes de ubicación precisas, como el sistema de posicionamiento global en la tableta, si está disponible. Las aplicaciones maliciosas pueden utilizar este permiso para determinar dónde te encuentras y pueden consumir batería adicional."</string>
- <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Permite acceder a las fuentes de ubicación precisa, como el sistema de posicionamiento global del teléfono, si está disponible. Las aplicaciones maliciosas pueden utilizar este permiso para determinar dónde te encuentras y pueden consumir batería adicional."</string>
+ <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Permite acceder a las fuentes de ubicación precisa, como el sistema de posicionamiento global del dispositivo, si está disponible. Las aplicaciones maliciosas pueden utilizar este permiso para determinar dónde te encuentras y pueden consumir batería adicional."</string>
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"ubicación aproximada (basada en la red)"</string>
<string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Permite acceder a las fuentes de ubicación aproximada, como la base de datos de la red para celulares, para determinar la ubicación aproximada de una tableta, si está disponible. Las aplicaciones maliciosas pueden utilizar este permiso para determinar tu ubicación aproximada."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Permite acceder a fuentes de ubicación aproximada como, por ejemplo, la base de datos de la red para celulares, para determinar la ubicación aproximada de un teléfono, si está disponible. Las aplicaciones maliciosas pueden utilizar este permiso para determinar tu ubicación aproximada."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Permite acceder a fuentes de ubicación aproximada como, por ejemplo, la base de datos de la red para celulares, para determinar la ubicación aproximada de un dispositivo, si está disponible. Las aplicaciones maliciosas pueden utilizar este permiso para determinar tu ubicación aproximada."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"acceder a SurfaceFlinger"</string>
<string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que la aplicación utilice funciones de SurfaceFlinger de bajo nivel."</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leer el búfer de tramas"</string>
@@ -366,14 +366,14 @@
<string name="permdesc_recordAudio" msgid="2387462233976248635">"Permite que la aplicación acceda a la ruta de grabación de audio."</string>
<string name="permlab_camera" msgid="3616391919559751192">"tomar fotografías y grabar videos"</string>
<string name="permdesc_camera" msgid="1507407407002492176">"Permite que la aplicación tome fotografías y grabe videos con la cámara. De este modo, la aplicación puede obtener las imágenes que capta la cámara en cualquier momento."</string>
- <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"inhabilitar tablet de forma permanente"</string>
- <string name="permlab_brick" product="default" msgid="8337817093326370537">"desactivar teléfono de manera permanente"</string>
+ <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"desactivar tablet de forma permanente"</string>
+ <string name="permlab_brick" product="default" msgid="8337817093326370537">"desactivar dispositivo de manera permanente"</string>
<string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Permite que la aplicación inhabilite toda la tableta de manera permanente. Esto es muy peligroso."</string>
- <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Permite que la aplicación inhabilite el teléfono de forma permanente. Este permiso es muy peligroso."</string>
+ <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Permite que la aplicación inhabilite el dispositivo de forma permanente. Este permiso es muy peligroso."</string>
<string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"forzar reinicio del tablet"</string>
- <string name="permlab_reboot" product="default" msgid="2898560872462638242">"forzar reinicio del teléfono"</string>
+ <string name="permlab_reboot" product="default" msgid="2898560872462638242">"forzar reinicio del dispositivo"</string>
<string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Permite que la aplicación provoque el reinicio de la tableta."</string>
- <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Permite que la aplicación fuerce el reinicio del teléfono."</string>
+ <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Permite que la aplicación fuerce el reinicio del dispositivo."</string>
<string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"montar y desmontar filesystems"</string>
<string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Permite que la aplicación active y desactive sistemas de archivos para un almacenamiento extraíble."</string>
<string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"espacio de almacenamiento externo del formato"</string>
@@ -403,7 +403,7 @@
<string name="permlab_callPrivileged" msgid="4198349211108497879">"llamar directamente a cualquier número de teléfono"</string>
<string name="permdesc_callPrivileged" msgid="1689024901509996810">"Permite que la aplicación llame a cualquier número de teléfono, incluidos números de emergencia, sin tu intervención. Las aplicaciones maliciosas pueden realizar llamadas innecesarias e ilegales a servicios de emergencia."</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"iniciar directamente la configuración CDMA del tablet"</string>
- <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"iniciar directamente la configuración CDMA del teléfono"</string>
+ <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"iniciar directamente la configuración CDMA del dispositivo"</string>
<string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Permite que la aplicación inicie el método de acceso CDMA. Las aplicaciones maliciosas pueden iniciar el método CDMA de forma innecesaria."</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar las notificaciones de actualización de ubicación"</string>
<string name="permdesc_locationUpdates" msgid="1120741557891438876">"Permite que la aplicación habilite/deshabilite notificaciones de actualización de ubicación de la radio. Las aplicaciones normales no deben utilizar este permiso."</string>
@@ -411,21 +411,21 @@
<string name="permdesc_checkinProperties" msgid="4024526968630194128">"Permite que la aplicación lea/escriba el acceso a propiedades subidas por el servicio de registro. Las aplicaciones normales no deben usar este permiso."</string>
<string name="permlab_bindGadget" msgid="776905339015863471">"elegir widgets"</string>
<string name="permdesc_bindGadget" msgid="8261326938599049290">"Permite que la aplicación le indique al sistema qué widgets se pueden utilizar con cada aplicación. Una aplicación con este permiso puede proporcionar acceso a información personal por parte de otras aplicaciones. Las aplicaciones normales no deben utilizar este permiso."</string>
- <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modificar el estado del teléfono"</string>
+ <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modificar el estado del dispositivo"</string>
<string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, encender y apagar la radio del teléfono y tareas similares sin siquiera notificártelo."</string>
- <string name="permlab_readPhoneState" msgid="2326172951448691631">"leer el estado del teléfono y la identidad"</string>
+ <string name="permlab_readPhoneState" msgid="2326172951448691631">"leer el estado del dispositivo y la identidad"</string>
<string name="permdesc_readPhoneState" msgid="5127767618743602782">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. Una aplicación con este permiso puede determinar el número de teléfono y el número de serie del teléfono, si hay una llamada activa, el número al que esa llamada está conectada, etc."</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evitar que el tablet entre en estado de inactividad"</string>
- <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar que el teléfono entre en estado de inactividad"</string>
+ <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar que el dispositivo entre en estado de inactividad"</string>
<string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permite que la aplicación evite que la tableta entre en estado de inactividad."</string>
- <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que la aplicación evite que el teléfono entre en estado de inactividad."</string>
+ <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permite que la aplicación evite que el dispositivo entre en estado de inactividad."</string>
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"apagar o encender el tablet"</string>
- <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"apagar o encender el teléfono"</string>
+ <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"apagar o encender el dispositivo"</string>
<string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permite que la aplicación encienda o apague la tableta."</string>
- <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Permite que la aplicación encienda o apague el teléfono."</string>
+ <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Permite que la aplicación encienda o apague el dispositivo."</string>
<string name="permlab_factoryTest" msgid="3715225492696416187">"ejecutar en el modo de prueba de fábrica"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Se ejecuta como una prueba de fábrica de bajo nivel que permite un acceso completo al hardware del tablet. Sólo disponible cuando el tablet se ejecuta en el modo de prueba de fábrica."</string>
- <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Se ejecuta como una prueba de fábrica de bajo nivel que permite un acceso completo al hardware del teléfono. Sólo disponible cuando un teléfono se ejecuta en el modo de prueba de fábrica."</string>
+ <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Se ejecuta como una prueba de fábrica de bajo nivel que permite un acceso completo al hardware del dispositivo. Sólo disponible cuando un dispositivo se ejecuta en el modo de prueba de fábrica."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"establecer papel tapiz"</string>
<string name="permdesc_setWallpaper" msgid="7373447920977624745">"Permite que la aplicación establezca el fondo de pantalla del sistema."</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"establecer sugerencias de tamaño del papel tapiz"</string>
@@ -434,15 +434,15 @@
<string name="permdesc_masterClear" msgid="3665380492633910226">"Permite que la aplicación restablezca por completo el sistema a su configuración de fábrica al eliminar todos los datos, la configuración y las aplicaciones instaladas."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"establecer la hora"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Permite que la aplicación cambie la hora del reloj de la tableta."</string>
- <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Permite que la aplicación cambie la hora del reloj del teléfono."</string>
+ <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Permite que la aplicación cambie la hora del reloj del dispositivo."</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"establecer zona horaria"</string>
<string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Permite que la aplicación cambie la zona horaria de la tableta."</string>
- <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permite que la aplicación cambie la zona horaria del teléfono."</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permite que la aplicación cambie la zona horaria del dispositivo."</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"actuar como cuenta, administrador o servicio"</string>
<string name="permdesc_accountManagerService" msgid="1948455552333615954">"Permite que la aplicación haga llamadas a los autenticadores de cuentas."</string>
<string name="permlab_getAccounts" msgid="4549918644233460103">"descubrir cuentas conocidas"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Permite que la aplicación obtenga una lista de cuentas reconocidas por la tableta."</string>
- <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Permite que la aplicación obtenga una lista de cuentas reconocidas por el teléfono."</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Permite que la aplicación obtenga una lista de cuentas reconocidas por el dispositivo."</string>
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"actuar como autenticador de cuenta"</string>
<string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Permite que la aplicación utilice las capacidades del autenticador de cuentas del administrador de cuentas, incluida la creación de cuentas y la obtención y configuración de sus contraseñas."</string>
<string name="permlab_manageAccounts" msgid="4440380488312204365">"administrar la lista de cuentas"</string>
@@ -469,18 +469,18 @@
<string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Permite que la aplicación reciba paquetes que no están dirigidos directamente a tu dispositivo. Esto puede ser útil para descubrir servicios cercanos. Utiliza más energia que el modo que no es de multidifusión."</string>
<string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administración de Bluetooth"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite que la aplicación configure la tableta Bluetooth local y descubra y se sincronice con dispositivos remotos."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que la aplicación configure el teléfono Bluetooth local y descubra y se sincronice con dispositivos remotos."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que la aplicación configure el dispositivo Bluetooth local y descubra y se sincronice con dispositivos remotos."</string>
<string name="permlab_accessWimaxState" msgid="1232061307208861588">"Ver el estado de WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="5914958077555177749">"Permite que la aplicación consulte la información sobre el estado de WiMAX."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"Cambiar el estado de WiMAX"</string>
<string name="permdesc_changeWimaxState" msgid="3328853825006455912">"Permite que la aplicación se conecte a una red WiMAX y se desconecte de ella."</string>
<string name="permlab_bluetooth" msgid="8361038707857018732">"crear conexiones de Bluetooth"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permite que la aplicación vea la configuración de la tableta Bluetooth local, y que cree y acepte conexiones con los dispositivos sincronizados."</string>
- <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Permite que la aplicación vea la configuración del teléfono Bluetooth local, y que cree y acepte conexiones con los dispositivos sincronizados."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Permite que la aplicación vea la configuración del dispositivo Bluetooth local, y que cree y acepte conexiones con los dispositivos sincronizados."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"controlar la Transmisión de datos en proximidad"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="4977406164311535092">"desactivar el bloqueo"</string>
- <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Permite que la aplicación inhabilite el bloqueo del teclado y cualquier protección con contraseña asociada. Un ejemplo de este permiso es la inhabilitación por parte del teléfono del bloqueo del teclado al recibir una llamada telefónica entrante y su posterior habilitación cuando finaliza la llamada."</string>
+ <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Permite que la aplicación inhabilite el bloqueo del teclado y cualquier protección con contraseña asociada. Un ejemplo de este permiso es la inhabilitación por parte del dispositivo del bloqueo del teclado al recibir una llamada telefónica entrante y su posterior habilitación cuando finaliza la llamada."</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
<string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Permite que la aplicación lea la configuración de sincronización; por ejemplo, si está habilitada la sincronización para la aplicación Personas."</string>
<string name="permlab_writeSyncSettings" msgid="6297138566442486462">"escribir configuración de sincronización"</string>
@@ -515,14 +515,14 @@
<string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Controla la cantidad de contraseñas incorrectas ingresadas al desbloquear la pantalla y bloquea la tableta o borra todos los datos de la tableta si se ingresaron demasiadas contraseñas incorrectas."</string>
- <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Controla la cantidad de contraseñas ingresadas incorrectamente al desbloquear la pantalla y bloquea el teléfono o borra todos sus datos si se ingresan demasiadas contraseñas incorrectas."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Controla la cantidad de contraseñas ingresadas incorrectamente al desbloquear la pantalla y bloquea el dispositivo o borra todos sus datos si se ingresan demasiadas contraseñas incorrectas."</string>
<string name="policylab_resetPassword" msgid="2620077191242688955">"Cambiar la contraseña para desbloquear la pantalla"</string>
<string name="policydesc_resetPassword" msgid="605963962301904458">"Cambiar la contraseña para desbloquear la pantalla"</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Bloquear la pantalla"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"Controlar cómo y cuándo se bloquea la pantalla"</string>
- <string name="policylab_wipeData" msgid="3910545446758639713">"Borrar todos los datos"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Borrar los datos de la tableta sin avisar y restablecer la configuración de fábrica"</string>
- <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Borrar los datos del teléfono sin avisar y restablecer la configuración de fábrica"</string>
+ <string name="policylab_wipeData" msgid="3910545446758639713">"Eliminar todos los datos"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Eliminar los datos de la tableta sin avisar y restablecer la configuración de fábrica"</string>
+ <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Eliminar los datos del dispositivo sin avisar y restablecer la configuración de fábrica"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Configura el proxy global de dispositivo"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configuración del proxy global de dispositivo que se utilizará mientras se habilita la política. Sólo la primera administración de dispositivo configura el proxy global efectivo."</string>
<string name="policylab_expirePassword" msgid="885279151847254056">"Establecer la caducidad del bloqueo de pantalla"</string>
@@ -629,7 +629,7 @@
<string name="relationTypeAssistant" msgid="6274334825195379076">"Asistente"</string>
<string name="relationTypeBrother" msgid="8757913506784067713">"Hermano"</string>
<string name="relationTypeChild" msgid="1890746277276881626">"Hijo"</string>
- <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Conviviente"</string>
+ <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Pareja de hecho"</string>
<string name="relationTypeFather" msgid="5228034687082050725">"Padre"</string>
<string name="relationTypeFriend" msgid="7313106762483391262">"Amigo"</string>
<string name="relationTypeManager" msgid="6365677861610137895">"Gerente"</string>
@@ -671,7 +671,7 @@
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta tu cargador."</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"No hay tarjeta SIM."</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"No hay tarjeta SIM en el tablet."</string>
- <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No hay tarjeta SIM en el teléfono."</string>
+ <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"No hay tarjeta SIM en el dispositivo."</string>
<string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Inserta una tarjeta SIM."</string>
<string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Falta la tarjeta SIM o no se puede leer. Introduce una tarjeta SIM."</string>
<string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Tu tarjeta SIM se ha inhabilitado de forma permanente."\n" Ponte en contacto con tu proveedor de servicios inalámbricos para obtener otra tarjeta SIM."</string>
@@ -690,27 +690,27 @@
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Escribiste incorrectamente tu contraseña <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Escribiste incorrectamente tu PIN <xliff:g id="NUMBER_0">%d</xliff:g> veces. "\n\n"Vuelve a intentarlo en <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu tableta mediante el uso de tu información de acceso de Google."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
- <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu teléfono mediante el uso de tu información de acceso de Google."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has establecido incorrectamente tu patrón de desbloqueo <xliff:g id="NUMBER_0">%d</xliff:g> veces. Luego de <xliff:g id="NUMBER_1">%d</xliff:g> intentos incorrectos, se te solicitará que desbloquees tu dispositivo mediante el uso de tu información de acceso de Google."\n\n" Vuelve a intentarlo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Intentaste desbloquear la tableta <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica de la tableta y se pierdan todos los datos de usuario."</string>
- <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del teléfono y se pierdan todos los datos de usuario."</string>
+ <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER_0">%d</xliff:g> veces, pero no lo lograste. Puedes intentarlo <xliff:g id="NUMBER_1">%d</xliff:g> veces más antes de que se restablezcan los valores predeterminados de fábrica del dispositivo y se pierdan todos los datos de usuario."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Intentaste desbloquear la tableta <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica de la tableta."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del teléfono."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Intentaste desbloquear el dispositivo <xliff:g id="NUMBER">%d</xliff:g> veces, pero no lo lograste. Se restablecerán los valores predeterminados de fábrica del dispositivo."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"¿Olvidaste el patrón?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Desbloquear cuenta"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Demasiados intentos incorrectos de creación del patrón"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Para desbloquear, accede con tu cuenta de Google."</string>
- <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nombre de usuario (correo electrónico)"</string>
+ <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Nombre de usuario (correo)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Contraseña"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Inicia sesión"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nombre de usuario o contraseña incorrecta."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"¿Olvidaste tu nombre de usuario o contraseña?"\n"Accede a "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Comprobando..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Desbloquear"</string>
- <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sonido encendido"</string>
- <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sonido apagado"</string>
+ <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sonido activado"</string>
+ <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Sonido desactivado"</string>
<string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Se inició el patrón"</string>
- <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Se borró el patrón"</string>
+ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Se eliminó el patrón"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Se agregó una celda."</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Se completó el patrón"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
@@ -749,7 +749,7 @@
<string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Permite que la aplicación consulte todos los marcadores del navegador y todas las URL que haya visitado."</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"escribir historial y marcadores del navegador"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Permite que la aplicación modifique el historial o los marcadores del navegador guardados en tu tableta. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar los datos de tu navegador."</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Permite que la aplicación modifique el historial o los marcadores del navegador guardados en tu teléfono. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar los datos de tu navegador."</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Permite que la aplicación modifique el historial o los marcadores del navegador guardados en tu dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para borrar o modificar los datos de tu navegador."</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"configurar alarma en reloj alarma"</string>
<string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que la aplicación establezca una alarma en una aplicación de alarma instalada. Es posible que algunas aplicaciones de alarma no incluyan esta función."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"agregar correo de voz"</string>
@@ -774,7 +774,7 @@
<string name="search_go" msgid="8298016669822141719">"Buscar"</string>
<string name="searchview_description_search" msgid="6749826639098512120">"Buscar"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"Consulta de búsqueda"</string>
- <string name="searchview_description_clear" msgid="1330281990951833033">"Borrar la consulta"</string>
+ <string name="searchview_description_clear" msgid="1330281990951833033">"Eliminar la consulta"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Enviar consulta"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Búsqueda por voz"</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"hace 1 mes"</string>
@@ -848,7 +848,7 @@
<item quantity="one" msgid="2178576254385739855">"mañana"</item>
<item quantity="other" msgid="2973062968038355991">"en <xliff:g id="COUNT">%d</xliff:g> días"</item>
</plurals>
- <string name="preposition_for_date" msgid="9093949757757445117">"encendido <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="preposition_for_date" msgid="9093949757757445117">"activado <xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"a las <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"en <xliff:g id="YEAR">%s</xliff:g>"</string>
<string name="day" msgid="8144195776058119424">"día"</string>
@@ -889,7 +889,7 @@
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
<string name="low_internal_storage_view_title" msgid="1399732408701697546">"Poco espacio de almacenamiento"</string>
<string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"Está quedando poco espacio de almacenamiento en el tablet."</string>
- <string name="low_internal_storage_view_text" product="default" msgid="635106544616378836">"Hay poco espacio de almacenamiento en el teléfono."</string>
+ <string name="low_internal_storage_view_text" product="default" msgid="635106544616378836">"Hay poco espacio de almacenamiento en el dispositivo."</string>
<string name="ok" msgid="5970060430562524910">"Aceptar"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
<string name="yes" msgid="5362982303337969312">"Aceptar"</string>
@@ -900,7 +900,7 @@
<string name="capital_off" msgid="6815870386972805832">"No"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar la acción mediante"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de manera predeterminada en esta acción."</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Borrar valores predeterminados en Configuración del sistema &gt; Aplicaciones &gt; Descargas."</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Eliminar valores predeterminados en Configuración del sistema &gt; Aplicaciones &gt; Descargas."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Seleccionar una acción"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Selecciona una aplicación para el dispositivo USB."</string>
<string name="noApplications" msgid="2991814273936504689">"Ninguna aplicación puede realizar esta acción."</string>
@@ -915,12 +915,13 @@
<string name="force_close" msgid="8346072094521265605">"Aceptar"</string>
<string name="report" msgid="4060218260984795706">"Notificar"</string>
<string name="wait" msgid="7147118217226317732">"Esperar"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"La página no responde."\n\n"¿Deseas cerrarla?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicación redireccionada"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando ahora."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> se inició originalmente."</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"Escala"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"Mostrar siempre"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Volver a habilitar Configuración del sistema &gt; Aplicaciones &gt; Descargas"</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Volver a activar Configuración del sistema &gt; Aplicaciones &gt; Descargas"</string>
<string name="smv_application" msgid="3307209192155442829">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha infringido su política StrictMode de aplicación automática."</string>
<string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha violado su política StrictMode autoimpuesta."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android se está actualizando..."</string>
@@ -1031,7 +1032,7 @@
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Se perderán todos los datos de tu tarjeta."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración de USB conectada"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para inhabilitar la depuración de USB."</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración de USB."</string>
<string name="select_input_method" msgid="4653387336791222978">"Selecciona el método de introducción"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introducción"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1203,7 +1204,7 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datos de 4 GB desactivados"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datos móviles desactivados"</string>
<string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Datos Wi-Fi desactivados"</string>
- <string name="data_usage_limit_body" msgid="3317964706973601386">"Toca para habilitar."</string>
+ <string name="data_usage_limit_body" msgid="3317964706973601386">"Toca para activar."</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Supera límite de datos de 2G-3G"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Límite de datos de 4G superado"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Límite de datos móviles superado"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index fe6c70441d17..0c526ff46f0f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"Aceptar"</string>
<string name="report" msgid="4060218260984795706">"Informar"</string>
<string name="wait" msgid="7147118217226317732">"Esperar"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"La página no responde."\n\n"¿Quieres cerrarla?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicación redireccionada"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Inicialmente, se inició la aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 1a86b9d65779..5591289173d0 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -73,11 +73,11 @@
<string name="RestrictedOnData" msgid="8653794784690065540">"Andmesideteenus on blokeeritud."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Hädaabiteenus on blokeeritud."</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"Häälteenus on blokeeritud."</string>
- <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Kõik häälteenused on blokeeritud."</string>
+ <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Kõik häälteenused on blokeeritud."</string>
<string name="RestrictedOnSms" msgid="8314352327461638897">"SMS-teenus on blokeeritud."</string>
- <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Hääl-/andmeteenused on blokeeritud."</string>
+ <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Hääl-/andmeteenused on blokeeritud."</string>
<string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Hääl-/SMS-teenused on blokeeritud."</string>
- <string name="RestrictedOnAll" msgid="2714924667937117304">"Kõik hääl-/andme-/SMS-teenused on blokeeritud."</string>
+ <string name="RestrictedOnAll" msgid="5643028264466092821">"Kõik hääl-/andme-/SMS-teenused on blokeeritud."</string>
<string name="serviceClassVoice" msgid="1258393812335258019">"Hääl"</string>
<string name="serviceClassData" msgid="872456782077937893">"Andmed"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"FAKS"</string>
@@ -108,27 +108,27 @@
<string name="fcComplete" msgid="3118848230966886575">"Funktsioonikood valmis."</string>
<string name="fcError" msgid="3327560126588500777">"Ühendusprobleem või kehtetu funktsioonikood."</string>
<string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
- <string name="httpError" msgid="6603022914760066338">"Ilmnes võrgu viga."</string>
- <string name="httpErrorLookup" msgid="4517085806977851374">"URL-i ei leitud."</string>
+ <string name="httpError" msgid="7956392511146698522">"Ilmnes võrgu viga."</string>
+ <string name="httpErrorLookup" msgid="4711687456111963163">"URL-i ei leita."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Saidi autentimise skeemi ei toetata."</string>
- <string name="httpErrorAuth" msgid="7293960746955020542">"Autentimine ebaõnnestus."</string>
+ <string name="httpErrorAuth" msgid="1435065629438044534">"Autentimine ebaõnnestus."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"Puhverserveri kaudu autentimine ebaõnnestus."</string>
- <string name="httpErrorConnect" msgid="7623096283505770433">"Ühendus serveriga ebaõnnestus."</string>
- <string name="httpErrorIO" msgid="4270874999047767599">"Serveril ei õnnestunud sidet luua. Proovige hiljem uuesti."</string>
+ <string name="httpErrorConnect" msgid="8714273236364640549">"Serveriga ei saanud ühendust."</string>
+ <string name="httpErrorIO" msgid="2340558197489302188">"Serveriga ei saanud ühendust. Proovige hiljem uuesti."</string>
<string name="httpErrorTimeout" msgid="4743403703762883954">"Ühendus serveriga aegunud."</string>
<string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Leht sisaldab liiga palju serveri ümbersuunamisi."</string>
<string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokolli ei toetata."</string>
- <string name="httpErrorFailedSslHandshake" msgid="3088290300440289771">"Turvalist ühendust ei saanud luua."</string>
- <string name="httpErrorBadUrl" msgid="6088183159988619736">"Lehte ei saa avada, kuna URL on vale."</string>
- <string name="httpErrorFile" msgid="8250549644091165175">"Faili ei saa avada."</string>
- <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Nõutud faili ei leitud."</string>
+ <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Turvalist ühendust ei saanud luua."</string>
+ <string name="httpErrorBadUrl" msgid="3636929722728881972">"Lehte pole võimalik avada, kuna URL on vale."</string>
+ <string name="httpErrorFile" msgid="2170788515052558676">"Failile ei pääse juurde."</string>
+ <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Soovitud faili ei leitud."</string>
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Töötlemisel on liiga palju taotlusi. Proovige hiljem uuesti."</string>
- <string name="notification_title" msgid="1259940370369187045">"Viga kontole <xliff:g id="ACCOUNT">%1$s</xliff:g> sisselogimisel"</string>
+ <string name="notification_title" msgid="8967710025036163822">"Viga kontole <xliff:g id="ACCOUNT">%1$s</xliff:g> sisselogimisel"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"Sünkroonimine"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sünkroonimine"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Liiga palju üksuse <xliff:g id="CONTENT_TYPE">%s</xliff:g> kustutusi."</string>
- <string name="low_memory" product="tablet" msgid="2292820184396262278">"Tahvelarvuti mälu on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
- <string name="low_memory" product="default" msgid="6632412458436461203">"Telefonimälu on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
+ <string name="low_memory" product="tablet" msgid="6494019234102154896">"Tahvelarvuti mäluruum on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
+ <string name="low_memory" product="default" msgid="3475999286680000541">"Telefonimälu on täis. Ruumi vabastamiseks kustutage mõned failid."</string>
<string name="me" msgid="6545696007631404292">"Mina"</string>
<string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tahvelarvuti valikud"</string>
<string name="power_dialog" product="default" msgid="1319919075463988638">"Telefonivalikud"</string>
@@ -137,6 +137,9 @@
<string name="turn_off_radio" msgid="8198784949987062346">"Lülitage raadioside välja"</string>
<string name="screen_lock" msgid="799094655496098153">"Ekraanilukk"</string>
<string name="power_off" msgid="4266614107412865048">"Lülita välja"</string>
+ <string name="silent_mode_silent" msgid="319298163018473078">"Helin on väljas"</string>
+ <string name="silent_mode_vibrate" msgid="7072043388581551395">"Vibreeriv helin"</string>
+ <string name="silent_mode_ring" msgid="8592241816194074353">"Helin on sees"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Väljalülitamine ..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Teie tahvelarvuti lülitub välja."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Teie telefon lülitub välja."</string>
@@ -157,16 +160,16 @@
<string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tasulised teenused"</string>
- <string name="permgroupdesc_costMoney" msgid="8596717365335027057">"Võimaldab rakendustel teha tasulisi toiminguid."</string>
+ <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Tasuliste toimingute tegemine."</string>
<string name="permgrouplab_messages" msgid="7521249148445456662">"Teie sõnumid"</string>
<string name="permgroupdesc_messages" msgid="7821999071003699236">"Teie SMS-, meili- ja muude sõnumite lugemine ja kirjutamine."</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Teie isiklikud andmed"</string>
<string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Otsene juurdepääs tahvelarvutisse salvestatud kontaktidele ja kalendrile."</string>
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Otsene juurdepääs telefoni salvestatud kontaktidele ja kalendrile."</string>
<string name="permgrouplab_location" msgid="635149742436692049">"Teie asukoht"</string>
- <string name="permgroupdesc_location" msgid="2430258821648348660">"Jälgige oma füüsilist asukohta"</string>
+ <string name="permgroupdesc_location" msgid="5704679763124170100">"Jälgige oma füüsilist asukohta."</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"Võrgusuhtlus"</string>
- <string name="permgroupdesc_network" msgid="4917593670797570584">"Võimaldab rakendustel pääseda juurde erinevatele võrgufunktsioonidele."</string>
+ <string name="permgroupdesc_network" msgid="4478299413241861987">"Juurdepääs erinevatele võrgufunktsioonidele."</string>
<string name="permgrouplab_accounts" msgid="3359646291125325519">"Teie kontod"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Juurdepääs saadaolevatele kontodele."</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Riistvara juhtelemendid"</string>
@@ -206,16 +209,16 @@
<string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Võimaldab rakendusel kirjutada teie telefoni või SIM-kaardile salvestatud SMS-sõnumitesse. Pahatahtlikud rakendused võivad teie sõnumid kustutada."</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"võta WAP vastu"</string>
<string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Võimaldab rakendusel vastu võtta ja töödelda WAP-sõnumeid. Pahatahtlikud rakendused võivad teie sõnumeid jälgida või neid kustutada teile näitamata."</string>
- <string name="permlab_getTasks" msgid="6466095396623933906">"käitatud rakenduste toomine"</string>
+ <string name="permlab_getTasks" msgid="6466095396623933906">"Käitatud rakenduste toomine"</string>
<string name="permdesc_getTasks" msgid="6608159250520381359">"Võimaldab rakendusel hankida teavet praegu töötavate ja hiljuti töötanud ülesannete kohta. Pahatahtlikud rakendused võivad avastada privaatset teavet teiste rakenduste kohta."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"käitatud rakenduste ümberjärjestamine"</string>
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Võimaldab rakendusel teisaldada ülesanded esiplaanile ja taustale. Pahatahtlikud rakendused võivad sundida end esiplaanile tulema teie loata."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"käitatud rakenduste peatamine"</string>
- <string name="permdesc_removeTasks" msgid="1000226123143185094">"Võimaldab rakendusel eemaldada ülesandeid ja peatada nende rakendused. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
+ <string name="permdesc_removeTasks" msgid="1394714352062635493">"Võimaldab rakendusel eemaldada ülesanded ja peatada nende rakendused. Pahatahtlikud rakendused võivad häirida teiste rakenduste käitumist."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"Rakenduse silumise lubamine"</string>
- <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Võimaldab rakendusel lülitada sisse teise rakenduse silumise. Pahatahtlikud rakendused võivad seda kasutada teiste rakenduste peatamiseks."</string>
+ <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Võimaldab rakendusel lülitada sisse teise rakenduse silumise. Pahatahtlikud rakendused võivad seda kasutada teiste rakenduste peatamiseks."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"muuda UI-seadeid"</string>
- <string name="permdesc_changeConfiguration" msgid="4104052649900380324">"Võimaldab rakendusel muuta praegust konfiguratsiooni, näiteks lokaati või üldist kirjasuurust."</string>
+ <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Võimaldab rakendusel muuta praegust konfiguratsiooni, näiteks lokaati või üldist kirjasuurust."</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"autorežiimi lubamine"</string>
<string name="permdesc_enableCarMode" msgid="4853187425751419467">"Võimaldab rakendusel autorežiimi lubada."</string>
<string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"taustaprotsesside peatamine"</string>
@@ -251,11 +254,11 @@
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"täieliku varukoopia kinnitamine või toimingu taastamine"</string>
<string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Võimaldab rakendusel käivitada täieliku varukoopia kinnitusliidese. Mitte kasutada üheski rakenduses."</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"kuva volituseta aknad"</string>
- <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Võimaldab rakendusel luua aknaid, mis on mõeldud süsteemisisesele kasutajaliidesele. Mitte kasutada tavarakenduste puhul."</string>
+ <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Võimaldab rakendusel luua aknaid, mis on mõeldud kasutamiseks süsteemisisesele kasutajaliidesele. Mitte kasutada tavarakenduste puhul."</string>
<string name="permlab_systemAlertWindow" msgid="3372321942941168324">"kuva süsteemitasemel märguandeid"</string>
<string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Võimaldab rakendusel kuvada süsteemihoiatuste aknaid. Pahatahtlikud rakendused võivad hõlmata kogu ekraani."</string>
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"muuda üldist animatsioonikiirust"</string>
- <string name="permdesc_setAnimationScale" msgid="6505093307223395456">"Võimaldab rakendusel muuta igal ajal üldist animatsiooni kiirust (animatsioone kiirendada või aeglustada)."</string>
+ <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Võimaldab rakendusel muuta animatsiooni üldist kiirust (animatsioone kiirendada või aeglustada) ükskõik millal."</string>
<string name="permlab_manageAppTokens" msgid="1286505717050121370">"Rakenduse lubade haldamine"</string>
<string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Võimaldab rakendusel luua ja hallata tema enda lube, möödudes tavapärasest Z-järjekorrast. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_injectEvents" msgid="1378746584023586600">"vajuta klahve ja juhtnuppe"</string>
@@ -266,9 +269,9 @@
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"seo sisestusmeetodiga"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lubab omanikul siduda sisestusmeetodi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
- <string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidest. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"seo VPN-teenusega"</string>
- <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Võimaldab omanikul siduda vidina teenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Võimaldab omanikul siduda VPN-teenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"taustapildiga sidumine"</string>
<string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Lubab omanikul siduda taustapildi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vidinateenusega sidumine"</string>
@@ -292,7 +295,7 @@
<string name="permlab_getPackageSize" msgid="7472921768357981986">"Rakenduse mäluruumi mõõtmine"</string>
<string name="permdesc_getPackageSize" msgid="3921068154420738296">"Võimaldab rakendusel tuua oma koodi, andmed ja vahemälu suurused"</string>
<string name="permlab_installPackages" msgid="2199128482820306924">"Rakenduste otse installimine"</string>
- <string name="permdesc_installPackages" msgid="5628530972548071284">"Võimaldab rakendusel installida uusi või värskendatud Android-pakette. Pahatahtlikud rakendused võivad seda kasutada uute rakenduste lisamiseks omavoliliselt võimsate õigustega."</string>
+ <string name="permdesc_installPackages" msgid="5628530972548071284">"Võimaldab rakendusel installida uusi või värskendatud Android-pakette. Pahatahtlikud rakendused võivad selle abil lisada uusi meelevaldse tegevuse lubadega rakendusi."</string>
<string name="permlab_clearAppCache" msgid="7487279391723526815">"Kõigi rakenduse vahemäluandmete kustutamine"</string>
<string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Võimaldab rakendusel vabastada tahvelarvuti mälu, kustutades faile otse rakenduse kataloogist. Süsteem on juurdepääsu sellele harilikult väga piiranud."</string>
<string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Võimaldab rakendusel vabastada telefoni mälu, kustutades faile otse rakenduse kataloogist. Süsteem on juurdepääsu sellele harilikult väga piiranud."</string>
@@ -301,6 +304,8 @@
<string name="permlab_readLogs" msgid="6615778543198967614">"tundlike logiandmete lugemine"</string>
<string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Võimaldab rakendusel lugeda süsteemi erinevaid logifaile. Nii on võimalik avastada üldist teavet selle kohta, mida te tahvelarvutiga teete, sh isiklikku või privaatset teavet."</string>
<string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Võimaldab rakendusel lugeda süsteemi erinevaid logifaile. Nii on võimalik avastada üldist teavet selle kohta, mida te telefoniga teete, mis võib kaasata ka isiklikku või privaatset teavet."</string>
+ <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Mis tahes meediumidekooderi kasutamine taasesituseks"</string>
+ <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Võimaldab rakendusel taasesituseks kasutada mis tahes installitud meediumidekooderit."</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"loe/kirjuta valija allikaid"</string>
<string name="permdesc_diagnostic" msgid="6608295692002452283">"Võimaldab rakendusel lugeda valimisrühma mis tahes ressurssi ja sellesse kirjutada (näiteks kaustas /dev olevad failid). See võib mõjutada süsteemi stabiilsust ja turvet. Seda tohiks kasutada tootja või operaator AINULT riistvaraspetsiifiliseks diagnostikaks."</string>
<string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
@@ -335,7 +340,7 @@
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Sotsiaalvoogu kirjutamine"</string>
<string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Võimaldab rakendusel kuvada sõprade suhtlusuudiseid. Pahatahtlikud rakendused saavad selle abil teie sõpra teeselda ja meelitada teid avaldama paroole või muud konfidentsiaalset teavet."</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"kalendrisündmuste lugemine ja konfidentsiaalne teave"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Võimaldab rakendusel lugeda kõiki teie tahvelarvutisse salvestatud kalendrisündmusi, sh teie sõprade või töökaaslaste omi. Pahatahtlikud rakendused võivad nendest kalendritest välja võtta isiklikku teavet ilma teadmiseta."</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Võimaldab rakendusel lugeda kõiki teie tahvelarvutisse salvestatud kalendrisündmusi, sh teie sõprade või töökaaslaste omi. Pahatahtlikud rakendused võivad nendest kalendritest välja võtta isiklikku teavet ilma omanike teadmata."</string>
<string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Võimaldab rakendusel lugeda kõiki teie telefoni salvestatud kalendrisündmusi, sh teie sõprade või töökaaslaste omi. Pahatahtlikud rakendused võivad nendest kalendritest välja võtta isiklikku teavet omaniku teadmiseta."</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"kalendrisündmuste lisamine või muutmine ja külalistele omanike teadmata meili saatmine"</string>
<string name="permdesc_writeCalendar" msgid="2243771395254848873">"Võimaldab rakendusel saata sündmusekutseid kalendri omanikuna ning lisada, eemaldada või muuta sündmusi, mida saate oma seadmel muuta, sh oma sõprade või töökaaslaste omi. Pahatahtlikud rakendused võivad saata rämpsposti, mis näib olevat tulnud kalendriomanikelt, muuta sündmusi omanike teadmata või lisada võltssündmusi."</string>
@@ -434,7 +439,7 @@
<string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Võimaldab rakendusel muuta tahvelarvuti ajavööndit."</string>
<string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Võimaldab rakendusel muuta telefoni ajavööndit."</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService\'ina tegutsemine"</string>
- <string name="permdesc_accountManagerService" msgid="2684502137670299915">"Võimaldab rakendusel helistada konto autentijatele."</string>
+ <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Võimaldab rakendusel helistada konto autentijatele."</string>
<string name="permlab_getAccounts" msgid="4549918644233460103">"leia teadaolevad kontod"</string>
<string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Võimaldab rakendusel hankida tahvelarvutile teadaolevate kontode loendi."</string>
<string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Võimaldab rakendusel saada telefonile teadaolevate kontode loendi."</string>
@@ -465,6 +470,10 @@
<string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetoothi haldamine"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Võimaldab rakendusel seadistada kohalikku Bluetooth-tahvelarvutit ning leida ja siduda seda kaugseadmetega."</string>
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Võimaldab rakendusel seadistada kohalikku Bluetooth-telefoni ning leida ja siduda seda kaugseadmetega."</string>
+ <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-i oleku kuvamine"</string>
+ <string name="permdesc_accessWimaxState" msgid="5914958077555177749">"Võimaldab rakendusel vaadata WiMAX-i olekuteavet."</string>
+ <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-i oleku muutmine"</string>
+ <string name="permdesc_changeWimaxState" msgid="3328853825006455912">"Võimaldab rakendusel luua ja katkestada ühenduse WiMAX-i võrguga."</string>
<string name="permlab_bluetooth" msgid="8361038707857018732">"loo Bluetooth-ühendusi"</string>
<string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Võimaldab rakendusel vaadata kohaliku Bluetooth-tahvelarvuti konfiguratsiooni ning luua ja heaks kiita ühendusi seotud seadmetega."</string>
<string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Võimaldab rakendusel vaadata kohaliku Bluetooth-telefoni konfiguratsiooni ning luua ja heaks kiita ühendusi seotud seadmetega."</string>
@@ -501,27 +510,27 @@
<string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"võrgueeskirjade haldamine"</string>
<string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Võimaldab rakendusel hallata võrgueeskirju ja määratleda rakendusespetsiifilisi reegleid."</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"võrgukasutuse arvestamise muutmine"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="8553240749784321765">"Võimaldab rakendusel muuta võrgukasutuse loendamist rakenduste suhtes. Mitte kasutada tavarakenduste puhul."</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Võimaldab rakendusel muuta võrgukasutuse loendamist rakenduste suhtes. Mitte kasutada tavarakenduste puhul."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
- <string name="policydesc_limitPassword" msgid="9083400080861728056">"Ekraaniluku paroolide lubatud pikkuse ja tähemärkide kontrollimine"</string>
+ <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Jälgib ekraani avamisel valesti sisestatud paroolide arvu ja lukustab tahvelarvuti või kustutab kõik selle andmed, kui vale parool sisestatakse liiga palju kordi."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Jälgib ekraani avamisel valesti sisestatud paroolide arvu ja lukustab telefoni või kustutab kõik selle andmed, kui vale parool sisestatakse liiga palju kordi."</string>
<string name="policylab_resetPassword" msgid="2620077191242688955">"Ekraaniluku parooli muutmine"</string>
- <string name="policydesc_resetPassword" msgid="5391240616981297361">"Ekraaniluku parooli muutmine"</string>
+ <string name="policydesc_resetPassword" msgid="605963962301904458">"Ekraaniluku parooli muutmine."</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Ekraani lukustamine"</string>
- <string name="policydesc_forceLock" msgid="5696964126226028442">"Juhtige, kuidas ja millal ekraan lukustub"</string>
+ <string name="policydesc_forceLock" msgid="1141797588403827138">"Määrake, kuidas ja millal ekraan lukustub."</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"Kõikide andmete kustutamine"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Tahvelarvuti andmete hoiatuseta kustutamine, lähtestades tehaseandmed"</string>
- <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Telefoniandmete hoiatuseta kustutamine, lähtestades tehaseandmed"</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Kustutage tahvelarvuti andmed hoiatamata, lähtestades arvuti tehaseandmetele."</string>
+ <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Kustuta telefoniandmed hoiatuseta, lähtestades telefoni tehaseandmetele."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Määra seadme globaalne puhverserver"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Eeskirjade lubamise ajal kasutatava seadme globaalse puhverserveri määramine. Ainult esimese seadme administraator määrab tõhusa globaalse puhverserveri."</string>
<string name="policylab_expirePassword" msgid="885279151847254056">"Ekraaniluku parooli aegumise määramine"</string>
- <string name="policydesc_expirePassword" msgid="4844430354224822074">"Juhib, kui sageli ekraaniluku parooli tuleb muuta"</string>
+ <string name="policydesc_expirePassword" msgid="1729725226314691591">"Määrake ekraaniluku parooli muutmissagedus."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"Salvestamise krüpt. määramine"</string>
- <string name="policydesc_encryptedStorage" msgid="8877192718681120469">"Nõue, et salvestatud rakenduse andmed krüpteeritakse"</string>
+ <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Nõua salvestatud rakenduse andmete krüpteerimist."</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"Keela kaamerad"</string>
- <string name="policydesc_disableCamera" msgid="5680054212889413366">"Väldi kõigi seadme kaamerate kasutamist"</string>
+ <string name="policydesc_disableCamera" msgid="2306349042834754597">"Vältige seadme kõigi kaamerate kasutamist."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Kodu"</item>
<item msgid="869923650527136615">"Mobiil"</item>
@@ -642,7 +651,7 @@
<string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Puudutage parooli sisestamiseks"</font></string>
<string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Avamiseks sisestage parool"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Avamiseks sisestage PIN-kood"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Vale PIN-kood."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Vale PIN-kood."</string>
<string name="keyguard_label_text" msgid="861796461028298424">"Avamiseks vajutage menüüklahvi, seejärel klahvi 0."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Hädaabinumber"</string>
<string name="lockscreen_carrier_default" msgid="8963839242565653192">"Teenus puudub."</string>
@@ -655,6 +664,7 @@
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Õige."</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Proovige uuesti"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Proovige uuesti"</string>
+ <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimaalne teenusega Face Unlock avamise katsete arv on ületatud"</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Laadimine, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_charged" msgid="4938930459620989972">"Laetud."</string>
<string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
@@ -688,14 +698,14 @@
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Proovige uuesti <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Kas unustasite mustri?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Konto avamine"</string>
- <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Liiga palju mustrikatseid."</string>
- <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Avamiseks logige sisse oma Google\'i kontoga"</string>
+ <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Liiga palju mustrikatseid"</string>
+ <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Avamiseks logige sisse oma Google\'i kontoga."</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Kasutajanimi (e-post)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parool"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logi sisse"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Vale kasutajanimi või parool."</string>
- <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Kas unustasite oma kasutajanime või parooli?"\n"Külastage aadressi "<b>"google.com/accounts/recovery"</b></string>
- <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Kontrollimine ..."</string>
+ <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Kas unustasite oma kasutajanime või parooli?"\n"Külastage aadressi "<b>"google.com/accounts/recovery"</b>"."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Kontrollimine ..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Ava"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Heli sisse"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Heli välja"</string>
@@ -712,13 +722,13 @@
<string name="factorytest_not_system" msgid="4435201656767276723">"Toimingut FACTORY_TEST toetatakse ainult kausta \\system\\app installitud pakettide puhul."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"Ei leitud ühtegi paketti, mis võimaldaks toimingut FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="6320168203050791643">"Taaskäivita"</string>
- <string name="js_dialog_title" msgid="8143918455087008109">"Veebileht aadressil <xliff:g id="TITLE">%s</xliff:g> ütleb:"</string>
+ <string name="js_dialog_title" msgid="1987483977834603872">"Leht „<xliff:g id="TITLE">%s</xliff:g>” ütleb järgmist."</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
- <string name="js_dialog_before_unload" msgid="730366588032430474">"Kas soovite sellelt lehelt lahkuda?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Jätkamiseks puudutage OK, praegusele lehele jäämiseks valikut Tühista."</string>
+ <string name="js_dialog_before_unload" msgid="730366588032430474">"Kas soovite sellelt lehelt lahkuda?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Jätkamiseks puudutage valikut OK, praegusele lehele jäämiseks valikut Tühista."</string>
<string name="save_password_label" msgid="6860261758665825069">"Kinnita"</string>
- <string name="double_tap_toast" msgid="2729045387923870404">"Vihje: suurendamiseks ja vähendamiseks puudutage kaks korda."</string>
- <string name="autofill_this_form" msgid="1272247532604569872">"Autom."</string>
- <string name="setup_autofill" msgid="8154593408885654044">"Aut. täit. sead."</string>
+ <string name="double_tap_toast" msgid="4595046515400268881">"Vihje: suurendamiseks ja vähendamiseks puudutage kaks korda."</string>
+ <string name="autofill_this_form" msgid="4616758841157816676">"Automaatne täitmine"</string>
+ <string name="setup_autofill" msgid="7103495070180590814">"Automaatse täitmise seadistamine"</string>
<string name="autofill_address_name_separator" msgid="2504700673286691795">" "</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
@@ -853,9 +863,9 @@
<string name="weeks" msgid="6509623834583944518">"nädalat"</string>
<string name="year" msgid="4001118221013892076">"aasta"</string>
<string name="years" msgid="6881577717993213522">"aastat"</string>
- <string name="VideoView_error_title" msgid="5927895235831021723">"Videot ei saa esitada"</string>
+ <string name="VideoView_error_title" msgid="3534509135438353077">"Probleem videoga"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"See video ei sobi voogesituseks selles seadmes."</string>
- <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"Seda videot ei saa esitada."</string>
+ <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Videot ei saa esitada."</string>
<string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
<string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="noon" msgid="7245353528818587908">"keskpäev"</string>
@@ -891,7 +901,7 @@
<string name="whichApplication" msgid="4533185947064773386">"Lõpetage toiming rakendusega"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Kasuta vaikimisi selleks toiminguks."</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Tühjendage vaikeandmed valikutes Süsteemiseaded &gt; Rakendused &gt; Allalaaditud."</string>
- <string name="chooseActivity" msgid="1009246475582238425">"Valige toiming"</string>
+ <string name="chooseActivity" msgid="7486876147751803333">"Toimingu valimine"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"USB-seadme jaoks rakenduse valimine"</string>
<string name="noApplications" msgid="2991814273936504689">"Ükski rakendus ei saa seda toimingut teostada."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
@@ -905,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Teata"</string>
<string name="wait" msgid="7147118217226317732">"Oodake"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Leht ei reageeri."\n\n"Kas soovite selle sulgeda?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Rakendus on ümber suunatud"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> on nüüd käivitunud."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Algselt käivitati rakendus <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
@@ -925,11 +936,11 @@
<string name="old_app_description" msgid="2082094275580358049">"Ärge käivitage uut rakendust."</string>
<string name="new_app_action" msgid="5472756926945440706">"Käivitage rakendus <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
<string name="new_app_description" msgid="1932143598371537340">"Peatage vana rakendus salvestamata."</string>
- <string name="sendText" msgid="5132506121645618310">"Valige teksti jaoks toiming"</string>
+ <string name="sendText" msgid="5209874571959469142">"Valige teksti jaoks toiming"</string>
<string name="volume_ringtone" msgid="6885421406845734650">"Helina helitugevus"</string>
<string name="volume_music" msgid="5421651157138628171">"Meediumi helitugevus"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Esitatakse Bluetoothi kaudu"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"Valitud on hääletu helin"</string>
+ <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Valitud on hääletu märguanne"</string>
<string name="volume_call" msgid="3941680041282788711">"Kõne helitugevus"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetoothi kõne helitugevus"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Alarmi helitugevus"</string>
@@ -953,17 +964,22 @@
<item quantity="one" msgid="1634101450343277345">"Avatud WiFi võrk on saadaval"</item>
<item quantity="other" msgid="7915895323644292768">"Avatud WiFi-võrgud on saadaval"</item>
</plurals>
- <string name="wifi_available_sign_in" msgid="9157196203958866662">"Logi sisse WiFi-võrku"</string>
+ <string name="wifi_available_sign_in" msgid="4029489716605255386">"Logige sisse WiFi-võrku"</string>
<!-- no translation found for wifi_available_sign_in_detailed (6797764740339907572) -->
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ei saanud WiFi-ga ühendust"</string>
- <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" on halb Interneti-ühendus."</string>
+ <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" on halb Interneti-ühendus."</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WiFi Direct"</string>
- <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Käivitage WiFi Directi töö. See lülitab WiFi-kliendi/-tööpunkti töö välja."</string>
- <string name="wifi_p2p_failed_message" msgid="1820097493844848281">"Otsese WiFi-ühenduse käivitamine ebaõnnestus"</string>
- <string name="wifi_p2p_pbc_go_negotiation_request_message" msgid="3170321684621420428">"WiFi Directi ühenduse seadistamise taotlus seadmelt <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Nõustumiseks klõpsake OK."</string>
- <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"WiFi Directi ühenduse seadistuse taotlus seadmelt <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Jätkamiseks sisestage PIN-kood."</string>
- <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"Jätkamiseks tuleb ühenduse seadistamise eesmärgil sisestada partnerseadmesse <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> WPS-i PIN-kood <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g>."</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käivitage WiFi otseühendus. See lülitab välja WiFi kliendi/leviala."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"WiFi otseühenduse käivitamine ebaõnnestus."</string>
+ <string name="accept" msgid="1645267259272829559">"Nõustu"</string>
+ <string name="decline" msgid="2112225451706137894">"Keeldu"</string>
+ <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Kutse on saadetud"</string>
+ <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Kutse ühendamiseks"</string>
+ <string name="wifi_p2p_from_message" msgid="570389174731951769">"Saatja:"</string>
+ <string name="wifi_p2p_to_message" msgid="248968974522044099">"Saaja:"</string>
+ <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Sisestage nõutav PIN-kood:"</string>
+ <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kood:"</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"WiFi Direct on sees"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Puuted seadete jaoks"</string>
<string name="select_character" msgid="3365550120617701745">"Sisesta tähemärk"</string>
@@ -976,7 +992,7 @@
<string name="sim_removed_message" msgid="2333164559970958645">"Mobiilsidevõrk ei ole saadaval, kuni sisestate kehtiva SIM-kaardi ja taaskäivitate seadme."</string>
<string name="sim_done_button" msgid="827949989369963775">"Valmis"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM-kaart lisatud"</string>
- <string name="sim_added_message" msgid="1209265974048554242">"Mobiilsidevõrku pääsemiseks peate oma seadme taaskäivitama."</string>
+ <string name="sim_added_message" msgid="6599945301141050216">"Mobiilsidevõrku pääsemiseks taaskäivitage seade."</string>
<string name="sim_restart_button" msgid="4722407842815232347">"Taaskäivita"</string>
<string name="time_picker_dialog_title" msgid="8349362623068819295">"Kellaaja määramine"</string>
<string name="date_picker_dialog_title" msgid="5879450659453782278">"Kuupäeva määramine"</string>
@@ -985,31 +1001,31 @@
<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>
- <string name="usb_storage_activity_title" msgid="2399289999608900443">"USB-massmälu"</string>
+ <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB-massmälu"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB ühendatud"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"Olete arvutiga USB kaudu ühendatud. Puudutage allolevat nuppu, kui soovite faile arvuti ja Androidi USB-mäluseadme vahel kopeerida."</string>
- <string name="usb_storage_message" product="default" msgid="4510858346516069238">"Olete arvutiga USB kaudu ühendatud. Puudutage allolevat nuppu, kui soovite faile arvuti ja Androidi SD-kaardi vahel kopeerida."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Teil on arvutiga ühendus USB kaudu. Puudutage allolevat nuppu, kui soovite faile arvuti ja Androidi USB-salvestusruumi vahel kopeerida."</string>
+ <string name="usb_storage_message" product="default" msgid="805351000446037811">"Olete arvutiga ühendatud USB kaudu. Puudutage allolevat nuppu, kui soovite faile arvuti ja Androidi SD-kaardi vahel kopeerida."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Lülita USB-mäluseade sisse"</string>
- <string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Probleem USB-mäluseadme kasutamisel USB-mäluseadmena."</string>
- <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Probleem SD-kaardi kasutamisel USB-mäluseadmena."</string>
+ <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Probleem USB-salvestusruumi kasutamisel USB-mäluseadmena."</string>
+ <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Probleem SD-kaardi kasutamisel USB-mäluseadmena."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB ühendatud"</string>
- <string name="usb_storage_notification_message" msgid="7380082404288219341">"Valige failide kopeerimiseks arvutist/arvutisse."</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Puudutage, et kopeerida faile arvutist/arvutisse."</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Lülita USB-mäluseade välja"</string>
- <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Valige USB-mäluseadme väljalülitamiseks."</string>
+ <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB-salvestusruumi väljalülitamiseks puudutage."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"USB kasutusel"</string>
- <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"Enne USB-mäluseadme väljalülitamist veenduge, et olete oma Androidi USB-mäluseadme arvutist eemaldanud (väljutanud)."</string>
- <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"Enne USB-seadme väljalülitamist veenduge, et olete oma Androidi SD-kaardi arvutist eemaldanud (“väljutanud“)."</string>
+ <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Enne USB-salvestusruumi väljalülitamist eraldage (väljutage) Androidi USB-salvestusruum arvutist."</string>
+ <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Enne USB-salvestusruumi väljalülitamist eemaldage (väljutage) Androidi SD-kaart arvutist."</string>
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Lülita USB-mäluseade välja"</string>
- <string name="usb_storage_stop_error_message" msgid="143881914840412108">"USB-mäluseadme väljalülitamisel ilmnes probleem. Veenduge, et olete USB-hosti eemaldanud ja proovige siis uuesti."</string>
+ <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Tekkis probleem USB-salvestusruumi väljalülitamisega. Kontrollige, kas olete USB-hosti eemaldanud, ja proovige seejärel uuesti."</string>
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Lülita USB-mäluseade sisse"</string>
- <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"USB-seadme sisselülitamisel peatuvad mõned teie kasutatavad rakendused ja on võimalik, et neid ei saa kasutada seni, kuni USB-seadme välja lülitate."</string>
+ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Kui lülitate USB-salvestusruumi sisse, võivad mõned kasutatavad rakendused peatuda ega pruugi olla saadaval enne USB-salvestusruumi väljalülitamist."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB toiming ebaõnnestus"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ühendatud meediumiseadmena"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Ühendatud kaamerana"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Ühendatud installijana"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
- <string name="usb_notification_message" msgid="4447869605109736382">"Puudutage teiste USB-valikute kuvamiseks"</string>
+ <string name="usb_notification_message" msgid="2290859399983720271">"Puudutage teisi USB valikuid."</string>
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Vormind. USB-seade?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Kas vormindada SD-kaart?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Kõik USB-mäluseadmele salvestatud failid kustutatakse. Seda toimingut ei saa tagasi võtta."</string>
@@ -1027,12 +1043,12 @@
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Vigade kontrollimine."</string>
<string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Tühi USB-mäluseade"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Tühi SD-kaart"</string>
- <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"USB-mäluseade on tühi või toetuseta failisüsteemiga."</string>
- <string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"SD-kaart on tühi või toetuseta failisüsteemiga."</string>
+ <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB-salvestusruum on tühi või ei toeta failisüsteemi."</string>
+ <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD-kaart on tühi või ei toetata selle failisüsteemi."</string>
<string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Kahjustatud USB-mäluseade"</string>
<string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Kahjustatud SD-kaart"</string>
- <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="529021299294450667">"USB-mäluseade on kahjustatud. Võib-olla peate selle uuesti vormindama."</string>
- <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"SD-kaart on kahjustatud. Võib-olla peale selle uuesti vormindama."</string>
+ <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB-salvestusruum on kahjustatud. Proovige uuesti vormindada."</string>
+ <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD-kaart on kahjustatud. Proovige uuesti vormindada."</string>
<string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB-seade eemaldati ootamatult"</string>
<string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD-kaart on ootamatult eemaldatud"</string>
<string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Andmekao vältimiseks lahutage USB-mäluseade enne eemaldamist."</string>
@@ -1045,13 +1061,13 @@
<string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Eemaldatud SD-kaart"</string>
<string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB-mäluseade eemaldatud. Sisestage uus meedium."</string>
<string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD-kaart on eemaldatud. Sisestage uus."</string>
- <string name="activity_list_empty" msgid="4168820609403385789">"Sobivat tegevust ei leitud"</string>
+ <string name="activity_list_empty" msgid="1675388330786841066">"Sobivat tegevust ei leitud"</string>
<string name="permlab_pkgUsageStats" msgid="8787352074326748892">"värskenda komponentide kasutusstatistikat"</string>
<string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Võimaldab rakendusel muuta komponendi kohta kogutud kasutusstatistikat. Mitte kasutada tavarakenduste puhul."</string>
<string name="permlab_copyProtectedData" msgid="4341036311211406692">"Sisu kopeerimine"</string>
<string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Võimaldab rakendusel võtta sisu kopeerimiseks appi vaikekonteinerteenuse. Mitte kasutada tavarakenduste puhul."</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Suumi juhtimiseks puudutage kaks korda"</string>
- <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Viga vidina täitmisel"</string>
+ <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Vidinat ei saanud lisada."</string>
<string name="ime_action_go" msgid="8320845651737369027">"Mine"</string>
<string name="ime_action_search" msgid="658110271822807811">"Otsing"</string>
<string name="ime_action_send" msgid="2316166556349314424">"Saada"</string>
@@ -1063,35 +1079,35 @@
<string name="create_contact_using" msgid="4947405226788104538">"Loo kontakt"\n"numbriga <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Üks või mitu rakendust taotlevad luba pääseda nüüd ja edaspidi teie kontole juurde."</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Kas soovite taotluse lubada?"</string>
- <string name="grant_permissions_header_text" msgid="2722567482180797717">"Juurdepääsutaotlus"</string>
+ <string name="grant_permissions_header_text" msgid="6874497408201826708">"Juurdepääsutaotlus"</string>
<string name="allow" msgid="7225948811296386551">"Luba"</string>
<string name="deny" msgid="2081879885755434506">"Keela"</string>
- <string name="permission_request_notification_title" msgid="5390555465778213840">"Luba taotletud"</string>
- <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Luba taotletud"\n"kontole <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+ <string name="permission_request_notification_title" msgid="6486759795926237907">"Taotletud luba"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Luba on taotletud"\n"kontole <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"Sisestusmeetod"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Sünkroonimine"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Juurdepääsetavus"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Taustapilt"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Muutke taustapilti"</string>
- <string name="vpn_title" msgid="8219003246858087489">"VPN on aktiveeritud."</string>
+ <string name="vpn_title" msgid="19615213552042827">"VPN on aktiveeritud"</string>
<string name="vpn_title_long" msgid="6400714798049252294">"VPN-i aktiveeris <xliff:g id="APP">%s</xliff:g>"</string>
- <string name="vpn_text" msgid="1610714069627824309">"Koputage võrgu haldamiseks."</string>
- <string name="vpn_text_long" msgid="4907843483284977618">"Ühendatud seansiga <xliff:g id="SESSION">%s</xliff:g>. Koputage võrgu haldamiseks"</string>
+ <string name="vpn_text" msgid="3011306607126450322">"Võrgu haldamiseks puudutage."</string>
+ <string name="vpn_text_long" msgid="6407351006249174473">"Ühendatud seansiga <xliff:g id="SESSION">%s</xliff:g>. Võrgu haldamiseks puudutage."</string>
<string name="upload_file" msgid="2897957172366730416">"Valige fail"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Ühtegi faili pole valitud"</string>
<string name="reset" msgid="2448168080964209908">"Lähtesta"</string>
<string name="submit" msgid="1602335572089911941">"Saada"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Autorežiim lubatud"</string>
- <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Valige autorežiimist väljumiseks."</string>
+ <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Autorežiimist väljumiseks puudutage."</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"Jagamine või tööpunkt on aktiivne"</string>
- <string name="tethered_notification_message" msgid="3067108323903048927">"Puudutage seadistamiseks"</string>
+ <string name="tethered_notification_message" msgid="6857031760103062982">"Seadistamiseks puudutage."</string>
<string name="back_button_label" msgid="2300470004503343439">"Tagasi"</string>
<string name="next_button_label" msgid="1080555104677992408">"Järgmine"</string>
<string name="skip_button_label" msgid="1275362299471631819">"Jäta vahele"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"Kõrge mobiilse andmeside kasutus"</string>
- <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Puudutage, et saada lisateavet mobiilse andmeside kasutamise kohta"</string>
+ <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Mobiilse andmeside kasutamise kohta lisateabe saamiseks puudutage."</string>
<string name="throttled_notification_title" msgid="6269541897729781332">"Mobiili andmemahupiirang ületatud"</string>
- <string name="throttled_notification_message" msgid="4712369856601275146">"Puudutage, et saada lisateavet mobiilse andmeside kasutamise kohta"</string>
+ <string name="throttled_notification_message" msgid="5443457321354907181">"Mobiilse andmeside kasutamise kohta lisateabe saamiseks puudutage."</string>
<string name="no_matches" msgid="8129421908915840737">"Vasted puuduvad"</string>
<string name="find_on_page" msgid="1946799233822820384">"Otsige lehelt"</string>
<plurals name="matches_found">
@@ -1099,10 +1115,10 @@
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g>/<xliff:g id="TOTAL">%d</xliff:g>"</item>
</plurals>
<string name="action_mode_done" msgid="7217581640461922289">"Valmis"</string>
- <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"USB-mäluseadme lahutamine ..."</string>
- <string name="progress_unmounting" product="default" msgid="5556813978958789471">"SD-kaardi lahutamine ..."</string>
- <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"USB-mäluseadme kustutamine ..."</string>
- <string name="progress_erasing" product="default" msgid="2115214724367534095">"SD-kaardi kustutamine ..."</string>
+ <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB-salvestusruumi eemaldamine ..."</string>
+ <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD-kaardi eemaldamine ..."</string>
+ <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB-salvestusruumi kustutamine ..."</string>
+ <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD-kaardi kustutamine ..."</string>
<string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB-mäluseadme tühjendamine ebaõnnestus."</string>
<string name="format_error" product="default" msgid="7315248696644510935">"SD-kaardi kustutamine ebaõnnestus."</string>
<string name="media_bad_removal" msgid="7960864061016603281">"SD-kaart eemaldati enne lahutamist."</string>
@@ -1121,17 +1137,17 @@
<string name="gpsVerifYes" msgid="2346566072867213563">"Jah"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"Ei"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"Kustutamiste piirarv on ületatud"</string>
- <string name="sync_too_many_deletes_desc" msgid="7030265992955132593">"Sünkroonimise tüübi <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> konto <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> kohta on <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> kustutatud üksust. Mida te teha sooviksite?"</string>
- <string name="sync_really_delete" msgid="8933566316059338692">"Kustuta üksused."</string>
- <string name="sync_undo_deletes" msgid="8610996708225006328">"Kustutamiste tagasivõtmine"</string>
- <string name="sync_do_nothing" msgid="8717589462945226869">"Ära tee praegu midagi."</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Kustutatavad üksused kontol <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> sünkroonimistüübi <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> jaoks: <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g>. Mida soovite teha?"</string>
+ <string name="sync_really_delete" msgid="2572600103122596243">"Kustuta üksused"</string>
+ <string name="sync_undo_deletes" msgid="2941317360600338602">"Võtke kustutamised tagasi"</string>
+ <string name="sync_do_nothing" msgid="3743764740430821845">"Ära tee praegu midagi"</string>
<string name="choose_account_label" msgid="5655203089746423927">"Konto valimine"</string>
<string name="add_account_label" msgid="2935267344849993553">"Konto lisamine"</string>
- <string name="choose_account_text" msgid="6891230675141555481">"Millist kontot sooviksite kasutada?"</string>
+ <string name="choose_account_text" msgid="6303348737197849675">"Millist kontot soovite kasutada?"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Lisa konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Suurenda"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähenda"</string>
- <string name="number_picker_increment_scroll_mode" msgid="1343063395404990189">"<xliff:g id="VALUE">%s</xliff:g> – puudutage ja hoidke all."</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> puudutage ja hoidke."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Suurendamiseks lohistage üles, vähendamiseks alla."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minutite arvu suurendamine"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minutite arvu vähendamine"</string>
@@ -1173,29 +1189,29 @@
<string name="description_target_silent" msgid="893551287746522182">"Hääletu"</string>
<string name="description_target_soundon" msgid="30052466675500172">"Heli on sees"</string>
<string name="description_target_unlock_tablet" msgid="3833195335629795055">"Avamiseks tõmmake sõrmega."</string>
- <string name="keyboard_headset_required_to_hear_password" msgid="5913502399391940888">"Ühendage peakomplekt, et kuulata paroole."</string>
+ <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Paroolide kuulamiseks ühendage peakomplekt."</string>
<string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
<string name="action_bar_home_description" msgid="5293600496601490216">"Liigu avalehele"</string>
<string name="action_bar_up_description" msgid="2237496562952152589">"Liigu üles"</string>
<string name="action_menu_overflow_description" msgid="2295659037509008453">"Rohkem valikuid"</string>
- <string name="storage_internal" msgid="7556050805474115618">"Sisemälu"</string>
- <string name="storage_sd_card" msgid="8921771478629812343">"SD-kaart"</string>
+ <string name="storage_internal" msgid="4891916833657929263">"Sisemine salvestusruum"</string>
+ <string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
<string name="storage_usb" msgid="3017954059538517278">"USB-mäluseade"</string>
- <string name="extract_edit_menu_button" msgid="302060189057163906">"Muuda ..."</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"Muuda"</string>
<string name="data_usage_warning_title" msgid="1955638862122232342">"Andmete kasutamise hoiatus"</string>
- <string name="data_usage_warning_body" msgid="7217480745540055170">"Kas./sätete vaatamiseks puud.-ge"</string>
+ <string name="data_usage_warning_body" msgid="2814673551471969954">"Kasutuse/sätete vaat. puudutage."</string>
<string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G–3G-andmeside on keelatud"</string>
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-andmeside on keelatud"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiilne andmeside on keelatud"</string>
<string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"WiFi-andmed on keelatud"</string>
- <string name="data_usage_limit_body" msgid="4313857592916426843">"Puudutage lubamiseks"</string>
+ <string name="data_usage_limit_body" msgid="3317964706973601386">"Lubamiseks puudutage."</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G andmemahupiirang ületatud"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G andmemahupiirang ületatud"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"Mobiilne andmemahupiirang ületatud"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"WiFi-andmete piir on ületatud"</string>
- <string name="data_usage_limit_snoozed_body" msgid="2932736326652880660">"<xliff:g id="SIZE">%s</xliff:g> üle kindlaksmääratud piirmäära"</string>
+ <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> üle määratud piirmäära."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Taustandmed on piiratud"</string>
- <string name="data_usage_restricted_body" msgid="5087354814839059798">"Puudutage piirangu eemaldamiseks"</string>
+ <string name="data_usage_restricted_body" msgid="6741521330997452990">"Piirangu eemaldamiseks puudut."</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Turvasertifikaat"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"See sertifikaat on kehtiv."</string>
<string name="issued_to" msgid="454239480274921032">"Väljastatud subjektile:"</string>
@@ -1212,7 +1228,10 @@
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 sõrmejälg:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Kuva kõik"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Tegevuse valimine"</string>
- <string name="share_action_provider_share_with" msgid="5247684435979149216">"Jagamine kasutajaga"</string>
+ <string name="share_action_provider_share_with" msgid="5247684435979149216">"Jagamine rakendusega:"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Seade lukustatud."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
+ <string name="sending" msgid="3245653681008218030">"Saatmine ..."</string>
+ <string name="launchBrowserDefault" msgid="2057951947297614725">"Kas käivitada brauser?"</string>
+ <string name="SetupCallDefault" msgid="5834948469253758575">"Kas vastata kõnele?"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index e2448f96b3dd..7097e436172a 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"تأیید"</string>
<string name="report" msgid="4060218260984795706">"گزارش"</string>
<string name="wait" msgid="7147118217226317732">"منتظر بمانید"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"این صفحه پاسخ نمی‌دهد."\n\n"آیا می‌خواهید آن را ببندید؟"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"برنامه مجدداً هدایت شد"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> اکنون در حال اجرا است."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> از ابتدا راه اندازی شد."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 27a9bf41c9b9..0a60adb4e5eb 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Ilmoita"</string>
<string name="wait" msgid="7147118217226317732">"Odota"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Sivu ei vastaa."\n\n"Haluatko sulkea sen?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Sovelluksen uud.ohjaus"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> on nyt käynnissä."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> käynnistettiin alun perin."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index c6475704e608..d32f48761370 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Rapport"</string>
<string name="wait" msgid="7147118217226317732">"Attendre"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"La page ne répond pas."\n" "\n"Voulez-vous la fermer ?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Application redirigée"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> est maintenant lancée."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Application lancée initialement : <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 3e440ca637a3..7a4f7064284d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"ठीक"</string>
<string name="report" msgid="4060218260984795706">"रिपोर्ट करें"</string>
<string name="wait" msgid="7147118217226317732">"प्रतीक्षा करें"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"पृष्ठ प्रतिसाद नहीं दे रहा है."\n\n"क्‍या आप इसे बंद करना चाहते हैं?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"एप्‍लि. रीडायरेक्‍ट किया गया"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> अभी चल रहा है."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> को वास्‍तविक रूप से लॉन्‍च किया गया था."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 460ec88d04ff..e37be22f7eeb 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"U redu"</string>
<string name="report" msgid="4060218260984795706">"Izvješće"</string>
<string name="wait" msgid="7147118217226317732">"Pričekaj"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Stranica ne reagira."\n\n"Želite li ju zatvoriti?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplikacija preusmjerena"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvodi sada."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> pokrenuta je prva."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 9278bdeb2241..9b3eb5415260 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Jelentés"</string>
<string name="wait" msgid="7147118217226317732">"Várakozás"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Az oldal nem válaszol."\n\n"Szeretné bezárni?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Alkalmazás átirányítva"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> éppen fut."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> volt eredetileg elindítva."</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 30fb87576a47..b61fb42935ea 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Laporkan"</string>
<string name="wait" msgid="7147118217226317732">"Tunggu"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak menanggapi."\n\n"Apakah Anda ingin menutupnya?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Apl dialihkan"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah diluncurkan aslinya."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2cc182f59cd6..ebf7223eaabe 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Segnala"</string>
<string name="wait" msgid="7147118217226317732">"Attendi"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"La pagina non risponde più."\n\n"Vuoi chiuderla?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Applicazione reindirizzata"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> è ora in esecuzione."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> già avviata."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index e9dd004d6b19..69d506e57c27 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"אישור"</string>
<string name="report" msgid="4060218260984795706">"שלח דוח"</string>
<string name="wait" msgid="7147118217226317732">"המתן"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"הדף אינו מגיב."\n\n"האם אתה רוצה לסגור אותו?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"הפנייה מחדש של יישום"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> פועל כעת."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> הופעל במקור."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 234f64c36d2f..cb958e4b8c7e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"レポート"</string>
<string name="wait" msgid="7147118217226317732">"待機"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"ページが応答しません。"\n\n"ページを閉じますか?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"アプリのリダイレクト"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>が実行中です。"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g>が最初に起動していました。"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 804110c17854..216ac7600766 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"확인"</string>
<string name="report" msgid="4060218260984795706">"신고"</string>
<string name="wait" msgid="7147118217226317732">"대기"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"페이지가 응답하지 않습니다."\n\n"페이지를 닫으시겠습니까?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"앱 리디렉션됨"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>이(가) 실행 중입니다."</string>
<string name="launch_warning_original" msgid="188102023021668683">"원래 <xliff:g id="APP_NAME">%1$s</xliff:g>을(를) 실행했습니다."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 9d6bd77ab5a2..7f0370f46303 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"Gerai"</string>
<string name="report" msgid="4060218260984795706">"Ataskaita"</string>
<string name="wait" msgid="7147118217226317732">"Palaukti"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Puslapis neatsako."\n\n"Ar norite jį uždaryti?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Programa peradresuota"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ dabar vykdoma."</string>
<string name="launch_warning_original" msgid="188102023021668683">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ buvo iš pradžių paleista."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 195059c71169..a05248133659 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"Labi"</string>
<string name="report" msgid="4060218260984795706">"Pārskats"</string>
<string name="wait" msgid="7147118217226317732">"Gaidīt"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"No lapas netiek saņemta atbilde."\n\n"Vai vēlaties to aizvērt?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Lietotne ir novirzīta"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> tagad darbojas."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Sākotnēji tika palaista lietojumprogramma <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index a8e733f78784..f6189f2ffe73 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Laporkan"</string>
<string name="wait" msgid="7147118217226317732">"Tunggu"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Laman ini tidak bertindak balas. "\n\n"Adakah anda mahu menutupnya?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Apl diubah hala"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kini sedang berjalan."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> pada asalnya telah dilancarkan."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 7e3fb86e4244..e03b735fa4a4 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Rapportér"</string>
<string name="wait" msgid="7147118217226317732">"Vent"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Siden svarer ikke."\n\n"Vil du lukke den?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Appen er viderekoblet"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører nå."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ble opprinnelig startet."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b956433dc1b7..3a43b8e47c6e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Rapport"</string>
<string name="wait" msgid="7147118217226317732">"Wachten"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer."\n\n"Wilt u de pagina sluiten?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"App verplaatst"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 9c713aadba22..e73f7d6486a1 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -908,13 +908,14 @@
<string name="aerr_application" msgid="932628488013092776">"Niestety, aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> została zatrzymana."</string>
<string name="aerr_process" msgid="4507058997035697579">"Niestety, proces <xliff:g id="PROCESS">%1$s</xliff:g> został zatrzymany."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
- <string name="anr_activity_application" msgid="1904477189057199066">"Aplikacja <xliff:g id="APPLICATION">%2$s</xliff:g> nie odpowiada."\n\n"Czy chcesz ją zamknąć?"</string>
+ <string name="anr_activity_application" msgid="1904477189057199066">"Aplikacja <xliff:g id="APPLICATION">%2$s</xliff:g> nie reaguje."\n\n"Czy chcesz ją zamknąć?"</string>
<string name="anr_activity_process" msgid="5776209883299089767">"Działanie <xliff:g id="ACTIVITY">%1$s</xliff:g> nie odpowiada."\n\n"Czy chcesz je zakończyć?"</string>
- <string name="anr_application_process" msgid="8941757607340481057">"Aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> nie odpowiada. Czy chcesz ją zamknąć?"</string>
+ <string name="anr_application_process" msgid="8941757607340481057">"Aplikacja <xliff:g id="APPLICATION">%1$s</xliff:g> nie reaguje. Czy chcesz ją zamknąć?"</string>
<string name="anr_process" msgid="6513209874880517125">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> nie odpowiada."\n\n"Czy chcesz go zakończyć?"</string>
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Zgłoś"</string>
<string name="wait" msgid="7147118217226317732">"Czekaj"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Strona nie odpowiada na żądania."\n\n"Zamknąć ją?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplikacja przekierowana"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest uruchomiona."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> została pierwotnie uruchomiona."</string>
@@ -1214,12 +1215,12 @@
<string name="ssl_certificate" msgid="6510040486049237639">"Certyfikat zabezpieczeń"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certyfikat jest ważny."</string>
<string name="issued_to" msgid="454239480274921032">"Wystawiony dla:"</string>
- <string name="common_name" msgid="2233209299434172646">"Nazwa pospolita (CN):"</string>
+ <string name="common_name" msgid="2233209299434172646">"Nazwa (CN):"</string>
<string name="org_name" msgid="6973561190762085236">"Organizacja:"</string>
<string name="org_unit" msgid="7265981890422070383">"Jednostka organizacyjna:"</string>
<string name="issued_by" msgid="2647584988057481566">"Wystawca:"</string>
<string name="validity_period" msgid="8818886137545983110">"Ważność:"</string>
- <string name="issued_on" msgid="5895017404361397232">"Data wystawienia:"</string>
+ <string name="issued_on" msgid="5895017404361397232">"Wystawiony:"</string>
<string name="expires_on" msgid="3676242949915959821">"Wygasa:"</string>
<string name="serial_number" msgid="758814067660862493">"Numer seryjny:"</string>
<string name="fingerprints" msgid="4516019619850763049">"Odciski cyfrowe:"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c5e470c24c8b..800013d99de4 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Relatório"</string>
<string name="wait" msgid="7147118217226317732">"Esperar"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"A página deixou de responder. "\n" "\n" Pretende fechá-la?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicação redirecionada"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> está agora a ser executado."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi originalmente iniciado."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 10ac03f73609..c907929cd117 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Informar"</string>
<string name="wait" msgid="7147118217226317732">"Aguardar"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"A página não responde."\n\n"Deseja fechá-la?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicativo redirecionado"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> não está em execução."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> foi iniciado."</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 4d40ddc419f9..bc8d4fbae0b9 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -27,7 +27,8 @@
<string name="terabyteShort" msgid="231613018159186962">"TB"</string>
<string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
<string name="fileSizeSuffix" msgid="7670819340156489359">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
- <!-- outdated translation 6071602020171759109 --> <string name="untitled" msgid="4638956954852782576">"&lt;senza titel&gt;"</string>
+ <!-- no translation found for untitled (4638956954852782576) -->
+ <skip />
<string name="ellipsis" msgid="7899829516048813237">"…"</string>
<!-- no translation found for ellipsis_two_dots (1228078994866030736) -->
<skip />
@@ -44,9 +45,12 @@
<string name="serviceErased" msgid="1288584695297200972">"Stizzà cun success."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"Il pled-clav è nuncorrect."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI terminà."</string>
- <!-- outdated translation 5085454289896032547 --> <string name="badPin" msgid="9015277645546710014">"Il code PIN vegl che Vus avais endatà è nuncorrect."</string>
- <!-- outdated translation 5702522162746042460 --> <string name="badPuk" msgid="5487257647081132201">"Il PUK che Vus avais tippà è nuncorrect."</string>
- <!-- outdated translation 3695902225843339274 --> <string name="mismatchPin" msgid="609379054496863419">"Ils codes PIN che Vus avais endatà n\'èn betg identics."</string>
+ <!-- no translation found for badPin (9015277645546710014) -->
+ <skip />
+ <!-- no translation found for badPuk (5487257647081132201) -->
+ <skip />
+ <!-- no translation found for mismatchPin (609379054496863419) -->
+ <skip />
<string name="invalidPin" msgid="3850018445187475377">"Endatai in code PIN che cuntegna 4 fin 8 cifras."</string>
<!-- no translation found for invalidPuk (8761456210898036513) -->
<skip />
@@ -70,16 +74,20 @@
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"La ID dal telefonader n\'è betg limitada tenor configuraziun predefinida. Proxim clom: limitada."</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"La ID dal telefonader n\'è betg limitada tenor configuraziun predefinida. Proxim clom: betg limitada."</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"Quest servetsch na vegn betg sustegnì."</string>
- <!-- outdated translation 5460892159398802465 --> <string name="CLIRPermanent" msgid="3377371145926835671">"Il parameter per la ID dal telefonader na po betg vegnir modifitgà."</string>
+ <!-- no translation found for CLIRPermanent (3377371145926835671) -->
+ <skip />
<string name="RestrictedChangedTitle" msgid="5592189398956187498">"L\'access limità è vegnì modifitgà."</string>
<string name="RestrictedOnData" msgid="8653794784690065540">"Il servetsch da datas è bloccà."</string>
<string name="RestrictedOnEmergency" msgid="6581163779072833665">"Il servetsch da cloms d\'urgenza è bloccà."</string>
<string name="RestrictedOnNormal" msgid="4953867011389750673">"Il servetsch vocal è bloccà."</string>
- <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Tut ils servetschs vocals èn bloccads."</string>
+ <!-- no translation found for RestrictedOnAllVoice (3396963652108151260) -->
+ <skip />
<string name="RestrictedOnSms" msgid="8314352327461638897">"Il servetsch SMS è bloccà."</string>
- <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Ils servetschs vocals/da datas èn bloccads."</string>
+ <!-- no translation found for RestrictedOnVoiceData (996636487106171320) -->
+ <skip />
<string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Ils servetschs vocals/dad SMS èn bloccads."</string>
- <string name="RestrictedOnAll" msgid="2714924667937117304">"Tut ils servetschs vocals/da datas/da SMS èn bloccads."</string>
+ <!-- no translation found for RestrictedOnAll (5643028264466092821) -->
+ <skip />
<string name="serviceClassVoice" msgid="1258393812335258019">"Vusch"</string>
<string name="serviceClassData" msgid="872456782077937893">"Datas"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
@@ -110,35 +118,56 @@
<string name="fcComplete" msgid="3118848230966886575">"Code da servetsch terminà"</string>
<string name="fcError" msgid="3327560126588500777">"Problem da connexiun u code da funcziun nunvalid"</string>
<string name="httpErrorOk" msgid="1191919378083472204">"OK"</string>
- <!-- outdated translation 2567300624552921790 --> <string name="httpError" msgid="6603022914760066338">"La pagina d\'internet cuntegna ina errur."</string>
- <string name="httpErrorLookup" msgid="4517085806977851374">"Impussibel da chattar la URL."</string>
- <!-- outdated translation 2781440683514730227 --> <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Il schema d\'autentificaziun da la site na vegn betg sustegnì."</string>
- <string name="httpErrorAuth" msgid="7293960746955020542">"L\'autentificaziun n\'è betg reussida."</string>
+ <!-- no translation found for httpError (7956392511146698522) -->
+ <skip />
+ <!-- no translation found for httpErrorLookup (4711687456111963163) -->
+ <skip />
+ <!-- no translation found for httpErrorUnsupportedAuthScheme (6299980280442076799) -->
+ <skip />
+ <!-- no translation found for httpErrorAuth (1435065629438044534) -->
+ <skip />
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"L\'autentificaziun cun agid dad in proxy server n\'è betg reussida."</string>
- <string name="httpErrorConnect" msgid="7623096283505770433">"Betg reussì da connectar cun il server."</string>
- <!-- outdated translation 5047872902739125260 --> <string name="httpErrorIO" msgid="4270874999047767599">"La communicaziun cun il server n\'è betg reussida. Empruvai pli tard anc ina giada."</string>
+ <!-- no translation found for httpErrorConnect (8714273236364640549) -->
+ <skip />
+ <!-- no translation found for httpErrorIO (2340558197489302188) -->
+ <skip />
<string name="httpErrorTimeout" msgid="4743403703762883954">"Surpassà il temp cun connectar al server."</string>
<string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Questa pagina cuntegna memia blers renviaments da server."</string>
- <!-- outdated translation 5257172771607996054 --> <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Quest protocol na vegn betg sustegnì."</string>
- <string name="httpErrorFailedSslHandshake" msgid="3088290300440289771">"Impussibel da stabilir ina connexiun segira."</string>
- <string name="httpErrorBadUrl" msgid="6088183159988619736">"Impussibel dad avrir la pagina. La URL è nunvalida."</string>
- <string name="httpErrorFile" msgid="8250549644091165175">"Impussibel d\'acceder a la datoteca."</string>
- <string name="httpErrorFileNotFound" msgid="5588380756326017105">"La datoteca dumandada n\'è betg vegnida chattada."</string>
+ <!-- no translation found for httpErrorUnsupportedScheme (5015730812906192208) -->
+ <skip />
+ <!-- no translation found for httpErrorFailedSslHandshake (96549606000658641) -->
+ <skip />
+ <!-- no translation found for httpErrorBadUrl (3636929722728881972) -->
+ <skip />
+ <!-- no translation found for httpErrorFile (2170788515052558676) -->
+ <skip />
+ <!-- no translation found for httpErrorFileNotFound (6203856612042655084) -->
+ <skip />
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Actualmain vegnan memia bleras dumondas elavuradas. Empruvai pli tard anc ina giada."</string>
- <string name="notification_title" msgid="1259940370369187045">"Errur cun connectar al conto <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+ <!-- no translation found for notification_title (8967710025036163822) -->
+ <skip />
<string name="contentServiceSync" msgid="8353523060269335667">"Sincronisar"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sincronisar"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Memia blers cuntegns stizzads (<xliff:g id="CONTENT_TYPE">%s</xliff:g>)."</string>
- <!-- outdated translation 6632412458436461203 --> <string name="low_memory" product="tablet" msgid="2292820184396262278">"La memoria dal telefon è occupada! Stizzai datotecas per crear capacitad da memorisar."</string>
- <string name="low_memory" product="default" msgid="6632412458436461203">"La memoria dal telefon è occupada! Stizzai datotecas per crear capacitad da memorisar."</string>
+ <!-- no translation found for low_memory (6494019234102154896) -->
+ <skip />
+ <!-- no translation found for low_memory (3475999286680000541) -->
+ <skip />
<string name="me" msgid="6545696007631404292">"Jau"</string>
- <!-- outdated translation 1319919075463988638 --> <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opziuns dal telefon"</string>
+ <!-- no translation found for power_dialog (8545351420865202853) -->
+ <skip />
<string name="power_dialog" product="default" msgid="1319919075463988638">"Opziuns dal telefon"</string>
<string name="silent_mode" msgid="7167703389802618663">"Modus silenzius"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"Activar il modus senza fil"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"Deactivar il modus senza fil"</string>
<string name="screen_lock" msgid="799094655496098153">"Bloccaziun dal visur"</string>
<string name="power_off" msgid="4266614107412865048">"Serrar"</string>
+ <!-- no translation found for silent_mode_silent (319298163018473078) -->
+ <skip />
+ <!-- no translation found for silent_mode_vibrate (7072043388581551395) -->
+ <skip />
+ <!-- no translation found for silent_mode_ring (8592241816194074353) -->
+ <skip />
<string name="shutdown_progress" msgid="2281079257329981203">"Vegn serrà..."</string>
<!-- no translation found for shutdown_confirm (3385745179555731470) -->
<skip />
@@ -147,8 +176,10 @@
<!-- no translation found for shutdown_confirm_question (2906544768881136183) -->
<skip />
<string name="recent_tasks_title" msgid="3691764623638127888">"Utilisà sco ultim"</string>
- <!-- outdated translation 279702952298056674 --> <string name="no_recent_tasks" msgid="8794906658732193473">"Naginas applicaziuns utilisadas dacurt"</string>
- <!-- outdated translation 2406416831541615258 --> <string name="global_actions" product="tablet" msgid="408477140088053665">"Opziuns dal telefon"</string>
+ <!-- no translation found for no_recent_tasks (8794906658732193473) -->
+ <skip />
+ <!-- no translation found for global_actions (408477140088053665) -->
+ <skip />
<string name="global_actions" product="default" msgid="2406416831541615258">"Opziuns dal telefon"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Bloccaziun dal visur"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Metter ord funcziun"</string>
@@ -163,16 +194,21 @@
<string name="safeMode" msgid="2788228061547930246">"Modus segirà"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Servetschs che custan"</string>
- <!-- outdated translation 8193824940620517189 --> <string name="permgroupdesc_costMoney" msgid="8596717365335027057">"Permetta ad applicaziuns dad exequir acziuns che custan eventualmain."</string>
+ <!-- no translation found for permgroupdesc_costMoney (3293301903409869495) -->
+ <skip />
<string name="permgrouplab_messages" msgid="7521249148445456662">"Voss messadis"</string>
- <!-- outdated translation 7045736972019211994 --> <string name="permgroupdesc_messages" msgid="7821999071003699236">"\"Leger e scriver Voss SMS, e-mails ed auters messadis.\""</string>
+ <!-- no translation found for permgroupdesc_messages (7821999071003699236) -->
+ <skip />
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Vossas infurmaziuns persunalas"</string>
- <!-- outdated translation 5488050357388806068 --> <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Acceder directamain als contacts ed al chalender memorisà sin il telefonin."</string>
+ <!-- no translation found for permgroupdesc_personalInfo (6975389054186265786) -->
+ <skip />
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Acceder directamain als contacts ed al chalender memorisà sin il telefonin."</string>
<string name="permgrouplab_location" msgid="635149742436692049">"Vossa posiziun"</string>
- <string name="permgroupdesc_location" msgid="2430258821648348660">"suandar Vossa posiziun geografica"</string>
+ <!-- no translation found for permgroupdesc_location (5704679763124170100) -->
+ <skip />
<string name="permgrouplab_network" msgid="5808983377727109831">"Communicaziun rait"</string>
- <!-- outdated translation 5035763698958415998 --> <string name="permgroupdesc_network" msgid="4917593670797570584">"Permetta ad applicaziuns l\'access a differentas funcziuns da la rait."</string>
+ <!-- no translation found for permgroupdesc_network (4478299413241861987) -->
+ <skip />
<string name="permgrouplab_accounts" msgid="3359646291125325519">"Voss contos"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Access als contos disponibels"</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Cumonds da la hardware"</string>
@@ -182,62 +218,90 @@
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"Utensils da sistem"</string>
<string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Access e controlla sin nivel datiers al sistem."</string>
<string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Utensils per sviluppaders"</string>
- <!-- outdated translation 9056431193893809814 --> <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Questas funcziunalitads èn mo previsas per ils sviluppaders dad applicaziuns."</string>
+ <!-- no translation found for permgroupdesc_developmentTools (7058828032358142018) -->
+ <skip />
<string name="permgrouplab_storage" msgid="1971118770546336966">"Memoria"</string>
- <!-- outdated translation 9203302214915355774 --> <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Access a la carta SD."</string>
+ <!-- no translation found for permgroupdesc_storage (7442318502446874999) -->
+ <skip />
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Access a la carta SD."</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"deactivar u modifitgar la trav da status"</string>
- <!-- outdated translation 1365473595331989732 --> <string name="permdesc_statusBar" msgid="8434669549504290975">"Permetta a l\'applicaziun da deactivar l\'indicatur da status u agiuntar ed allontanar simbols dal sistem."</string>
+ <!-- no translation found for permdesc_statusBar (8434669549504290975) -->
+ <skip />
<string name="permlab_statusBarService" msgid="7247281911387931485">"trav da status"</string>
- <!-- outdated translation 4097605867643520920 --> <string name="permdesc_statusBarService" msgid="716113660795976060">"Permetta a l\'applicaziun dad esser la trav da status."</string>
+ <!-- no translation found for permdesc_statusBarService (716113660795976060) -->
+ <skip />
<string name="permlab_expandStatusBar" msgid="1148198785937489264">"expander/reducir la trav da status"</string>
- <!-- outdated translation 7088604400110768665 --> <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Permetta a l\'applicaziun da mussar u zuppentar la trav da status."</string>
+ <!-- no translation found for permdesc_expandStatusBar (6917549437129401132) -->
+ <skip />
<string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"interceptar cloms sortints"</string>
- <!-- outdated translation 2228988201852654461 --> <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"\"Permetta ad ina applicaziun dad elavurar ils cloms sortints e da modifitgar il numer che duai vegnir cumponì. Applicaziuns donnegiusas pon uschia eventualmain survegliar, renviar u evitar cloms sortints.\""</string>
+ <!-- no translation found for permdesc_processOutgoingCalls (1152111671618301044) -->
+ <skip />
<string name="permlab_receiveSms" msgid="2697628268086208535">"retschaiver SMS"</string>
- <!-- outdated translation 6298292335965966117 --> <string name="permdesc_receiveSms" msgid="8107887121893611793">"Permetta a l\'applicaziun da retschaiver ed elavurar SMS. Applicaziuns donnegiusas pon uschia survegliar Voss messadis u als stizzar avant ch\'els vegnan mussads."</string>
+ <!-- no translation found for permdesc_receiveSms (8107887121893611793) -->
+ <skip />
<string name="permlab_receiveMms" msgid="8894700916188083287">"retschaiver MMS"</string>
- <!-- outdated translation 4563346832000174373 --> <string name="permdesc_receiveMms" msgid="1424805308566612086">"Permetta a l\'applicaziun da retschaiver ed elavurar MMS. Applicaziuns donnegiusas pon uschia survegliar Voss messadis u als stizzar avant ch\'els vegnan mussads."</string>
+ <!-- no translation found for permdesc_receiveMms (1424805308566612086) -->
+ <skip />
<!-- no translation found for permlab_receiveEmergencyBroadcast (1803477660846288089) -->
<skip />
<!-- no translation found for permdesc_receiveEmergencyBroadcast (848524070262431974) -->
<skip />
<string name="permlab_sendSms" msgid="5600830612147671529">"trametter messadis SMS"</string>
- <!-- outdated translation 1946540351763502120 --> <string name="permdesc_sendSms" msgid="906546667507626156">"Permetta ad applicaziuns da trametter messadis SMS. Applicaziuns donnegiusas pon chaschunar custs cun trametter messadis senza As dumandar."</string>
+ <!-- no translation found for permdesc_sendSms (906546667507626156) -->
+ <skip />
<!-- no translation found for permlab_sendSmsNoConfirmation (4781483105951730228) -->
<skip />
<!-- no translation found for permdesc_sendSmsNoConfirmation (3437759207020400204) -->
<skip />
<string name="permlab_readSms" msgid="4085333708122372256">"leger SMS u MMS"</string>
- <!-- outdated translation 3002170087197294591 --> <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Permetta ad ina applicaziun da leger ils SMS memorisads sin Voss telefonin u sin Vossa carta SIM. Applicaziuns donnegiusas legian uschia eventualmain Voss messadis confidenzials."</string>
- <!-- outdated translation 3002170087197294591 --> <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Permetta ad ina applicaziun da leger ils SMS memorisads sin Voss telefonin u sin Vossa carta SIM. Applicaziuns donnegiusas legian uschia eventualmain Voss messadis confidenzials."</string>
+ <!-- no translation found for permdesc_readSms (2341692916884515613) -->
+ <skip />
+ <!-- no translation found for permdesc_readSms (5653850482025875493) -->
+ <skip />
<string name="permlab_writeSms" msgid="6881122575154940744">"modifitgar SMS u MMS"</string>
- <!-- outdated translation 6299398896177548095 --> <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Permetta ad ina applicaziun da modifitgar SMS memorisads sin Voss telefonin u Vossa carta SIM. Applicaziuns donnegiusas stizzan uschia eventualmain Voss messadis."</string>
- <!-- outdated translation 6299398896177548095 --> <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Permetta ad ina applicaziun da modifitgar SMS memorisads sin Voss telefonin u Vossa carta SIM. Applicaziuns donnegiusas stizzan uschia eventualmain Voss messadis."</string>
+ <!-- no translation found for permdesc_writeSms (5160413947794501538) -->
+ <skip />
+ <!-- no translation found for permdesc_writeSms (7268668709052328567) -->
+ <skip />
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"retschaiver messadis WAP"</string>
- <!-- outdated translation 5979623826128082171 --> <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Permetta a l\'applicaziun da retschaiver ed elavurar messadis WAP. Applicaziuns donnegiusas pon uschia survegliar Voss messadis u als stizzar avant ch\'els vegnan mussads."</string>
- <!-- outdated translation 5005277531132573353 --> <string name="permlab_getTasks" msgid="6466095396623933906">"recuperaziun da las applicaziuns exequidas"</string>
- <!-- outdated translation 7048711358713443341 --> <string name="permdesc_getTasks" msgid="6608159250520381359">"Permetta a l\'applicaziun da recuperar infurmaziuns davart incumbensas che vegnan exequidas u èn gist vegnidas exequidas. Applicaziuns donnegiusas pon uschia obtegnair infurmaziuns privatas concernent autras applicaziuns."</string>
- <!-- outdated translation 5669588525059921549 --> <string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganisar las applicaziuns che vegnan exequidas"</string>
- <!-- outdated translation 126252774270522835 --> <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Permetta ad ina applicaziun da spustar las incumbensas en il fund davant u en il fund davos. Applicaziuns donnegiusas pon sa mussar en il fund davant senza Vossa autorisaziun."</string>
+ <!-- no translation found for permdesc_receiveWapPush (7983455145335316872) -->
+ <skip />
+ <!-- no translation found for permlab_getTasks (6466095396623933906) -->
+ <skip />
+ <!-- no translation found for permdesc_getTasks (6608159250520381359) -->
+ <skip />
+ <!-- no translation found for permlab_reorderTasks (2018575526934422779) -->
+ <skip />
+ <!-- no translation found for permdesc_reorderTasks (4175137612205663399) -->
+ <skip />
<!-- no translation found for permlab_removeTasks (6821513401870377403) -->
<skip />
- <!-- no translation found for permdesc_removeTasks (1000226123143185094) -->
+ <!-- no translation found for permdesc_removeTasks (1394714352062635493) -->
+ <skip />
+ <!-- no translation found for permlab_setDebugApp (3022107198686584052) -->
+ <skip />
+ <!-- no translation found for permdesc_setDebugApp (4474512416299013256) -->
<skip />
- <!-- outdated translation 4339730312925176742 --> <string name="permlab_setDebugApp" msgid="3022107198686584052">"activar il debugging da l\'applicaziun"</string>
- <!-- outdated translation 5584310661711990702 --> <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Permetta ad ina applicaziun dad activar il debugging per autras applicaziuns. Applicaziuns donnegiusas pon uschia serrar autras applicaziuns."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"modifitgar ils parameters da la UI"</string>
- <!-- outdated translation 3465121501528064399 --> <string name="permdesc_changeConfiguration" msgid="4104052649900380324">"Permetta ad ina applicaziun da modifitgar la configuraziun actuala (per exempel la grondezza da la scrittira ed ils parameters regiunals)."</string>
+ <!-- no translation found for permdesc_changeConfiguration (4372223873154296076) -->
+ <skip />
<string name="permlab_enableCarMode" msgid="5684504058192921098">"activar il modus dad auto"</string>
- <!-- outdated translation 5673461159384850628 --> <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permetta ad ina applicaziun dad activar il modus dad auto."</string>
+ <!-- no translation found for permdesc_enableCarMode (4853187425751419467) -->
+ <skip />
<string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"interrumper ils process en il fund davos"</string>
- <!-- outdated translation 2908829602869383753 --> <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Permetta ad ina applicaziun da serrar process en il fund davos dad autras applicaziuns era en cas da memoria suffizienta."</string>
- <!-- outdated translation 1447830113260156236 --> <string name="permlab_forceStopPackages" msgid="2329627428832067700">"serrar autras applicaziuns cun forza"</string>
- <!-- outdated translation 7263036616161367402 --> <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Permetta ad ina applicaziun da sfurzar autras applicaziuns da serrar."</string>
- <!-- outdated translation 1804196839880393631 --> <string name="permlab_forceBack" msgid="652935204072584616">"serrar l\'applicaziun cun forza"</string>
- <!-- outdated translation 6534109744159919013 --> <string name="permdesc_forceBack" msgid="3892295830419513623">"Permetta ad ina applicaziun da serrar tut las activitads che vegnan exequidas en il fund davant e da las spustar en il fund davos. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_killBackgroundProcesses (931129103262126617) -->
+ <skip />
+ <!-- no translation found for permlab_forceStopPackages (2329627428832067700) -->
+ <skip />
+ <!-- no translation found for permdesc_forceStopPackages (5253157296183940812) -->
+ <skip />
+ <!-- no translation found for permlab_forceBack (652935204072584616) -->
+ <skip />
+ <!-- no translation found for permdesc_forceBack (3892295830419513623) -->
+ <skip />
<string name="permlab_dump" msgid="1681799862438954752">"verifitgar il status intern dal sistem"</string>
- <!-- outdated translation 2198776174276275220 --> <string name="permdesc_dump" msgid="1778299088692290329">"\"Permetta ad ina applicaziun da vesair il status intern dal sistem. Applicaziuns donnegiusas pon uschia obtegnair numerusas infurmaziuns privatas u segiradas, a las qualas ellas na dastgassan normalmain mai acceder.\""</string>
+ <!-- no translation found for permdesc_dump (1778299088692290329) -->
+ <skip />
<!-- no translation found for permlab_retrieve_window_content (8022588608994589938) -->
<skip />
<!-- no translation found for permdesc_retrieve_window_content (3193269069469700265) -->
@@ -245,42 +309,62 @@
<string name="permlab_shutdown" msgid="7185747824038909016">"serrar parzialmain"</string>
<string name="permdesc_shutdown" msgid="7046500838746291775">"Metta l\'administratur dad activitads en in stadi da pausa. El na vegn betg serrà dal tut."</string>
<string name="permlab_stopAppSwitches" msgid="4138608610717425573">"evitar il midar tranter applicaziuns"</string>
- <!-- outdated translation 3857886086919033794 --> <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Impedescha che l\'utilisader midia ad ina autra applicaziun."</string>
- <!-- outdated translation 7811586187574696296 --> <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"survegliar e controllar l\'aviar dad applicaziuns"</string>
- <!-- outdated translation 3228701938345388092 --> <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permetta ad ina applicaziun da survegliar e controllar l\'aviar dad activitads dal sistem. Applicaziuns donnegiusas pon uschia periclitar l\'entir sistem. Questa permissiun è mo previsa per process da svilup e mai per il diever normal dal telefonin."</string>
+ <!-- no translation found for permdesc_stopAppSwitches (8262195802582255021) -->
+ <skip />
+ <!-- no translation found for permlab_runSetActivityWatcher (892239094867182656) -->
+ <skip />
+ <!-- no translation found for permdesc_runSetActivityWatcher (6003603162578577406) -->
+ <skip />
<string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"trametter in broadcast senza pachet"</string>
- <!-- outdated translation 3453286591439891260 --> <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Permetta ad ina applicaziun da trametter in avis cura ch\'in pachet d\'applicaziun è vegnì stizzà. Applicaziuns donnegiusas pon utilisar questa funcziunalitad per interrumper l\'execuziun dad autras applicaziuns."</string>
+ <!-- no translation found for permdesc_broadcastPackageRemoved (6621901216207931089) -->
+ <skip />
<string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"trametter in broadcast retschavì per SMS"</string>
- <!-- outdated translation 9122419277306740155 --> <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Permetta ad ina applicaziun da trametter in avis cura ch\'in messadi vegn retschavì. Applicaziuns donnegiusas pon utilisar questa funcziunalitad per dar da crair ch\'in messadi saja arrivà."</string>
+ <!-- no translation found for permdesc_broadcastSmsReceived (4152037720034365492) -->
+ <skip />
<string name="permlab_broadcastWapPush" msgid="3145347413028582371">"trametter in broadcast retschavì da WAP-PUSH"</string>
- <!-- outdated translation 3955303669461378091 --> <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Permetta ad ina applicaziun da trametter in avis cura ch\'in messadi WAP PUSH vegn retschavì. Applicaziuns donnegiusas pon utilisar questa funcziunalitad per dar da crair ch\'in MMS saja arrivà u per remplazzar il cuntegn da mintga pagina d\'internet cun datas donnegiusas."</string>
+ <!-- no translation found for permdesc_broadcastWapPush (4783402525039442729) -->
+ <skip />
<string name="permlab_setProcessLimit" msgid="2451873664363662666">"limitar il dumber maximal da process exequids"</string>
- <!-- outdated translation 7824786028557379539 --> <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Permetta ad ina applicaziun da controllar il dumber maximal da process che pon vegnir exequids a medem temp. Betg previs per applicaziuns normalas."</string>
- <!-- outdated translation 5342837862439543783 --> <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"serrar tut las applicaziuns en il fund davos"</string>
- <!-- outdated translation 8773936403987091620 --> <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Permetta ad ina applicaziun da controllar schebain activitads vegnan adina terminadas sch\'ellas vegnan stuschadas en il fund davos. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_setProcessLimit (7318061314040879542) -->
+ <skip />
+ <!-- no translation found for permlab_setAlwaysFinish (238828158465736054) -->
+ <skip />
+ <!-- no translation found for permdesc_setAlwaysFinish (7471310652868841499) -->
+ <skip />
<string name="permlab_batteryStats" msgid="7863923071360031652">"modifitgar las datas da l\'accu"</string>
- <!-- outdated translation 5847319823772230560 --> <string name="permdesc_batteryStats" msgid="6835186932305744068">"Permetta da modifitgar las datas statisticas da l\'accu. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_batteryStats (6835186932305744068) -->
+ <skip />
<string name="permlab_backup" msgid="470013022865453920">"controllar las copias da segirezza e la restauraziun dal sistem"</string>
- <!-- outdated translation 4837493065154256525 --> <string name="permdesc_backup" msgid="6912230525140589891">"Permetta a l\'applicaziun da controllar il mecanissem da copias da segirezza e da restauraziun dal sistem. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_backup (6912230525140589891) -->
+ <skip />
<!-- no translation found for permlab_confirm_full_backup (5557071325804469102) -->
<skip />
<!-- no translation found for permdesc_confirm_full_backup (1748762171637699562) -->
<skip />
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"mussar fanestras betg autorisadas"</string>
- <!-- outdated translation 5895082268284998469 --> <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Permetta da crear fanestras destinadas per l\'utilisaziun da l\'interfatscha d\'utilisader interna dal sistem. Questa funcziun n\'è betg previsa per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_internalSystemWindow (7458387759461466397) -->
+ <skip />
<string name="permlab_systemAlertWindow" msgid="3372321942941168324">"mussar avertiments dal sistem"</string>
- <!-- outdated translation 5109622689323490558 --> <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Permetta ad ina applicaziun da mussar fanestras cun avertiments dal sistem. Applicaziuns donnegiusas pon uschia occupar l\'entir visur dal telefonin."</string>
+ <!-- no translation found for permdesc_systemAlertWindow (8507863469978066409) -->
+ <skip />
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"modifitgar la sveltezza globala da las animaziuns"</string>
- <!-- outdated translation 7181522138912391988 --> <string name="permdesc_setAnimationScale" msgid="6505093307223395456">"Permetta ad ina applicaziun da modifitgar da tut temp la sveltezza generala da las animaziuns (per las pudair far ir pli svelt u pli plaun)."</string>
- <!-- outdated translation 17124341698093865 --> <string name="permlab_manageAppTokens" msgid="1286505717050121370">"administrar tokens dad applicaziuns"</string>
- <!-- outdated translation 977127907524195988 --> <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Permetta ad applicaziuns da crear ed administrar lur agens tokens cun ignorar lur urden da zavrar Z normal. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_setAnimationScale (7690063428924343571) -->
+ <skip />
+ <!-- no translation found for permlab_manageAppTokens (1286505717050121370) -->
+ <skip />
+ <!-- no translation found for permdesc_manageAppTokens (8043431713014395671) -->
+ <skip />
<string name="permlab_injectEvents" msgid="1378746584023586600">"smatgar tastas e tastas da controlla"</string>
- <!-- outdated translation 3946098050410874715 --> <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Permetta ad ina applicaziun da furnir ses agens cumonds (tastas smatgadas etc.) ad autras applicaziuns. Applicaziuns donnegiusas pon utilisar questa funcziunalitad per surpigliar la controlla da Voss telefonin."</string>
- <!-- outdated translation 3946098050410874715 --> <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Permetta ad ina applicaziun da furnir ses agens cumonds (tastas smatgadas etc.) ad autras applicaziuns. Applicaziuns donnegiusas pon utilisar questa funcziunalitad per surpigliar la controlla da Voss telefonin."</string>
+ <!-- no translation found for permdesc_injectEvents (206352565599968632) -->
+ <skip />
+ <!-- no translation found for permdesc_injectEvents (653128057572326253) -->
+ <skip />
<string name="permlab_readInputState" msgid="469428900041249234">"registrar endataziuns sur la tastatura ed acziuns"</string>
- <!-- outdated translation 5132879321450325445 --> <string name="permdesc_readInputState" msgid="8387754901688728043">"\"Permetta ad ina applicaziun dad identifitgar las tastas che Vus smatgais, era durant l\'utilisaziun dad in auter program (durant l\'endataziun dad in pled-clav, per exempel). Applicaziuns normalas na duessan betg avair access a questa funcziun.\""</string>
+ <!-- no translation found for permdesc_readInputState (8387754901688728043) -->
+ <skip />
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"associar cun ina metoda d\'endataziun"</string>
- <!-- outdated translation 3734838321027317228 --> <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permetta da sa fixar al nivel d\'interfatscha pli aut dad ina metoda d\'endataziun. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_bindInputMethod (3250440322807286331) -->
+ <skip />
<!-- no translation found for permlab_bindTextService (7358378401915287938) -->
<skip />
<!-- no translation found for permdesc_bindTextService (8151968910973998670) -->
@@ -290,66 +374,112 @@
<!-- no translation found for permdesc_bindVpnService (2067845564581693905) -->
<skip />
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"sa fixar vid in fund davos"</string>
- <!-- outdated translation 5287754520361915347 --> <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permetta da sa fixar al nivel d\'interfatscha pli aut dad ina metoda d\'endataziun. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_bindWallpaper (7108428692595491668) -->
+ <skip />
<!-- no translation found for permlab_bindRemoteViews (5697987759897367099) -->
<skip />
<!-- no translation found for permdesc_bindRemoteViews (4717987810137692572) -->
<skip />
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"interacziun cun in administratur dad apparats"</string>
- <!-- outdated translation 8714424333082216979 --> <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Permetta al possessur da trametter intenziuns a l\'administratur dal apparat periferic. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_bindDeviceAdmin (569715419543907930) -->
+ <skip />
<string name="permlab_setOrientation" msgid="3365947717163866844">"midar l\'orientaziun dal visur"</string>
- <!-- outdated translation 6335814461615851863 --> <string name="permdesc_setOrientation" msgid="3046126619316671476">"Permetta a l\'applicaziun da midar da tut temp la orientaziun dal visur. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_setOrientation (3046126619316671476) -->
+ <skip />
<!-- no translation found for permlab_setPointerSpeed (9175371613322562934) -->
<skip />
<!-- no translation found for permdesc_setPointerSpeed (6866563234274104233) -->
<skip />
- <!-- outdated translation 4255467255488653854 --> <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"trametter signals Linux a las applicaziuns"</string>
- <!-- outdated translation 3565530463215015289 --> <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Permetta a l\'applicaziun da pretender ch\'il signal furnì vegnia tramess a tut ils process persistents."</string>
- <!-- outdated translation 8659652042401085862 --> <string name="permlab_persistentActivity" msgid="8841113627955563938">"exequir permanentamain applicaziuns"</string>
- <!-- outdated translation 5037199778265006008 --> <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Permetta ad ina applicaziun da render persistent atgnas cumponentas per ch\'il sistem na po betg utilisar questas per autras applicaziuns."</string>
- <!-- outdated translation 3343439331576348805 --> <string name="permlab_deletePackages" msgid="184385129537705938">"stizzar applicaziuns"</string>
- <!-- outdated translation 3634943677518723314 --> <string name="permdesc_deletePackages" msgid="7411480275167205081">"Permetta ad ina applicaziun da stizzar pachets da datas Android. Applicaziuns donnegiusas pon utilisar questa funcziun per stizzar applicaziuns impurtantas."</string>
- <!-- outdated translation 2192134353540277878 --> <string name="permlab_clearAppUserData" msgid="274109191845842756">"stizzar datas dad ina autra applicaziun"</string>
- <!-- outdated translation 7546345080434325456 --> <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Permetta ad ina applicaziun da stizzar las datas da l\'utilisader."</string>
- <!-- outdated translation 1518556602634276725 --> <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"stizzar ils caches dad autras applicaziuns"</string>
- <!-- outdated translation 2283074077168165971 --> <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Permetta ad ina applicaziun da stizzar las datotecas en il cache."</string>
- <!-- outdated translation 4799785352306641460 --> <string name="permlab_getPackageSize" msgid="7472921768357981986">"evaluar la capacitad da memoria occupada da l\'applicaziun"</string>
- <!-- outdated translation 5557253039670753437 --> <string name="permdesc_getPackageSize" msgid="3921068154420738296">"\"Permetta ad ina applicaziun dad obtegnair la grondezza dal code, da las datas e dal cache.\""</string>
- <!-- outdated translation 335800214119051089 --> <string name="permlab_installPackages" msgid="2199128482820306924">"installar directamain applicaziuns"</string>
- <!-- outdated translation 526669220850066132 --> <string name="permdesc_installPackages" msgid="5628530972548071284">"Permetta ad ina applicaziun dad installar pachets novs u actualisads dad Android. Applicaziuns donnegiusas pon utilisar questa funcziunalitad per agiuntar novas applicaziuns che han tut las permissiuns pussaivlas."</string>
- <!-- outdated translation 4747698311163766540 --> <string name="permlab_clearAppCache" msgid="7487279391723526815">"stizzar las datas dal cache da tut las applicaziuns"</string>
- <!-- outdated translation 7740465694193671402 --> <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Permetta ad ina applicaziun da dar liber capacitad da memorisar dal telefonin cun stizzar datotecas en l\'ordinatur da cache da l\'applicaziun. L\'access è per regla limità a process da sistem."</string>
- <!-- outdated translation 7740465694193671402 --> <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Permetta ad ina applicaziun da dar liber capacitad da memorisar dal telefonin cun stizzar datotecas en l\'ordinatur da cache da l\'applicaziun. L\'access è per regla limità a process da sistem."</string>
- <!-- outdated translation 728454979946503926 --> <string name="permlab_movePackage" msgid="3289890271645921411">"Spustar resursas d\'applicaziun"</string>
- <!-- outdated translation 6323049291923925277 --> <string name="permdesc_movePackage" msgid="319562217778244524">"Permetta ad ina applicaziun da spustar resursas d\'applicaziun dad in medium intern ad in medium extern e viceversa."</string>
- <!-- outdated translation 4811921703882532070 --> <string name="permlab_readLogs" msgid="6615778543198967614">"leger datotecas da protocol dal sistem"</string>
- <!-- outdated translation 2257937955580475902 --> <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permetta ad ina applicaziun da leger las differentas datotecas da protocol dal sistem. Quai pussibilitescha dad obtegnair infurmaziuns generalas davart il diever da Voss telefon che na duessan betg cuntegnair datas persunalas u privatas."</string>
- <!-- outdated translation 2257937955580475902 --> <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permetta ad ina applicaziun da leger las differentas datotecas da protocol dal sistem. Quai pussibilitescha dad obtegnair infurmaziuns generalas davart il diever da Voss telefon che na duessan betg cuntegnair datas persunalas u privatas."</string>
+ <!-- no translation found for permlab_signalPersistentProcesses (4539002991947376659) -->
+ <skip />
+ <!-- no translation found for permdesc_signalPersistentProcesses (4896992079182649141) -->
+ <skip />
+ <!-- no translation found for permlab_persistentActivity (8841113627955563938) -->
+ <skip />
+ <!-- no translation found for permdesc_persistentActivity (4909910271316074418) -->
+ <skip />
+ <!-- no translation found for permlab_deletePackages (184385129537705938) -->
+ <skip />
+ <!-- no translation found for permdesc_deletePackages (7411480275167205081) -->
+ <skip />
+ <!-- no translation found for permlab_clearAppUserData (274109191845842756) -->
+ <skip />
+ <!-- no translation found for permdesc_clearAppUserData (4625323684125459488) -->
+ <skip />
+ <!-- no translation found for permlab_deleteCacheFiles (3128665571837408675) -->
+ <skip />
+ <!-- no translation found for permdesc_deleteCacheFiles (3812998599006730196) -->
+ <skip />
+ <!-- no translation found for permlab_getPackageSize (7472921768357981986) -->
+ <skip />
+ <!-- no translation found for permdesc_getPackageSize (3921068154420738296) -->
+ <skip />
+ <!-- no translation found for permlab_installPackages (2199128482820306924) -->
+ <skip />
+ <!-- no translation found for permdesc_installPackages (5628530972548071284) -->
+ <skip />
+ <!-- no translation found for permlab_clearAppCache (7487279391723526815) -->
+ <skip />
+ <!-- no translation found for permdesc_clearAppCache (3523396284474042284) -->
+ <skip />
+ <!-- no translation found for permdesc_clearAppCache (5067988373366292186) -->
+ <skip />
+ <!-- no translation found for permlab_movePackage (3289890271645921411) -->
+ <skip />
+ <!-- no translation found for permdesc_movePackage (319562217778244524) -->
+ <skip />
+ <!-- no translation found for permlab_readLogs (6615778543198967614) -->
+ <skip />
+ <!-- no translation found for permdesc_readLogs (82061313293455151) -->
+ <skip />
+ <!-- no translation found for permdesc_readLogs (2063438140241560443) -->
+ <skip />
+ <!-- no translation found for permlab_anyCodecForPlayback (715805555823881818) -->
+ <skip />
+ <!-- no translation found for permdesc_anyCodecForPlayback (8283912488433189010) -->
+ <skip />
<string name="permlab_diagnostic" msgid="8076743953908000342">"leger/scriver en resursas che appartegnan a diagnostics"</string>
- <!-- outdated translation 3121238373951637049 --> <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permetta ad ina applicaziun da leger e modifitgar tut ils elements ella gruppa da diagnosa (per exempel las datotecas en /dev). Quai po avair consequenzas negativas per la stabilitad e la segirezza dal sistem e duess vegnir permess mo a programs da diagnosa specifics per la hardware mess a disposiziun dal producider u dal gestiunari da la rait."</string>
- <!-- outdated translation 79425198834329406 --> <string name="permlab_changeComponentState" msgid="6335576775711095931">"activar u deactivar cumponentas dad applicaziuns"</string>
- <!-- outdated translation 4569107043246700630 --> <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"\"Permetta ad ina applicaziun dad activar u deactivar cumponentas dad autras applicaziuns. Applicaziuns donnegiusas pon uschia deactivar funcziuns impurtantas dal telefonin. Faschai attenziun cun permetter l\'access a questa funcziun perquai ch\'ella permetta da render nunduvrablas, incoerentas ed instabilas las cumponentas da las applicaziuns.\""</string>
- <!-- outdated translation 4569107043246700630 --> <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"\"Permetta ad ina applicaziun dad activar u deactivar cumponentas dad autras applicaziuns. Applicaziuns donnegiusas pon uschia deactivar funcziuns impurtantas dal telefonin. Faschai attenziun cun permetter l\'access a questa funcziun perquai ch\'ella permetta da render nunduvrablas, incoerentas ed instabilas las cumponentas da las applicaziuns.\""</string>
- <!-- outdated translation 3393305202145172005 --> <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"definir las applicaziuns preferidas"</string>
- <!-- outdated translation 760008293501937546 --> <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permetta ad ina applicaziun da modifitgar Vossas applicaziuns preferidas. Applicaziuns donnegiusas pon uschia remplazzar en il zuppà applicaziuns che vegnan gist exequidas ed imitar Vossas applicaziuns existentas cun la finamira da rimnar datas persunalas da Vus."</string>
+ <!-- no translation found for permdesc_diagnostic (6608295692002452283) -->
+ <skip />
+ <!-- no translation found for permlab_changeComponentState (6335576775711095931) -->
+ <skip />
+ <!-- no translation found for permdesc_changeComponentState (8887435740982237294) -->
+ <skip />
+ <!-- no translation found for permdesc_changeComponentState (1827232484416505615) -->
+ <skip />
+ <!-- no translation found for permlab_setPreferredApplications (8463181628695396391) -->
+ <skip />
+ <!-- no translation found for permdesc_setPreferredApplications (4973986762241783712) -->
+ <skip />
<string name="permlab_writeSettings" msgid="1365523497395143704">"modifitgar parameters generals dal sistem"</string>
- <!-- outdated translation 838789419871034696 --> <string name="permdesc_writeSettings" msgid="7775723441558907181">"Permetta ad ina applicaziun da modifitgar las datas dals parameters dal sistem. Applicaziuns donnegiusas pon utilisar questa funcziun per donnegiar la configuraziun da Voss sistem."</string>
+ <!-- no translation found for permdesc_writeSettings (7775723441558907181) -->
+ <skip />
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"modifitgar ils parameters da segirezza dal sistem"</string>
- <!-- outdated translation 5497873143539034724 --> <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Permetta ad ina applicaziun da modifitgar las datas da configuraziun da segirezza dal sistem. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_writeSecureSettings (8159535613020137391) -->
+ <skip />
<string name="permlab_writeGservices" msgid="2149426664226152185">"modifitgar Google Services Map"</string>
- <!-- outdated translation 6602362746516676175 --> <string name="permdesc_writeGservices" msgid="1287309437638380229">"Permetta ad ina applicaziun da modifitgar la charta da servetschs Google. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_writeGservices (1287309437638380229) -->
+ <skip />
<string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"aviar automaticamain suenter ch\'il sistem è avià"</string>
- <!-- outdated translation 698336728415008796 --> <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"\"Permetta ad ina applicaziun dad aviar sasez suenter ch\'il sistem è vegnì avià. Qua tras po l\'aviar dal telefonin durar pli ditg, ultra da quai po l\'entir sistem vegnir retardà cun l\'activitad permanenta da l\'applicaziun.\""</string>
- <!-- outdated translation 698336728415008796 --> <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"\"Permetta ad ina applicaziun dad aviar sasez suenter ch\'il sistem è vegnì avià. Qua tras po l\'aviar dal telefonin durar pli ditg, ultra da quai po l\'entir sistem vegnir retardà cun l\'activitad permanenta da l\'applicaziun.\""</string>
+ <!-- no translation found for permdesc_receiveBootCompleted (7390304664116880704) -->
+ <skip />
+ <!-- no translation found for permdesc_receiveBootCompleted (513950589102617504) -->
+ <skip />
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"trametter in broadcast permanent"</string>
- <!-- outdated translation 1920045289234052219 --> <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Permetta ad ina applicaziun da trametter broadcasts persistents che na sa serran betg a la fin dal broadcast. Applicaziuns donnegiusas pon uschia render plaun ed instabil il telefonin cun occupar memia blera memoria."</string>
- <!-- outdated translation 1920045289234052219 --> <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Permetta ad ina applicaziun da trametter broadcasts persistents che na sa serran betg a la fin dal broadcast. Applicaziuns donnegiusas pon uschia render plaun ed instabil il telefonin cun occupar memia blera memoria."</string>
+ <!-- no translation found for permdesc_broadcastSticky (1181582512022829259) -->
+ <skip />
+ <!-- no translation found for permdesc_broadcastSticky (3287869131621514325) -->
+ <skip />
<string name="permlab_readContacts" msgid="6219652189510218240">"leger las datas da contact"</string>
- <!-- outdated translation 3371591512896545975 --> <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Permetta ad ina applicaziun da leger tut las datas da contacts (adressas) memorisadas sin Voss telefonin. Applicaziuns donnegiusas pon utilisar questa funcziun per trametter Vossas datas ad autras persunas."</string>
- <!-- outdated translation 3371591512896545975 --> <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Permetta ad ina applicaziun da leger tut las datas da contacts (adressas) memorisadas sin Voss telefonin. Applicaziuns donnegiusas pon utilisar questa funcziun per trametter Vossas datas ad autras persunas."</string>
+ <!-- no translation found for permdesc_readContacts (4028657556924039119) -->
+ <skip />
+ <!-- no translation found for permdesc_readContacts (2032222056456498547) -->
+ <skip />
<string name="permlab_writeContacts" msgid="644616215860933284">"scriver datas da contact"</string>
- <!-- outdated translation 3924383579108183601 --> <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Permetta ad ina applicaziun da modifitgar tut las datas da contact (adressas) memorisadas sin Voss telefonin. Applicaziuns donnegiusas pon utilisar questa funcziun per stizzar u modifitgar Vossas datas da contact."</string>
- <!-- outdated translation 3924383579108183601 --> <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Permetta ad ina applicaziun da modifitgar tut las datas da contact (adressas) memorisadas sin Voss telefonin. Applicaziuns donnegiusas pon utilisar questa funcziun per stizzar u modifitgar Vossas datas da contact."</string>
+ <!-- no translation found for permdesc_writeContacts (988969759110632978) -->
+ <skip />
+ <!-- no translation found for permdesc_writeContacts (5075164818647934067) -->
+ <skip />
<!-- no translation found for permlab_readProfile (6824681438529842282) -->
<skip />
<!-- no translation found for permdesc_readProfile (94520753797630679) -->
@@ -366,59 +496,96 @@
<skip />
<!-- no translation found for permdesc_writeSocialStream (3496277176955721451) -->
<skip />
- <!-- outdated translation 6898987798303840534 --> <string name="permlab_readCalendar" msgid="5972727560257612398">"leger eveniments da chalender"</string>
- <!-- outdated translation 5533029139652095734 --> <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Permetta ad ina applicaziun da leger tut ils eveniments da chalender memorisads sin Voss telefonin. Applicaziuns donnegiusas pon uschia trametter Voss eveniments da chalender ad autras persunas."</string>
- <!-- outdated translation 5533029139652095734 --> <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Permetta ad ina applicaziun da leger tut ils eveniments da chalender memorisads sin Voss telefonin. Applicaziuns donnegiusas pon uschia trametter Voss eveniments da chalender ad autras persunas."</string>
- <!-- outdated translation 3894879352594904361 --> <string name="permlab_writeCalendar" msgid="8438874755193825647">"agiuntar u modifitgar eveniments en il chalender e trametter e-mails als envidads"</string>
- <!-- outdated translation 2988871373544154221 --> <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Permetta ad ina applicaziun dad agiuntar u modifitgar eveniments en Voss chalender che pon trametter e-mails ad envidads. Applicaziuns donnegiusas pon uschia stizzar u modifitgar las datas en Voss chalender u trametter e-mails ad envidads."</string>
+ <!-- no translation found for permlab_readCalendar (5972727560257612398) -->
+ <skip />
+ <!-- no translation found for permdesc_readCalendar (2338414551004122687) -->
+ <skip />
+ <!-- no translation found for permdesc_readCalendar (5693933067751827753) -->
+ <skip />
+ <!-- no translation found for permlab_writeCalendar (8438874755193825647) -->
+ <skip />
+ <!-- no translation found for permdesc_writeCalendar (2243771395254848873) -->
+ <skip />
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"creaziun da funtaunas da posiziun fictivas per motivs da test"</string>
- <!-- outdated translation 7648286063459727252 --> <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Permetta da crear funtaunas da localisaziun fictivas per motivs da test. Applicaziuns donnegiusas pon uschia remplazzar la posiziun ed il status returnà da las vairas funtaunas sco GPS u Voss gestiunari da la rait."</string>
+ <!-- no translation found for permdesc_accessMockLocation (7577931556422993949) -->
+ <skip />
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access als cumonds supplementars da purschiders da posiziuns geograficas"</string>
- <!-- outdated translation 1948144701382451721 --> <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Permetta d\'acceder a cumonds supplementars da purschiders da posiziuns geograficas. Applicaziuns donnegiusas pon uschia eventualmain disturbar il funcziunament da GPS u autras funtaunas da localisaziun geografica."</string>
+ <!-- no translation found for permdesc_accessLocationExtraCommands (6737736970602176133) -->
+ <skip />
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"permetter l\'installaziun d\'in purschider da servetschs da localisaziun"</string>
- <!-- outdated translation 5449175116732002106 --> <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Crear funtaunas da localisaziun fictivas per motivs da test. Applicaziuns donnegiusas pon uschia remplazzar la posiziun ed il status returnads da las funtaunas vairas sco GPS u Voss gestiunari da la rait u survegliar Vossa posiziun geografica e la transmetter ad ina funtauna externa."</string>
+ <!-- no translation found for permdesc_installLocationProvider (1742577679350078373) -->
+ <skip />
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"posiziun exacta (GPS)"</string>
- <!-- outdated translation 7411213317434337331 --> <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Permetta d\'acceder a funtaunas da localisaziun exactas sco GPS (Global Positioning System) sche in tal è disponibel. Applicaziuns donnegiusas pon uschia identifitgar Vossa posiziun geografica e consumar energia supplementara da l\'accu."</string>
- <!-- outdated translation 7411213317434337331 --> <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Permetta d\'acceder a funtaunas da localisaziun exactas sco GPS (Global Positioning System) sche in tal è disponibel. Applicaziuns donnegiusas pon uschia identifitgar Vossa posiziun geografica e consumar energia supplementara da l\'accu."</string>
+ <!-- no translation found for permdesc_accessFineLocation (5326423948268164934) -->
+ <skip />
+ <!-- no translation found for permdesc_accessFineLocation (7130267914433890869) -->
+ <skip />
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"Posiziun geografica approximativa (sin basa da la rait)"</string>
- <!-- outdated translation 8235655958070862293 --> <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"\"Acceda a funtaunas approximativas da localisaziun (per exempel bancas da datas da raits mobilas) per determinar la posiziun geografica dal telefonin, sche questa opziun è disponibla. Applicaziuns donnegiusas pon utilisar questa funcziun per vegnir a savair nua che Vus sa chattais circa.\""</string>
- <!-- outdated translation 8235655958070862293 --> <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"\"Acceda a funtaunas approximativas da localisaziun (per exempel bancas da datas da raits mobilas) per determinar la posiziun geografica dal telefonin, sche questa opziun è disponibla. Applicaziuns donnegiusas pon utilisar questa funcziun per vegnir a savair nua che Vus sa chattais circa.\""</string>
+ <!-- no translation found for permdesc_accessCoarseLocation (5460726396318105483) -->
+ <skip />
+ <!-- no translation found for permdesc_accessCoarseLocation (8900795778057579522) -->
+ <skip />
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"access a SurfaceFlinger"</string>
- <!-- outdated translation 6805241830020733025 --> <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permetta ad ina applicaziun dad utilisar las funcziuns SurfaceFlinger datiers al nivel dal sistem."</string>
+ <!-- no translation found for permdesc_accessSurfaceFlinger (1041619516733293551) -->
+ <skip />
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leger il paraculp da frame"</string>
- <!-- outdated translation 5777679658669057819 --> <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permetta ad ina applicaziun da leger il cuntegn dal paraculp da frame."</string>
+ <!-- no translation found for permdesc_readFrameBuffer (4937405521809454680) -->
+ <skip />
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifitgar Voss parameters audio"</string>
- <!-- outdated translation 5793461287365991922 --> <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Permetta a l\'applicaziun da modifitgar ils parameters generals dad audio (per exempel il volumen e routing)."</string>
+ <!-- no translation found for permdesc_modifyAudioSettings (7343951185408396919) -->
+ <skip />
<string name="permlab_recordAudio" msgid="3876049771427466323">"registrar audio"</string>
- <!-- outdated translation 6493228261176552356 --> <string name="permdesc_recordAudio" msgid="2387462233976248635">"Permetta a l\'applicaziun dad acceder a la via d\'access per registraziuns dad audio."</string>
+ <!-- no translation found for permdesc_recordAudio (2387462233976248635) -->
+ <skip />
<string name="permlab_camera" msgid="3616391919559751192">"fotografar e registrar videos"</string>
- <!-- outdated translation 6004878235852154239 --> <string name="permdesc_camera" msgid="1507407407002492176">"Permetta a l\'applicaziun da fotografar e da registrar videos cun la camera. Uschia po l\'applicaziun rimnar da tut temp maletgs fatgs cun la camera."</string>
- <!-- outdated translation 8337817093326370537 --> <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"deactivar permanentamain il telefonin"</string>
+ <!-- no translation found for permdesc_camera (1507407407002492176) -->
+ <skip />
+ <!-- no translation found for permlab_brick (2961292205764488304) -->
+ <skip />
<string name="permlab_brick" product="default" msgid="8337817093326370537">"deactivar permanentamain il telefonin"</string>
- <!-- outdated translation 5569526552607599221 --> <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Permetta ad ina applicaziun da deactivar definitivamain il telefon. Questa autorisaziun è fitg privlusa."</string>
- <!-- outdated translation 5569526552607599221 --> <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Permetta ad ina applicaziun da deactivar definitivamain il telefon. Questa autorisaziun è fitg privlusa."</string>
- <!-- outdated translation 2898560872462638242 --> <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"sfurzar il telefonin da reaviar"</string>
+ <!-- no translation found for permdesc_brick (4334818808001699530) -->
+ <skip />
+ <!-- no translation found for permdesc_brick (5788903297627283099) -->
+ <skip />
+ <!-- no translation found for permlab_reboot (3436634972561795002) -->
+ <skip />
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"sfurzar il telefonin da reaviar"</string>
- <!-- outdated translation 7914933292815491782 --> <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Permetta a l\'applicaziun da sfurzar il telefonin da reaviar."</string>
- <!-- outdated translation 7914933292815491782 --> <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Permetta a l\'applicaziun da sfurzar il telefonin da reaviar."</string>
+ <!-- no translation found for permdesc_reboot (8172056180063700741) -->
+ <skip />
+ <!-- no translation found for permdesc_reboot (5326008124289989969) -->
+ <skip />
<string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"montar e demontar sistems da datotecas"</string>
- <!-- outdated translation 6253263792535859767 --> <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Permetta a l\'applicaziun da montar e demontar sistems da datotecas per apparats periferics da memoria mobila."</string>
+ <!-- no translation found for permdesc_mount_unmount_filesystems (1829290701658992347) -->
+ <skip />
<string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"formataziun da la memoria externa"</string>
- <!-- outdated translation 574060044906047386 --> <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Permetta a l\'applicaziun da formatar memoria mobila."</string>
- <!-- outdated translation 1070364079249834666 --> <string name="permlab_asec_access" msgid="3411338632002193846">"obtegnair infurmaziuns davart la memoria segira"</string>
- <!-- outdated translation 7691616292170590244 --> <string name="permdesc_asec_access" msgid="3094563844593878548">"Permetta a l\'applicaziun dad obtegnair infurmaziuns davart la memoria segira."</string>
- <!-- outdated translation 7312078032326928899 --> <string name="permlab_asec_create" msgid="6414757234789336327">"crear ina memoria segira"</string>
- <!-- outdated translation 7041802322759014035 --> <string name="permdesc_asec_create" msgid="4558869273585856876">"Permetta a l\'applicaziun da crear ina memoria segira."</string>
- <!-- outdated translation 7787322878955261006 --> <string name="permlab_asec_destroy" msgid="526928328301618022">"allontanar la memoria segira"</string>
- <!-- outdated translation 5740754114967893169 --> <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Permetta a l\'applicaziun dad allontanar la memoria segira."</string>
- <!-- outdated translation 7517449694667828592 --> <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"montar/demontar la memoria segira"</string>
- <!-- outdated translation 5438078121718738625 --> <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Permetta a l\'applicaziun da montar/demontar la memoria segira."</string>
- <!-- outdated translation 5685344390439934495 --> <string name="permlab_asec_rename" msgid="7496633954080472417">"renumnar la memoria segira"</string>
- <!-- outdated translation 1387881770708872470 --> <string name="permdesc_asec_rename" msgid="1794757588472127675">"Permetta a l\'applicaziun da renumnar la memoria segira."</string>
+ <!-- no translation found for permdesc_mount_format_filesystems (8784268246779198627) -->
+ <skip />
+ <!-- no translation found for permlab_asec_access (3411338632002193846) -->
+ <skip />
+ <!-- no translation found for permdesc_asec_access (3094563844593878548) -->
+ <skip />
+ <!-- no translation found for permlab_asec_create (6414757234789336327) -->
+ <skip />
+ <!-- no translation found for permdesc_asec_create (4558869273585856876) -->
+ <skip />
+ <!-- no translation found for permlab_asec_destroy (526928328301618022) -->
+ <skip />
+ <!-- no translation found for permdesc_asec_destroy (7218749286145526537) -->
+ <skip />
+ <!-- no translation found for permlab_asec_mount_unmount (8877998101944999386) -->
+ <skip />
+ <!-- no translation found for permdesc_asec_mount_unmount (3451360114902490929) -->
+ <skip />
+ <!-- no translation found for permlab_asec_rename (7496633954080472417) -->
+ <skip />
+ <!-- no translation found for permdesc_asec_rename (1794757588472127675) -->
+ <skip />
<string name="permlab_vibrate" msgid="7768356019980849603">"controllar la vibraziun"</string>
- <!-- outdated translation 2886677177257789187 --> <string name="permdesc_vibrate" msgid="6284989245902300945">"Permetta a l\'applicaziun da controllar la vibraziun."</string>
+ <!-- no translation found for permdesc_vibrate (6284989245902300945) -->
+ <skip />
<string name="permlab_flashlight" msgid="2155920810121984215">"controllar la glischina"</string>
- <!-- outdated translation 6433045942283802309 --> <string name="permdesc_flashlight" msgid="6522284794568368310">"Permetta a l\'applicaziun da controllar la glischina."</string>
+ <!-- no translation found for permdesc_flashlight (6522284794568368310) -->
+ <skip />
<!-- no translation found for permlab_manageUsb (1113453430645402723) -->
<skip />
<!-- no translation found for permdesc_manageUsb (7776155430218239833) -->
@@ -428,112 +595,180 @@
<!-- no translation found for permdesc_accessMtp (6532961200486791570) -->
<skip />
<string name="permlab_hardware_test" msgid="4148290860400659146">"testar la hardware"</string>
- <!-- outdated translation 3668894686500081699 --> <string name="permdesc_hardware_test" msgid="6597964191208016605">"Permetta ad ina applicaziun da controllar differents apparats periferics per motivs da test da hardware."</string>
+ <!-- no translation found for permdesc_hardware_test (6597964191208016605) -->
+ <skip />
<string name="permlab_callPhone" msgid="3925836347681847954">"telefonar directamain a numers da telefon"</string>
- <!-- outdated translation 3369867353692722456 --> <string name="permdesc_callPhone" msgid="6396463004110544744">"Permetta a l\'applicaziun da far telefons senza Vossa intervenziun. Applicaziuns donnegiusas pon uschia chaschunar telefons nunspetgads sin Voss quint da telefon. Questa funcziun permetta dentant betg da telefonar a numers d\'urgenza."</string>
+ <!-- no translation found for permdesc_callPhone (6396463004110544744) -->
+ <skip />
<string name="permlab_callPrivileged" msgid="4198349211108497879">"telefonar directamain a mintga numer"</string>
- <!-- outdated translation 244405067160028452 --> <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Permetta a l\'applicaziun da cumponer mintga numer (inclus numers d\'urgenza) senza Vossa intervenziun. Applicaziuns donnegiusas pon uschia far telefons nunnecessaris ed illegals a numers d\'urgenza."</string>
- <!-- outdated translation 5604848095315421425 --> <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"aviar directamain la configuraziun dal telefonin CDMA"</string>
+ <!-- no translation found for permdesc_callPrivileged (1689024901509996810) -->
+ <skip />
+ <!-- no translation found for permlab_performCdmaProvisioning (4842576994144604821) -->
+ <skip />
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"aviar directamain la configuraziun dal telefonin CDMA"</string>
- <!-- outdated translation 6457447676108355905 --> <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Permetta a l\'applicaziun dad aviar il provediment CDMA. Applicaziuns donnegiusas pon uschia aviar inutilmain il provediment CDMA."</string>
+ <!-- no translation found for permdesc_performCdmaProvisioning (1994193538802314186) -->
+ <skip />
<string name="permlab_locationUpdates" msgid="7785408253364335740">"controllar ils avis ad actualisaziuns da la posiziun geografica"</string>
- <!-- outdated translation 2300018303720930256 --> <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Permetta l\'activaziun/deactivaziun dad avis ad actualisaziuns da la posiziun geografica che derivan dal signal da radio. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_locationUpdates (1120741557891438876) -->
+ <skip />
<string name="permlab_checkinProperties" msgid="7855259461268734914">"access a las caracteristicas check-in"</string>
- <!-- outdated translation 7150307006141883832 --> <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Permetta l\'access (leger e scriver) ad elements transmess dal servetsch check-in. Betg previs per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_checkinProperties (4024526968630194128) -->
+ <skip />
<string name="permlab_bindGadget" msgid="776905339015863471">"tscherner ils widgets"</string>
- <!-- outdated translation 2098697834497452046 --> <string name="permdesc_bindGadget" msgid="8261326938599049290">"Permetta a l\'applicaziun dad annunziar al sistem tge widgets che pon vegnir utilisads da tge applicaziun. Cun questa permissiun pon applicaziuns autorisar l\'access a datas persunalas per autras applicaziuns. Questa opziun n\'è betg previsa per applicaziuns normalas."</string>
+ <!-- no translation found for permdesc_bindGadget (8261326938599049290) -->
+ <skip />
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"modifitgar il status dal telefon"</string>
- <!-- outdated translation 3302284561346956587 --> <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"\"Permetta ad ina applicaziun da controllar las funcziunalitads telefonicas da l\'apparat. Ina applicaziun po uschia midar la rait, deactivar ed activar il signal radiofonic dal telefon etc. senza As avertir.\""</string>
+ <!-- no translation found for permdesc_modifyPhoneState (1029877529007686732) -->
+ <skip />
<string name="permlab_readPhoneState" msgid="2326172951448691631">"leger il status e l\'identitad dal telefon"</string>
- <!-- outdated translation 8987653603298258459 --> <string name="permdesc_readPhoneState" msgid="5127767618743602782">"\"Permetta a l\'applicaziun dad acceder a las funcziuns da clom dal telefonin. Ina applicaziun cun questas permissiuns po eruir il numer che quest telefonin utilisescha, schebain i vegn telefonà ed identifitgar il numer clamà etc.\""</string>
- <!-- outdated translation 573480187941496130 --> <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evitar ch\'il telefon midia en il modus stand-by"</string>
+ <!-- no translation found for permdesc_readPhoneState (5127767618743602782) -->
+ <skip />
+ <!-- no translation found for permlab_wakeLock (1531731435011495015) -->
+ <skip />
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar ch\'il telefon midia en il modus stand-by"</string>
- <!-- outdated translation 7584036471227467099 --> <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Permetta ad ina applicaziun dad evitar ch\'il telefon midia en il modus standby."</string>
- <!-- outdated translation 7584036471227467099 --> <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Permetta ad ina applicaziun dad evitar ch\'il telefon midia en il modus standby."</string>
- <!-- outdated translation 4928622470980943206 --> <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"metter en/ord funcziun l\'apparat"</string>
+ <!-- no translation found for permdesc_wakeLock (7311319824400447868) -->
+ <skip />
+ <!-- no translation found for permdesc_wakeLock (8559100677372928754) -->
+ <skip />
+ <!-- no translation found for permlab_devicePower (2787034722616350417) -->
+ <skip />
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"metter en/ord funcziun l\'apparat"</string>
- <!-- outdated translation 4577331933252444818 --> <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Permetta ad ina applicaziun dad activar u deactivar il telefonin."</string>
- <!-- outdated translation 4577331933252444818 --> <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Permetta ad ina applicaziun dad activar u deactivar il telefonin."</string>
+ <!-- no translation found for permdesc_devicePower (6689862878984631831) -->
+ <skip />
+ <!-- no translation found for permdesc_devicePower (6037057348463131032) -->
+ <skip />
<string name="permlab_factoryTest" msgid="3715225492696416187">"exequir en il modus da test da fabrica"</string>
- <!-- outdated translation 8136644990319244802 --> <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Permetta d\'exequir sco test da fabrica datiers al nivel dal sistem cun autorisar l\'access a la hardware dal telefonin. Questa funcziunalitad è mo disponibla sch\'il telefonin sa chatta en il modus da test da fabrica."</string>
+ <!-- no translation found for permdesc_factoryTest (3952059318359653091) -->
+ <skip />
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Permetta d\'exequir sco test da fabrica datiers al nivel dal sistem cun autorisar l\'access a la hardware dal telefonin. Questa funcziunalitad è mo disponibla sch\'il telefonin sa chatta en il modus da test da fabrica."</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"definir la culissa"</string>
- <!-- outdated translation 6417041752170585837 --> <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Permetta a l\'applicaziun da definir il fund davos dal sistem."</string>
+ <!-- no translation found for permdesc_setWallpaper (7373447920977624745) -->
+ <skip />
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"definir ils indicaturs da grondezza per il fund davos"</string>
- <!-- outdated translation 6019479164008079626 --> <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Permetta a l\'applicaziun da definir la grondezza dal fund dal visur."</string>
+ <!-- no translation found for permdesc_setWallpaperHints (8235784384223730091) -->
+ <skip />
<string name="permlab_masterClear" msgid="2315750423139697397">"reinizialisar il sistem cun ses parameters originals"</string>
- <!-- outdated translation 5033465107545174514 --> <string name="permdesc_masterClear" msgid="3665380492633910226">"\"Permetta ad ina applicaziun da restaurar il stadi original dal sistem. Qua tras vegnan tut las datas, las configuraziuns e las applicaziuns installadas stizzadas.\""</string>
+ <!-- no translation found for permdesc_masterClear (3665380492633910226) -->
+ <skip />
<string name="permlab_setTime" msgid="2021614829591775646">"drizzar l\'ura"</string>
- <!-- outdated translation 667294309287080045 --> <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Permetta ad ina applicaziun da drizzar l\'ura dal telefonin."</string>
- <!-- outdated translation 667294309287080045 --> <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Permetta ad ina applicaziun da drizzar l\'ura dal telefonin."</string>
+ <!-- no translation found for permdesc_setTime (1896341438151152881) -->
+ <skip />
+ <!-- no translation found for permdesc_setTime (1855702730738020) -->
+ <skip />
<string name="permlab_setTimeZone" msgid="2945079801013077340">"definir la zona d\'urari"</string>
- <!-- outdated translation 1902540227418179364 --> <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Permetta ad ina applicaziun da modifitgar la zona d\'urari dal telefonin."</string>
- <!-- outdated translation 1902540227418179364 --> <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Permetta ad ina applicaziun da modifitgar la zona d\'urari dal telefonin."</string>
+ <!-- no translation found for permdesc_setTimeZone (1676983712315827645) -->
+ <skip />
+ <!-- no translation found for permdesc_setTimeZone (4499943488436633398) -->
+ <skip />
<string name="permlab_accountManagerService" msgid="4829262349691386986">"agir sco administratur da contos"</string>
- <!-- outdated translation 6056903274106394752 --> <string name="permdesc_accountManagerService" msgid="2684502137670299915">"Permetta ad ina applicaziun da telefonar ad autentificaturs da contos."</string>
+ <!-- no translation found for permdesc_accountManagerService (1948455552333615954) -->
+ <skip />
<string name="permlab_getAccounts" msgid="4549918644233460103">"tschertgar contos enconuschents"</string>
- <!-- outdated translation 6839262446413155394 --> <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Permetta ad ina applicaziun da consultar la glista dals contos enconuschents al telefonin."</string>
- <!-- outdated translation 6839262446413155394 --> <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Permetta ad ina applicaziun da consultar la glista dals contos enconuschents al telefonin."</string>
+ <!-- no translation found for permdesc_getAccounts (3238360555257773358) -->
+ <skip />
+ <!-- no translation found for permdesc_getAccounts (2735689364629830348) -->
+ <skip />
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"agir sco autentificatur da contos"</string>
- <!-- outdated translation 4006839406474208874 --> <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"\"Permetta ad ina applicaziun dad utilisar las funcziuns d\'autentificaziun da conto da l\'administratur da contos, inclus funcziuns per crear contos ed obtegnair e definir lur pleds-clav.\""</string>
+ <!-- no translation found for permdesc_authenticateAccounts (5472124296908977260) -->
+ <skip />
<string name="permlab_manageAccounts" msgid="4440380488312204365">"administrar la glista da contos"</string>
- <!-- outdated translation 8804114016661104517 --> <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Permetta ad ina applicaziun dad agiuntar ed allontanar contos e stizzar lur pleds-clav."</string>
+ <!-- no translation found for permdesc_manageAccounts (8698295625488292506) -->
+ <skip />
<string name="permlab_useCredentials" msgid="6401886092818819856">"utilisar las infurmaziuns dad autentificaziun dad in conto"</string>
- <!-- outdated translation 7416570544619546974 --> <string name="permdesc_useCredentials" msgid="7984227147403346422">"Permetta ad ina applicaziun da dumandar tokens d\'autentificaziun."</string>
+ <!-- no translation found for permdesc_useCredentials (7984227147403346422) -->
+ <skip />
<string name="permlab_accessNetworkState" msgid="6865575199464405769">"mussar il status da la rait"</string>
- <!-- outdated translation 558721128707712766 --> <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Permetta ad ina applicaziun da vesair ils status da tut las raits."</string>
+ <!-- no translation found for permdesc_accessNetworkState (479772796952547198) -->
+ <skip />
<string name="permlab_createNetworkSockets" msgid="9121633680349549585">"access cumplet a l\'internet"</string>
- <!-- outdated translation 4593339106921772192 --> <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Permetta ad ina applicaziun da crear sockets da rait."</string>
- <!-- outdated translation 7823599210086622545 --> <string name="permlab_writeApnSettings" msgid="505660159675751896">"scriver parameters per nums da puncts d\'access"</string>
- <!-- outdated translation 7443433457842966680 --> <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"\"Permetta ad ina applicaziun da modifitgar ils parameters APN (num dals puncts d\'access), sco proxy ni port da mintga APN.\""</string>
+ <!-- no translation found for permdesc_createNetworkSockets (5963922297444265950) -->
+ <skip />
+ <!-- no translation found for permlab_writeApnSettings (505660159675751896) -->
+ <skip />
+ <!-- no translation found for permdesc_writeApnSettings (5333798886412714193) -->
+ <skip />
<string name="permlab_changeNetworkState" msgid="958884291454327309">"modifitgar la connectivitad da la rait"</string>
- <!-- outdated translation 4199958910396387075 --> <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permetta ad ina applicaziun da modifitgar il status da connectivitad da la rait."</string>
- <!-- outdated translation 2702121155761140799 --> <string name="permlab_changeTetherState" msgid="5952584964373017960">"midar la connectivitad da tethering"</string>
- <!-- outdated translation 8905815579146349568 --> <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permetta ad ina applicaziun da modifitgar il status da connectivitad dal tethering."</string>
+ <!-- no translation found for permdesc_changeNetworkState (6789123912476416214) -->
+ <skip />
+ <!-- no translation found for permlab_changeTetherState (5952584964373017960) -->
+ <skip />
+ <!-- no translation found for permdesc_changeTetherState (1524441344412319780) -->
+ <skip />
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"modifitgar il parameter d\'utilisaziun da datas dal fund davos"</string>
- <!-- outdated translation 1001482853266638864 --> <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Permetta ad ina applicaziun da modifitgar il parameters d\'utilisaziun da las datas dal fund davos."</string>
+ <!-- no translation found for permdesc_changeBackgroundDataSetting (5347729578468744379) -->
+ <skip />
<string name="permlab_accessWifiState" msgid="8100926650211034400">"mussar il status WLAN"</string>
- <!-- outdated translation 485796529139236346 --> <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Permetta ad ina applicaziun da vesair las infurmaziuns concernent il status WLAN."</string>
+ <!-- no translation found for permdesc_accessWifiState (7770452658226256831) -->
+ <skip />
<string name="permlab_changeWifiState" msgid="7280632711057112137">"modifitgar il status WLAN"</string>
- <!-- outdated translation 2950383153656873267 --> <string name="permdesc_changeWifiState" msgid="7399961004537946240">"\"Permetta ad ina applicaziun da stabilir ina connexiun a puncts d\'access WLAN, da sa deconnectar da quels e da modifitgar ils parameters da raits WLAN configuradas.\""</string>
+ <!-- no translation found for permdesc_changeWifiState (7399961004537946240) -->
+ <skip />
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permetter la recepziun da multicast WLAN"</string>
- <!-- outdated translation 8199464507656067553 --> <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Permetta ad ina applicaziun da retschaiver pachets da datas che n\'èn betg adressads directamain a Voss apparat. Quai po esser nizzaivel per tschertgar servetschs che vegnan mess a disposiziun en il conturn. Consumescha dapli energia ch\'il modus betg-multicast."</string>
- <!-- outdated translation 1092209628459341292 --> <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"administraziun bluetooth"</string>
- <!-- outdated translation 7256289774667054555 --> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"\"Permetta ad ina applicaziun da configurar il telefon bluetooth local, dad identifitgar apparats periferics a distanza e d\'als associar cun il telefon.\""</string>
- <!-- outdated translation 7256289774667054555 --> <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"\"Permetta ad ina applicaziun da configurar il telefon bluetooth local, dad identifitgar apparats periferics a distanza e d\'als associar cun il telefon.\""</string>
+ <!-- no translation found for permdesc_changeWifiMulticastState (7633598524564320817) -->
+ <skip />
+ <!-- no translation found for permlab_bluetoothAdmin (3606576270792236062) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetoothAdmin (6921177471748882137) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetoothAdmin (8931682159331542137) -->
+ <skip />
+ <!-- no translation found for permlab_accessWimaxState (1232061307208861588) -->
+ <skip />
+ <!-- no translation found for permdesc_accessWimaxState (5914958077555177749) -->
+ <skip />
+ <!-- no translation found for permlab_changeWimaxState (2405042267131496579) -->
+ <skip />
+ <!-- no translation found for permdesc_changeWimaxState (3328853825006455912) -->
+ <skip />
<string name="permlab_bluetooth" msgid="8361038707857018732">"stabilir connexiuns bluetooth"</string>
- <!-- outdated translation 762515380679392945 --> <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permetta ad ina applicaziun dad obtegnair la configuraziun dal telefon bluetooth local e da crear ed acceptar connexiuns ad apparats associads."</string>
- <!-- outdated translation 762515380679392945 --> <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Permetta ad ina applicaziun dad obtegnair la configuraziun dal telefon bluetooth local e da crear ed acceptar connexiuns ad apparats associads."</string>
+ <!-- no translation found for permdesc_bluetooth (7007851048416363446) -->
+ <skip />
+ <!-- no translation found for permdesc_bluetooth (31846362767164948) -->
+ <skip />
<!-- no translation found for permlab_nfc (4423351274757876953) -->
<skip />
<!-- no translation found for permdesc_nfc (7120611819401789907) -->
<skip />
<string name="permlab_disableKeyguard" msgid="4977406164311535092">"deactivar la bloccaziun da la tastatura"</string>
- <!-- outdated translation 3189763479326302017 --> <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Permetta ad ina applicaziun da deactivar la bloccaziun da la tastatura e la protecziun cun il pled-clav associada. In exempel dad ina utilisaziun legitima: La bloccaziun da la tastatura vegn deactivada sche Vus retschavais in clom ed ella vegn reactivada sche Vus finis il telefon."</string>
+ <!-- no translation found for permdesc_disableKeyguard (6231611286892232626) -->
+ <skip />
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"leger ils parameters da sincronisaziun"</string>
- <!-- outdated translation 5315925706353341823 --> <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Permetta ad ina applicaziun da leger ils parameters da sincronisaziun (per exempel per savair sche la sincronisaziun da contacts è activà u betg)."</string>
+ <!-- no translation found for permdesc_readSyncSettings (5464056785274229278) -->
+ <skip />
<string name="permlab_writeSyncSettings" msgid="6297138566442486462">"scriver configuraziuns da sincronisaziun"</string>
- <!-- outdated translation 2498201614431360044 --> <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Permetta ad ina applicaziun da modifitgar ils parameters da sincronisaziun. Uschia po ella per exempel activar e deactivar la sincronisaziun da contacts."</string>
+ <!-- no translation found for permdesc_writeSyncSettings (1466056564502117130) -->
+ <skip />
<string name="permlab_readSyncStats" msgid="7396577451360202448">"leger las statisticas da sincronisaziun"</string>
- <!-- outdated translation 7511448343374465000 --> <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Permetta ad ina applicaziun da leger las statisticas da sincronisaziun (per exempel la cronologia da las sincronisaziuns exequidas)."</string>
+ <!-- no translation found for permdesc_readSyncStats (3801971839939951678) -->
+ <skip />
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"leger feeds abunads"</string>
- <!-- outdated translation 3622200625634207660 --> <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permetta ad ina applicaziun dad obtegnair infurmaziuns davart ils feeds actualisads dacurt."</string>
+ <!-- no translation found for permdesc_subscribedFeedsRead (5557058907906144505) -->
+ <skip />
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"scriver feeds abunads"</string>
- <!-- outdated translation 8121607099326533878 --> <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Permetta ad ina applicaziun da modifitgar Voss feeds sincronisads dacurt. Applicaziuns donnegiusas pudessan uschia modifitgar Voss feeds sincronisads."</string>
- <!-- outdated translation 432535716804748781 --> <string name="permlab_readDictionary" msgid="8410247960433376352">"leger il dicziunari definì da l\'utilisader"</string>
- <!-- outdated translation 1082972603576360690 --> <string name="permdesc_readDictionary" msgid="8977815988329283705">"Permetta ad ina applicaziun da leger tut ils pleds e nums privats e las expressiuns privatas che in utilisader ha memorisà en ses dicziunari."</string>
- <!-- outdated translation 6703109511836343341 --> <string name="permlab_writeDictionary" msgid="2296383164914812772">"scriver en il dicziunari definì da l\'utilisader"</string>
- <!-- outdated translation 2241256206524082880 --> <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Permetta ad ina applicaziun da scriver novs pleds en il dicziunari dal utilisader."</string>
- <!-- outdated translation 8079403759001777291 --> <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"modifitgar/stizzar cuntegns da la carta SD"</string>
+ <!-- no translation found for permdesc_subscribedFeedsWrite (6928930188826089413) -->
+ <skip />
+ <!-- no translation found for permlab_readDictionary (8410247960433376352) -->
+ <skip />
+ <!-- no translation found for permdesc_readDictionary (8977815988329283705) -->
+ <skip />
+ <!-- no translation found for permlab_writeDictionary (2296383164914812772) -->
+ <skip />
+ <!-- no translation found for permdesc_writeDictionary (8185385716255065291) -->
+ <skip />
+ <!-- no translation found for permlab_sdcardWrite (85430876310764752) -->
+ <skip />
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"modifitgar/stizzar cuntegns da la carta SD"</string>
- <!-- outdated translation 6643963204976471878 --> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Permetta ad ina applicaziun da scriver sin la carta SD."</string>
- <!-- outdated translation 6643963204976471878 --> <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Permetta ad ina applicaziun da scriver sin la carta SD."</string>
+ <!-- no translation found for permdesc_sdcardWrite (6175406299445710888) -->
+ <skip />
+ <!-- no translation found for permdesc_sdcardWrite (4337417790936632090) -->
+ <skip />
<!-- no translation found for permlab_mediaStorageWrite (6859839199706879015) -->
<skip />
<!-- no translation found for permdesc_mediaStorageWrite (8189160597698529185) -->
<skip />
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"access al sistem da datotecas da cache"</string>
- <!-- outdated translation 1624734528435659906 --> <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Permetta ad ina applicaziun da leger e da scriver en il sistem da datotecas dal cache."</string>
+ <!-- no translation found for permdesc_cache_filesystem (5578967642265550955) -->
+ <skip />
<!-- no translation found for permlab_use_sip (5986952362795870502) -->
<skip />
<!-- no translation found for permdesc_use_sip (4717632000062674294) -->
@@ -548,33 +783,44 @@
<skip />
<!-- no translation found for permlab_modifyNetworkAccounting (5088217309088729650) -->
<skip />
- <!-- no translation found for permdesc_modifyNetworkAccounting (8553240749784321765) -->
- <skip />
- <!-- outdated translation 4307861496302850201 --> <string name="policylab_limitPassword" msgid="4497420728857585791">"Limitar il pled-clav"</string>
- <!-- outdated translation 1719877245692318299 --> <string name="policydesc_limitPassword" msgid="9083400080861728056">"Restrenscher ils tips da pleds-clav che Vus pudais utilisar."</string>
- <!-- outdated translation 7374780712664285321 --> <string name="policylab_watchLogin" msgid="914130646942199503">"Survegliar las emprovas da s\'annunziar"</string>
- <!-- outdated translation 1961251179624843483 --> <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Survegliar las emprovas betg reussidas da s\'annunziar ad in apparat periferic / dad exequir ina acziun."</string>
- <!-- outdated translation 1961251179624843483 --> <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Survegliar las emprovas betg reussidas da s\'annunziar ad in apparat periferic / dad exequir ina acziun."</string>
- <!-- outdated translation 9084772090797485420 --> <string name="policylab_resetPassword" msgid="2620077191242688955">"Reinizialisar il pled-clav"</string>
- <!-- outdated translation 3332167600331799991 --> <string name="policydesc_resetPassword" msgid="5391240616981297361">"\"Definir ina nova valur per Voss pled-clav, uschia che l\'administratur As sto dar il pled-clav avant che Vus pudais s\'annunziar.\""</string>
- <!-- outdated translation 5760466025247634488 --> <string name="policylab_forceLock" msgid="2274085384704248431">"Sfurzar da bloccar"</string>
- <!-- outdated translation 2819868664946089740 --> <string name="policydesc_forceLock" msgid="5696964126226028442">"Controlla da la bloccaziun dad apparats periferics cun l\'obligaziun dad endatar danovamain il pled-clav."</string>
+ <!-- no translation found for permdesc_modifyNetworkAccounting (5443412866746198123) -->
+ <skip />
+ <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
+ <skip />
+ <!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
+ <skip />
+ <!-- no translation found for policylab_watchLogin (914130646942199503) -->
+ <skip />
+ <!-- no translation found for policydesc_watchLogin (3215729294215070072) -->
+ <skip />
+ <!-- no translation found for policydesc_watchLogin (5712323091846761073) -->
+ <skip />
+ <!-- no translation found for policylab_resetPassword (2620077191242688955) -->
+ <skip />
+ <!-- no translation found for policydesc_resetPassword (605963962301904458) -->
+ <skip />
+ <!-- no translation found for policylab_forceLock (2274085384704248431) -->
+ <skip />
+ <!-- no translation found for policydesc_forceLock (1141797588403827138) -->
+ <skip />
<string name="policylab_wipeData" msgid="3910545446758639713">"Stizzar tut las datas"</string>
- <!-- outdated translation 2314060933796396205 --> <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Restaurar ils parameters originals dal telefonin. Qua tras vegnan tut Vossas datas stizzadas senza dumonda da conferma."</string>
- <!-- outdated translation 2314060933796396205 --> <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Restaurar ils parameters originals dal telefonin. Qua tras vegnan tut Vossas datas stizzadas senza dumonda da conferma."</string>
+ <!-- no translation found for policydesc_wipeData (4306184096067756876) -->
+ <skip />
+ <!-- no translation found for policydesc_wipeData (5096895604574188391) -->
+ <skip />
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Definir il proxy global da l\'apparat"</string>
<string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir il proxy global da l\'apparat che duai vegnir utilisà sche la directiva è activada. Mo l\'emprim administratur dad apparats definescha il vair proxy global."</string>
<!-- no translation found for policylab_expirePassword (885279151847254056) -->
<skip />
- <!-- no translation found for policydesc_expirePassword (4844430354224822074) -->
+ <!-- no translation found for policydesc_expirePassword (1729725226314691591) -->
<skip />
<!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
<skip />
- <!-- no translation found for policydesc_encryptedStorage (8877192718681120469) -->
+ <!-- no translation found for policydesc_encryptedStorage (2637732115325316992) -->
<skip />
<!-- no translation found for policylab_disableCamera (6395301023152297826) -->
<skip />
- <!-- no translation found for policydesc_disableCamera (5680054212889413366) -->
+ <!-- no translation found for policydesc_disableCamera (2306349042834754597) -->
<skip />
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Privat"</item>
@@ -644,7 +890,8 @@
<skip />
<string name="eventTypeBirthday" msgid="2813379844211390740">"Anniversari"</string>
<string name="eventTypeAnniversary" msgid="3876779744518284000">"Anniversari"</string>
- <!-- outdated translation 5834288791948564594 --> <string name="eventTypeOther" msgid="7388178939010143077">"Termin"</string>
+ <!-- no translation found for eventTypeOther (7388178939010143077) -->
+ <skip />
<string name="emailTypeCustom" msgid="8525960257804213846">"Persunalisà"</string>
<string name="emailTypeHome" msgid="449227236140433919">"Privat"</string>
<string name="emailTypeWork" msgid="3548058059601149973">"Lavur"</string>
@@ -709,7 +956,8 @@
<skip />
<!-- no translation found for sipAddressTypeOther (4408436162950119849) -->
<skip />
- <!-- outdated translation 3731488827218876115 --> <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Endatar il code PIN"</string>
+ <!-- no translation found for keyguard_password_enter_pin_code (3037685796058495017) -->
+ <skip />
<!-- no translation found for keyguard_password_enter_puk_code (4800725266925845333) -->
<skip />
<!-- no translation found for keyguard_password_enter_puk_prompt (1341112146710087048) -->
@@ -718,12 +966,16 @@
<skip />
<!-- no translation found for keyguard_password_entry_touch_hint (7858547464982981384) -->
<skip />
- <!-- outdated translation 9138158344813213754 --> <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Endatai il pled-clav per debloccar."</string>
- <!-- outdated translation 638347075625491514 --> <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Endatar il PIN per debloccar"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Code PIN nuncorrect!"</string>
+ <!-- no translation found for keyguard_password_enter_password_code (1054721668279049780) -->
+ <skip />
+ <!-- no translation found for keyguard_password_enter_pin_password_code (6391755146112503443) -->
+ <skip />
+ <!-- no translation found for keyguard_password_wrong_pin_code (2422225591006134936) -->
+ <skip />
<string name="keyguard_label_text" msgid="861796461028298424">"Smatgai per debloccar sin la tasta Menu e lura sin 0."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Numer d\'urgenza"</string>
- <!-- outdated translation 8812714795156374435 --> <string name="lockscreen_carrier_default" msgid="8963839242565653192">"(nagin servetsch)"</string>
+ <!-- no translation found for lockscreen_carrier_default (8963839242565653192) -->
+ <skip />
<string name="lockscreen_screen_locked" msgid="7288443074806832904">"Visur bloccà."</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Smatgai la tasta Menu per debloccar il telefonin u telefonar sin in numer d\'urgenza."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Smatgar la tasta da menu per debloccar."</string>
@@ -731,17 +983,23 @@
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"Numer d\'urgenza"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Enavos al clom"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correct!"</string>
- <!-- outdated translation 4817583279053112312 --> <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Quai ans displascha. Empruvai anc ina giada."</string>
- <!-- outdated translation 6237443657358168819 --> <string name="lockscreen_password_wrong" msgid="5737815393253165301">"\"Perstgisai, empruvai anc ina giada.\""</string>
+ <!-- no translation found for lockscreen_pattern_wrong (4317955014948108794) -->
+ <skip />
+ <!-- no translation found for lockscreen_password_wrong (5737815393253165301) -->
+ <skip />
+ <!-- no translation found for faceunlock_multiple_failures (754137583022792429) -->
+ <skip />
<!-- no translation found for lockscreen_plugged_in (8057762828355572315) -->
<skip />
<string name="lockscreen_charged" msgid="4938930459620989972">"Chargià"</string>
<string name="lockscreen_battery_short" msgid="3617549178603354656">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Connectai Voss chargiader."</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Nagina carta SIM."</string>
- <!-- outdated translation 2186920585695169078 --> <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"En il telefon na sa chatta nagina carta SIM."</string>
+ <!-- no translation found for lockscreen_missing_sim_message (151659196095791474) -->
+ <skip />
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"En il telefon na sa chatta nagina carta SIM."</string>
- <!-- outdated translation 8874620818937719067 --> <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Inseri per plaschair ina carta SIM."</string>
+ <!-- no translation found for lockscreen_missing_sim_instructions (5372787138023272615) -->
+ <skip />
<!-- no translation found for lockscreen_missing_sim_instructions_long (3526573099019319472) -->
<skip />
<!-- no translation found for lockscreen_permanent_disabled_sim_instructions (910904643433151371) -->
@@ -760,7 +1018,8 @@
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rait bloccada"</string>
<!-- no translation found for lockscreen_sim_puk_locked_message (7441797339976230) -->
<skip />
- <!-- outdated translation 635967534992394321 --> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Ulteriuras infurmaziuns chattais Vus en il manual u che Vus pudais contactar il servetsch da clientella."</string>
+ <!-- no translation found for lockscreen_sim_puk_locked_instructions (8127916255245181063) -->
+ <skip />
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"La carta SIM è bloccada."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Debloccar la carta SIM..."</string>
<!-- no translation found for lockscreen_too_many_failed_attempts_dialog_message (6481623830344107222) -->
@@ -784,15 +1043,18 @@
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Empruvar anc ina giada en <xliff:g id="NUMBER">%d</xliff:g> secundas."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Emblidà il schema?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Debloccaziun dal conto"</string>
- <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Memia bleras tentativas!"</string>
- <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"S\'annunziai cun Voss conto Google per debloccar il telefonin."</string>
+ <!-- no translation found for lockscreen_glogin_too_many_attempts (2751368605287288808) -->
+ <skip />
+ <!-- no translation found for lockscreen_glogin_instructions (3931816256100707784) -->
+ <skip />
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Num d\'utilisader (e-mail)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Pled-clav"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"S\'annunziar"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Num d\'utilisader u pled-clav nunvalid."</string>
- <!-- no translation found for lockscreen_glogin_account_recovery_hint (8253152905532900548) -->
+ <!-- no translation found for lockscreen_glogin_account_recovery_hint (1696924763690379073) -->
+ <skip />
+ <!-- no translation found for lockscreen_glogin_checking_password (7114627351286933867) -->
<skip />
- <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Verifitgar..."</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"Debloccar"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Tun activà"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"Tun deactivà"</string>
@@ -813,15 +1075,17 @@
<string name="factorytest_not_system" msgid="4435201656767276723">"L\'acziun FACTORY_TEST vegn mo sustegnida per pachets installads en /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"Betg chattà in pachet che porscha l\'acziun FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="6320168203050791643">"Reaviar il sistem"</string>
- <string name="js_dialog_title" msgid="8143918455087008109">"La pagina \'<xliff:g id="TITLE">%s</xliff:g>\' annunzia:"</string>
+ <!-- no translation found for js_dialog_title (1987483977834603872) -->
+ <skip />
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<!-- no translation found for js_dialog_before_unload (730366588032430474) -->
<skip />
<string name="save_password_label" msgid="6860261758665825069">"Confermar"</string>
- <!-- outdated translation 1068216937244567247 --> <string name="double_tap_toast" msgid="2729045387923870404">"Tip: Smatgar duas giadas per zoomar pli datiers u zoomar pli lontan."</string>
- <!-- no translation found for autofill_this_form (1272247532604569872) -->
+ <!-- no translation found for double_tap_toast (4595046515400268881) -->
+ <skip />
+ <!-- no translation found for autofill_this_form (4616758841157816676) -->
<skip />
- <!-- no translation found for setup_autofill (8154593408885654044) -->
+ <!-- no translation found for setup_autofill (7103495070180590814) -->
<skip />
<!-- no translation found for autofill_address_name_separator (2504700673286691795) -->
<skip />
@@ -856,10 +1120,13 @@
<!-- no translation found for autofill_emirate (2893880978835698818) -->
<skip />
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"leger la cronologia ed ils segnapaginas dal navigatur"</string>
- <!-- outdated translation 4981489815467617191 --> <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"\"Permetta a l\'applicaziun da leger tut las URLs visitadas, sco era ils segnapaginas dal navigatur.\""</string>
+ <!-- no translation found for permdesc_readHistoryBookmarks (4577476392604595921) -->
+ <skip />
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"scriver en la cronologia ed en ils segnapaginas dal navigatur"</string>
- <!-- outdated translation 945571990357114950 --> <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"\"Permetta ad ina applicaziun da modifitgar la cronologia u ils segnapaginas dal navigatur, memorisads sin Voss telefonin. Applicaziuns donnegiusas pon uschia stizzar u modifitgar las datas da Voss navigatur.\""</string>
- <!-- outdated translation 945571990357114950 --> <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"\"Permetta ad ina applicaziun da modifitgar la cronologia u ils segnapaginas dal navigatur, memorisads sin Voss telefonin. Applicaziuns donnegiusas pon uschia stizzar u modifitgar las datas da Voss navigatur.\""</string>
+ <!-- no translation found for permdesc_writeHistoryBookmarks (1757103804824209530) -->
+ <skip />
+ <!-- no translation found for permdesc_writeHistoryBookmarks (6693764355720719197) -->
+ <skip />
<!-- no translation found for permlab_setAlarm (5924401328803615165) -->
<skip />
<!-- no translation found for permdesc_setAlarm (316392039157473848) -->
@@ -868,8 +1135,10 @@
<skip />
<!-- no translation found for permdesc_addVoicemail (6604508651428252437) -->
<skip />
- <!-- outdated translation 4715212655598275532 --> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modifitgar las autorisaziuns da geolocalisaziun dal navigatur"</string>
- <!-- outdated translation 4011908282980861679 --> <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permetta ad ina applicaziun da modifitgar las permissiuns da geolocalisaziun dal navigatur. Applicaziuns donnegiusas pon utilisar questa funcziun per trametter datas da posiziun a websites arbitraras."</string>
+ <!-- no translation found for permlab_writeGeolocationPermissions (5962224158955273932) -->
+ <skip />
+ <!-- no translation found for permdesc_writeGeolocationPermissions (1083743234522638747) -->
+ <skip />
<!-- no translation found for permlab_packageVerificationAgent (5568139100645829117) -->
<skip />
<!-- no translation found for permdesc_packageVerificationAgent (8437590190990843381) -->
@@ -882,7 +1151,8 @@
<string name="save_password_notnow" msgid="6389675316706699758">"Betg ussa"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Memorisar"</string>
<string name="save_password_never" msgid="8274330296785855105">"Mai"</string>
- <!-- outdated translation 5661861460947222274 --> <string name="open_permission_deny" msgid="7374036708316629800">"Vus n\'avais betg las permissiuns necessarias per avrir questa pagina."</string>
+ <!-- no translation found for open_permission_deny (7374036708316629800) -->
+ <skip />
<string name="text_copied" msgid="4985729524670131385">"Il text è vegnì copià en l\'archiv provisoric."</string>
<string name="more_item_label" msgid="4650918923083320495">"Dapli"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Menu+"</string>
@@ -986,9 +1256,12 @@
<string name="weeks" msgid="6509623834583944518">"emnas"</string>
<string name="year" msgid="4001118221013892076">"onn"</string>
<string name="years" msgid="6881577717993213522">"onns"</string>
- <!-- outdated translation 3359437293118172396 --> <string name="VideoView_error_title" msgid="5927895235831021723">"Betg reussì da reproducir il video."</string>
- <!-- outdated translation 897920883624437033 --> <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"\"Perstgisai, deplorablamain n\'è quest video betg valid per il streaming sin quest apparat.\""</string>
- <!-- outdated translation 710301040038083944 --> <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"\"Perstgisai, impussibel da leger quest video.\""</string>
+ <!-- no translation found for VideoView_error_title (3534509135438353077) -->
+ <skip />
+ <!-- no translation found for VideoView_error_text_invalid_progressive_playback (3186670335938670444) -->
+ <skip />
+ <!-- no translation found for VideoView_error_text_unknown (3450439155187810085) -->
+ <skip />
<string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
<string name="relative_time" msgid="1818557177829411417">"\"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>\""</string>
<string name="noon" msgid="7245353528818587908">"mezdi"</string>
@@ -1006,10 +1279,9 @@
<!-- no translation found for delete (6098684844021697789) -->
<skip />
<string name="copyUrl" msgid="2538211579596067402">"Copiar l\'URL"</string>
- <!-- outdated translation 6738556348861347240 --> <string name="selectTextMode" msgid="1018691815143165326">"Selecziunar text…"</string>
- <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selecziun da text"</string>
- <!-- unknown placeholder WORD in addToDictionary -->
+ <!-- no translation found for selectTextMode (1018691815143165326) -->
<skip />
+ <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selecziun da text"</string>
<!-- no translation found for addToDictionary (9090375111134433012) -->
<skip />
<!-- no translation found for deleteText (7070985395199629156) -->
@@ -1017,23 +1289,28 @@
<string name="inputMethod" msgid="1653630062304567879">"Metoda d\'endataziun"</string>
<string name="editTextMenuTitle" msgid="4909135564941815494">"Acziuns da text"</string>
<string name="low_internal_storage_view_title" msgid="1399732408701697546">"Pauca capacitad da memorisar"</string>
- <!-- outdated translation 635106544616378836 --> <string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"Mo pli pauca capacitad da memorisar."</string>
+ <!-- no translation found for low_internal_storage_view_text (4231085657068852042) -->
+ <skip />
<string name="low_internal_storage_view_text" product="default" msgid="635106544616378836">"Mo pli pauca capacitad da memorisar."</string>
<string name="ok" msgid="5970060430562524910">"OK"</string>
<string name="cancel" msgid="6442560571259935130">"Interrumper"</string>
<string name="yes" msgid="5362982303337969312">"OK"</string>
<string name="no" msgid="5141531044935541497">"Interrumper"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Attenziun"</string>
- <!-- outdated translation 1760724998928255250 --> <string name="loading" msgid="7933681260296021180">"Chargiar…"</string>
+ <!-- no translation found for loading (7933681260296021180) -->
+ <skip />
<string name="capital_on" msgid="1544682755514494298">"ACTIVÀ"</string>
<string name="capital_off" msgid="6815870386972805832">"DEACTIVÀ"</string>
<string name="whichApplication" msgid="4533185947064773386">"Cumplettar l\'acziun cun"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilisar questa applicaziun sco standard per questa acziun."</string>
- <!-- outdated translation 4815455344600932173 --> <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Stizzar ils parameters da standard en Parameters da la pagina da partenza &gt; Applicaziuns &gt; Administrar las applicaziuns."</string>
- <string name="chooseActivity" msgid="1009246475582238425">"Tscherner ina acziun"</string>
+ <!-- no translation found for clearDefaultHintMsg (3252584689512077257) -->
+ <skip />
+ <!-- no translation found for chooseActivity (7486876147751803333) -->
+ <skip />
<!-- no translation found for chooseUsbActivity (6894748416073583509) -->
<skip />
- <!-- outdated translation 1691104391758345586 --> <string name="noApplications" msgid="2991814273936504689">"Nagina applicaziun po exequir questa acziun."</string>
+ <!-- no translation found for noApplications (2991814273936504689) -->
+ <skip />
<string name="aerr_title" msgid="1905800560317137752"></string>
<!-- no translation found for aerr_application (932628488013092776) -->
<skip />
@@ -1048,9 +1325,12 @@
<skip />
<!-- no translation found for anr_process (6513209874880517125) -->
<skip />
- <!-- outdated translation 3653416315450806396 --> <string name="force_close" msgid="8346072094521265605">"Sfurzar da serrar"</string>
+ <!-- no translation found for force_close (8346072094521265605) -->
+ <skip />
<string name="report" msgid="4060218260984795706">"Rapport"</string>
<string name="wait" msgid="7147118217226317732">"Spetgar"</string>
+ <!-- no translation found for webpage_unresponsive (3272758351138122503) -->
+ <skip />
<!-- no translation found for launch_warning_title (1547997780506713581) -->
<skip />
<!-- no translation found for launch_warning_replace (6202498949970281412) -->
@@ -1075,18 +1355,25 @@
<!-- no translation found for android_upgrading_complete (1405954754112999229) -->
<skip />
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> vegn exequida"</string>
- <!-- outdated translation 2423977499339403402 --> <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Tscherner per midar a l\'applicaziun"</string>
- <!-- outdated translation 1135403633766694316 --> <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Midar dad ina applicaziun a l\'autra?"</string>
- <!-- outdated translation 4592075610079319667 --> <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Ina autra applicaziun vegn gia exequida e sto vegnir serrada avant ch\'ina nova po vegnir aviada."</string>
+ <!-- no translation found for heavy_weight_notification_detail (1721681741617898865) -->
+ <skip />
+ <!-- no translation found for heavy_weight_switcher_title (7153167085403298169) -->
+ <skip />
+ <!-- no translation found for heavy_weight_switcher_text (7022631924534406403) -->
+ <skip />
<string name="old_app_action" msgid="493129172238566282">"Turnar a <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <!-- outdated translation 942967900237208466 --> <string name="old_app_description" msgid="2082094275580358049">"Betg aviai la nova applicaziun."</string>
+ <!-- no translation found for old_app_description (2082094275580358049) -->
+ <skip />
<string name="new_app_action" msgid="5472756926945440706">"Aviar <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <!-- outdated translation 6830398339826789493 --> <string name="new_app_description" msgid="1932143598371537340">"Fermai l\'applicaziun veglia senza memorisar."</string>
- <string name="sendText" msgid="5132506121645618310">"Tscherner ina acziun per il text"</string>
+ <!-- no translation found for new_app_description (1932143598371537340) -->
+ <skip />
+ <!-- no translation found for sendText (5209874571959469142) -->
+ <skip />
<string name="volume_ringtone" msgid="6885421406845734650">"Volumen dal tun da scalin"</string>
<string name="volume_music" msgid="5421651157138628171">"Volumen da medias"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Reproducir tras bluetooth"</string>
- <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"Tschernì il modus silenzius per il tun da scalin"</string>
+ <!-- no translation found for volume_music_hint_silent_ringtone_selected (8310739960973156272) -->
+ <skip />
<string name="volume_call" msgid="3941680041282788711">"Volumen dals cloms entrants"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"Volumen da cloms entrants da bluetooth"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Volumen dal svegliarin"</string>
@@ -1115,34 +1402,46 @@
<item quantity="one" msgid="1634101450343277345">"Rait WLAN averta disponibla"</item>
<item quantity="other" msgid="7915895323644292768">"Raits WLAN avertas disponiblas"</item>
</plurals>
- <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
+ <!-- no translation found for wifi_available_sign_in (4029489716605255386) -->
<skip />
<!-- no translation found for wifi_available_sign_in_detailed (6797764740339907572) -->
<skip />
<!-- no translation found for wifi_watchdog_network_disabled (7904214231651546347) -->
<skip />
- <!-- no translation found for wifi_watchdog_network_disabled_detailed (4917472096696322767) -->
+ <!-- no translation found for wifi_watchdog_network_disabled_detailed (5548780776418332675) -->
<skip />
<!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
<skip />
- <!-- no translation found for wifi_p2p_turnon_message (2804722042556269129) -->
+ <!-- no translation found for wifi_p2p_turnon_message (2909250942299627244) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_failed_message (3763669677935623084) -->
+ <skip />
+ <!-- no translation found for accept (1645267259272829559) -->
+ <skip />
+ <!-- no translation found for decline (2112225451706137894) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_invitation_sent_title (1318975185112070734) -->
<skip />
- <!-- no translation found for wifi_p2p_failed_message (1820097493844848281) -->
+ <!-- no translation found for wifi_p2p_invitation_to_connect_title (4958803948658533637) -->
<skip />
- <!-- no translation found for wifi_p2p_pbc_go_negotiation_request_message (3170321684621420428) -->
+ <!-- no translation found for wifi_p2p_from_message (570389174731951769) -->
<skip />
- <!-- no translation found for wifi_p2p_pin_go_negotiation_request_message (5177412094633377308) -->
+ <!-- no translation found for wifi_p2p_to_message (248968974522044099) -->
<skip />
- <!-- no translation found for wifi_p2p_pin_display_message (2834049169114922902) -->
+ <!-- no translation found for wifi_p2p_enter_pin_message (5920929550367828970) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_show_pin_message (8530563323880921094) -->
<skip />
<!-- no translation found for wifi_p2p_enabled_notification_title (2068321881673734886) -->
<skip />
<!-- no translation found for wifi_p2p_enabled_notification_message (1638949953993894335) -->
<skip />
<string name="select_character" msgid="3365550120617701745">"Inserir in caracter"</string>
- <!-- outdated translation 7630529934366549163 --> <string name="sms_control_default_app_name" msgid="3058577482636640465">"Applicaziun nunenconuschenta"</string>
+ <!-- no translation found for sms_control_default_app_name (3058577482636640465) -->
+ <skip />
<string name="sms_control_title" msgid="7296612781128917719">"Trametter messadis SMS"</string>
- <!-- outdated translation 1289331457999236205 --> <string name="sms_control_message" msgid="4073755190243093924">"Vulais Vus trametter in grond dumber da messadis SMS? Tschernì OK per cuntinuar u Interrumper per annullar la spediziun."</string>
+ <!-- no translation found for sms_control_message (4073755190243093924) -->
+ <skip />
<string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
<string name="sms_control_no" msgid="1715320703137199869">"Interrumper"</string>
<!-- no translation found for sim_removed_title (6227712319223226185) -->
@@ -1153,7 +1452,7 @@
<skip />
<!-- no translation found for sim_added_title (3719670512889674693) -->
<skip />
- <!-- no translation found for sim_added_message (1209265974048554242) -->
+ <!-- no translation found for sim_added_message (6599945301141050216) -->
<skip />
<!-- no translation found for sim_restart_button (4722407842815232347) -->
<skip />
@@ -1166,25 +1465,37 @@
<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>
- <string name="usb_storage_activity_title" msgid="2399289999608900443">"Memoria da massa USB"</string>
+ <!-- no translation found for usb_storage_activity_title (4465055157209648641) -->
+ <skip />
<string name="usb_storage_title" msgid="5901459041398751495">"Connectà cun agid d\'in cabel USB"</string>
- <!-- outdated translation 4796759646167247178 --> <string name="usb_storage_message" product="nosdcard" msgid="6631094834151575841">"\"Vus avais connectà Voss telefonin cun Voss computer cun agid dad in cabel USB. Tscherni il buttun sutvart per copiar datotecas da Voss computer sin la carta SD da Voss Android, u viceversa.\""</string>
- <!-- outdated translation 4796759646167247178 --> <string name="usb_storage_message" product="default" msgid="4510858346516069238">"\"Vus avais connectà Voss telefonin cun Voss computer cun agid dad in cabel USB. Tscherni il buttun sutvart per copiar datotecas da Voss computer sin la carta SD da Voss Android, u viceversa.\""</string>
+ <!-- no translation found for usb_storage_message (3308538094316477839) -->
+ <skip />
+ <!-- no translation found for usb_storage_message (805351000446037811) -->
+ <skip />
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activar la memoria USB"</string>
- <!-- outdated translation 2534784751603345363 --> <string name="usb_storage_error_message" product="nosdcard" msgid="3276413764430468454">"Cun l\'utilisaziun da Vossa carta SD sco memoria USB è cumparì in problem."</string>
- <!-- outdated translation 2534784751603345363 --> <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Cun l\'utilisaziun da Vossa carta SD sco memoria USB è cumparì in problem."</string>
+ <!-- no translation found for usb_storage_error_message (3017045217365540658) -->
+ <skip />
+ <!-- no translation found for usb_storage_error_message (2876018512716970313) -->
+ <skip />
<string name="usb_storage_notification_title" msgid="8175892554757216525">"Connectà cun in cabel USB"</string>
- <string name="usb_storage_notification_message" msgid="7380082404288219341">"Tscherni las datotecas che duain vegnir copiadas da/sin Voss computer."</string>
+ <!-- no translation found for usb_storage_notification_message (939822783828183763) -->
+ <skip />
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Deactivar la memoria USB"</string>
- <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Tscherner per deactivar la memoria USB."</string>
+ <!-- no translation found for usb_storage_stop_notification_message (1656852098555623822) -->
+ <skip />
<string name="usb_storage_stop_title" msgid="660129851708775853">"La memoria USB vegn gest utilisada"</string>
- <!-- outdated translation 3613713396426604104 --> <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"Verifitgai avant che deactivar la memoria USB che Vus avais demontà la carta SD Android da Voss computer."</string>
- <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"Verifitgai avant che deactivar la memoria USB che Vus avais demontà la carta SD Android da Voss computer."</string>
+ <!-- no translation found for usb_storage_stop_message (4264025280777219521) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_message (8043969782460613114) -->
+ <skip />
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Deactivar l\'apparat periferic da memoria USB"</string>
- <string name="usb_storage_stop_error_message" msgid="143881914840412108">"Cun deactivar la memoria USB è in problem cumparì. Verifitgai che Vus avais demontà il host USB ed empruvai anc ina giada."</string>
+ <!-- no translation found for usb_storage_stop_error_message (1970374898263063836) -->
+ <skip />
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Activar la memoria USB"</string>
- <!-- outdated translation 3202838234780505886 --> <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"Sche Vus activais l\'apparat periferic da memoria USB sa ferman tschertas applicaziuns che Vus utilisais. Ellas n\'èn probablamain betg disponiblas enfin che l\'apparat periferic vegn puspè deactivà."</string>
- <!-- outdated translation 8048999973837339174 --> <string name="dlg_error_title" msgid="7323658469626514207">"Operaziun USB betg reussida"</string>
+ <!-- no translation found for dlg_confirm_kill_storage_users_text (5100428757107469454) -->
+ <skip />
+ <!-- no translation found for dlg_error_title (7323658469626514207) -->
+ <skip />
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
<!-- no translation found for usb_mtp_notification_title (3699913097391550394) -->
<skip />
@@ -1194,51 +1505,76 @@
<skip />
<!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
<skip />
- <!-- no translation found for usb_notification_message (4447869605109736382) -->
+ <!-- no translation found for usb_notification_message (2290859399983720271) -->
+ <skip />
+ <!-- no translation found for extmedia_format_title (9020092196061007262) -->
+ <skip />
+ <!-- no translation found for extmedia_format_title (3648415921526526069) -->
+ <skip />
+ <!-- no translation found for extmedia_format_message (3934016853425761078) -->
+ <skip />
+ <!-- no translation found for extmedia_format_message (14131895027543830) -->
<skip />
- <!-- outdated translation 8663247929551095854 --> <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatar la carta SD"</string>
- <!-- outdated translation 8663247929551095854 --> <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formatar la carta SD"</string>
- <!-- outdated translation 3621369962433523619 --> <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Vulais Vus propi formatar la carta SD? En quest cas van tut las datas sin Vossa carta a perder."</string>
- <!-- outdated translation 3621369962433523619 --> <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Vulais Vus propi formatar la carta SD? En quest cas van tut las datas sin Vossa carta a perder."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB connectà"</string>
- <!-- outdated translation 8470296818270110396 --> <string name="adb_active_notification_message" msgid="1016654627626476142">"Tscherner per deactivar il debugging USB."</string>
- <!-- outdated translation 6865512749462072765 --> <string name="select_input_method" msgid="4653387336791222978">"Tscherner ina metoda d\'endataziun"</string>
+ <!-- no translation found for adb_active_notification_message (1016654627626476142) -->
+ <skip />
+ <!-- no translation found for select_input_method (4653387336791222978) -->
+ <skip />
<!-- no translation found for configure_input_methods (9091652157722495116) -->
<skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
- <!-- outdated translation 5457603418970994050 --> <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"Preparaziun da la carta SD"</string>
+ <!-- no translation found for ext_media_checking_notification_title (3449816005351468560) -->
+ <skip />
<string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"Preparaziun da la carta SD"</string>
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Tschertgar errurs"</string>
- <!-- outdated translation 780477838241212997 --> <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Carta SD vida"</string>
+ <!-- no translation found for ext_media_nofs_notification_title (7788040745686229307) -->
+ <skip />
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Carta SD vida"</string>
- <!-- outdated translation 1312266820092958014 --> <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"La carta SD è vida u ch\'ella utilisescha in sistem da datotecas che na vegn betg sustegnì."</string>
- <string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"La carta SD è vida ubain che ses sistem da datotecas na vegn betg sustegnì."</string>
- <!-- outdated translation 6410723906019100189 --> <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Carta SD donnegiada"</string>
+ <!-- no translation found for ext_media_nofs_notification_message (7840121067427269500) -->
+ <skip />
+ <!-- no translation found for ext_media_nofs_notification_message (8641065641786923604) -->
+ <skip />
+ <!-- no translation found for ext_media_unmountable_notification_title (2090046769532713563) -->
+ <skip />
<string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Carta SD donnegiada"</string>
- <!-- outdated translation 2679412884290061775 --> <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="529021299294450667">"La carta SD è donnegiada. Vus stuais eventualmain reformatar Vossa carta."</string>
- <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"La carta SD è donnegiada. Vus stuais eventualmain reformatar la carta."</string>
- <!-- outdated translation 6872152882604407837 --> <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Allontanà la carta SD nunspetgadamain"</string>
+ <!-- no translation found for ext_media_unmountable_notification_message (1795917578395333280) -->
+ <skip />
+ <!-- no translation found for ext_media_unmountable_notification_message (1753898567525568253) -->
+ <skip />
+ <!-- no translation found for ext_media_badremoval_notification_title (1661683031330951073) -->
+ <skip />
<string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Allontanà la carta SD nunspetgadamain"</string>
- <!-- outdated translation 7260183293747448241 --> <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Demontar la carta SD avant che retrair ella per evitar ina sperdita da datas."</string>
+ <!-- no translation found for ext_media_badremoval_notification_message (4329848819865594241) -->
+ <skip />
<string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Demontar la carta SD avant che retrair ella per evitar ina sperdita da datas."</string>
- <!-- outdated translation 6729801130790616200 --> <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"La carta SD po vegnir allontanada a moda segira"</string>
+ <!-- no translation found for ext_media_safe_unmount_notification_title (3967973893270360230) -->
+ <skip />
<string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"La carta SD po vegnir allontanada a moda segira"</string>
- <!-- outdated translation 7613960686747592770 --> <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"La carta SD po ussa vegnir allontanada."</string>
+ <!-- no translation found for ext_media_safe_unmount_notification_message (6142195361606493530) -->
+ <skip />
<string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"La carta SD po vegnir retratga a moda segira."</string>
- <!-- outdated translation 8902518030404381318 --> <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"Allontanà la carta SD"</string>
+ <!-- no translation found for ext_media_nomedia_notification_title (4486377230140227651) -->
+ <skip />
<string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"Allontanà la carta SD"</string>
- <!-- outdated translation 4205117227342822275 --> <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"La carta SD è vegnida allontanada. Inseri ina carta SD nova per engrondir la capacitad da memorisar da Voss apparat."</string>
+ <!-- no translation found for ext_media_nomedia_notification_message (6921126162580574143) -->
+ <skip />
<string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Allontanà la carta SD. Inseri ina nova."</string>
- <string name="activity_list_empty" msgid="4168820609403385789">"Betg chattà activitads correspundentas"</string>
+ <!-- no translation found for activity_list_empty (1675388330786841066) -->
+ <skip />
<string name="permlab_pkgUsageStats" msgid="8787352074326748892">"actualisar las datas statisticas da la cumponenta"</string>
- <!-- outdated translation 891553695716752835 --> <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Permetta da modifitgar las datas statisticas rimnadas da la cumponenta. Betg previs per applicaziuns normalas."</string>
- <!-- outdated translation 1660908117394854464 --> <string name="permlab_copyProtectedData" msgid="4341036311211406692">"Permetta da clamar il servetsch da container predefinì per copiar il cuntegn. Betg previs per applicaziuns normalas."</string>
- <!-- outdated translation 537780957633976401 --> <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Permetta da clamar il servetsch da container predefinì per copiar il cuntegn. Betg previs per applicaziuns normalas."</string>
- <!-- outdated translation 1311810005957319690 --> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Tutgar duas giadas per reglar il zoom"</string>
- <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Errur cun engrondir il widget"</string>
+ <!-- no translation found for permdesc_pkgUsageStats (1106612424254277630) -->
+ <skip />
+ <!-- no translation found for permlab_copyProtectedData (4341036311211406692) -->
+ <skip />
+ <!-- no translation found for permdesc_copyProtectedData (4390697124288317831) -->
+ <skip />
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4070433208160063538) -->
+ <skip />
+ <!-- no translation found for gadget_host_error_inflating (4882004314906466162) -->
+ <skip />
<string name="ime_action_go" msgid="8320845651737369027">"Dai"</string>
<string name="ime_action_search" msgid="658110271822807811">"Tschertgar"</string>
<string name="ime_action_send" msgid="2316166556349314424">"Trametter"</string>
@@ -1249,41 +1585,49 @@
<string name="ime_action_default" msgid="2840921885558045721">"Exequir"</string>
<string name="dial_number_using" msgid="5789176425167573586">"Cumponer il numer"\n"cun utilisar <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="4947405226788104538">"Agiuntar in contact"\n"cun il numer <xliff:g id="NUMBER">%s</xliff:g>"</string>
- <!-- outdated translation 6824538733852821001 --> <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Las suandantas applicaziuns dumondan l\'autorisaziun dad acceder a partir dad ussa a Voss conto."</string>
+ <!-- no translation found for grant_credentials_permission_message_header (2106103817937859662) -->
+ <skip />
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vulais Vus autorisar questa dumonda?"</string>
- <string name="grant_permissions_header_text" msgid="2722567482180797717">"Dumonda d\'access"</string>
+ <!-- no translation found for grant_permissions_header_text (6874497408201826708) -->
+ <skip />
<string name="allow" msgid="7225948811296386551">"Permetter"</string>
<string name="deny" msgid="2081879885755434506">"Refusar"</string>
- <string name="permission_request_notification_title" msgid="5390555465778213840">"Autorisaziun dumandada"</string>
- <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Autorisaziun dumandada"\n"per il conto <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
+ <!-- no translation found for permission_request_notification_title (6486759795926237907) -->
+ <skip />
+ <!-- no translation found for permission_request_notification_with_subtitle (8530393139639560189) -->
+ <skip />
<string name="input_method_binding_label" msgid="1283557179944992649">"Metoda d\'endataziun"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"Sincronisar"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"Agids d\'access"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Fund davos"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Midar il fund davos"</string>
- <!-- no translation found for vpn_title (8219003246858087489) -->
+ <!-- no translation found for vpn_title (19615213552042827) -->
<skip />
<!-- no translation found for vpn_title_long (6400714798049252294) -->
<skip />
- <!-- no translation found for vpn_text (1610714069627824309) -->
+ <!-- no translation found for vpn_text (3011306607126450322) -->
<skip />
- <!-- no translation found for vpn_text_long (4907843483284977618) -->
+ <!-- no translation found for vpn_text_long (6407351006249174473) -->
<skip />
<string name="upload_file" msgid="2897957172366730416">"Tscherner ina datoteca"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Nagina datoteca tschernida"</string>
<string name="reset" msgid="2448168080964209908">"Reinizialisar"</string>
<string name="submit" msgid="1602335572089911941">"Trametter"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Modus dad auto activà"</string>
- <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Tscherner per serrar il modus dad auto."</string>
+ <!-- no translation found for car_mode_disable_notification_message (8035230537563503262) -->
+ <skip />
<string name="tethered_notification_title" msgid="3146694234398202601">"Tethering u hotspot activ"</string>
- <string name="tethered_notification_message" msgid="3067108323903048927">"Tutgar per configurar"</string>
+ <!-- no translation found for tethered_notification_message (6857031760103062982) -->
+ <skip />
<string name="back_button_label" msgid="2300470004503343439">"Enavos"</string>
<string name="next_button_label" msgid="1080555104677992408">"Vinavant"</string>
<string name="skip_button_label" msgid="1275362299471631819">"Sursiglir"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"Grond diever da datas mobilas"</string>
- <string name="throttle_warning_notification_message" msgid="2609734763845705708">"Tutgar per vegnir a savair dapli davart l\'utilisaziun da datas mobilas"</string>
+ <!-- no translation found for throttle_warning_notification_message (3340822228599337743) -->
+ <skip />
<string name="throttled_notification_title" msgid="6269541897729781332">"Surpassà la limita da datas mobilas"</string>
- <string name="throttled_notification_message" msgid="4712369856601275146">"Tutgar per vegnir a savair dapli davart l\'utilisaziun da datas mobilas"</string>
+ <!-- no translation found for throttled_notification_message (5443457321354907181) -->
+ <skip />
<!-- no translation found for no_matches (8129421908915840737) -->
<skip />
<!-- no translation found for find_on_page (1946799233822820384) -->
@@ -1292,13 +1636,13 @@
<!-- no translation found for matches_found:other (4641872797067609177) -->
<!-- no translation found for action_mode_done (7217581640461922289) -->
<skip />
- <!-- no translation found for progress_unmounting (535863554318797377) -->
+ <!-- no translation found for progress_unmounting (3923810448507612746) -->
<skip />
- <!-- no translation found for progress_unmounting (5556813978958789471) -->
+ <!-- no translation found for progress_unmounting (1327894998409537190) -->
<skip />
- <!-- no translation found for progress_erasing (4183664626203056915) -->
+ <!-- no translation found for progress_erasing (4521573321524340058) -->
<skip />
- <!-- no translation found for progress_erasing (2115214724367534095) -->
+ <!-- no translation found for progress_erasing (6596988875507043042) -->
<skip />
<!-- no translation found for format_error (6299769563624776948) -->
<skip />
@@ -1336,19 +1680,19 @@
<skip />
<!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
<skip />
- <!-- no translation found for sync_too_many_deletes_desc (7030265992955132593) -->
+ <!-- no translation found for sync_too_many_deletes_desc (496551671008694245) -->
<skip />
- <!-- no translation found for sync_really_delete (8933566316059338692) -->
+ <!-- no translation found for sync_really_delete (2572600103122596243) -->
<skip />
- <!-- no translation found for sync_undo_deletes (8610996708225006328) -->
+ <!-- no translation found for sync_undo_deletes (2941317360600338602) -->
<skip />
- <!-- no translation found for sync_do_nothing (8717589462945226869) -->
+ <!-- no translation found for sync_do_nothing (3743764740430821845) -->
<skip />
<!-- no translation found for choose_account_label (5655203089746423927) -->
<skip />
<!-- no translation found for add_account_label (2935267344849993553) -->
<skip />
- <!-- no translation found for choose_account_text (6891230675141555481) -->
+ <!-- no translation found for choose_account_text (6303348737197849675) -->
<skip />
<!-- no translation found for add_account_button_label (3611982894853435874) -->
<skip />
@@ -1356,7 +1700,7 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
- <!-- no translation found for number_picker_increment_scroll_mode (1343063395404990189) -->
+ <!-- no translation found for number_picker_increment_scroll_mode (3073101067441638428) -->
<skip />
<!-- no translation found for number_picker_increment_scroll_action (4628981789985093179) -->
<skip />
@@ -1440,7 +1784,7 @@
<skip />
<!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
<skip />
- <!-- no translation found for keyboard_headset_required_to_hear_password (5913502399391940888) -->
+ <!-- no translation found for keyboard_headset_required_to_hear_password (7011927352267668657) -->
<skip />
<!-- no translation found for keyboard_password_character_no_headset (2859873770886153678) -->
<skip />
@@ -1450,17 +1794,17 @@
<skip />
<!-- no translation found for action_menu_overflow_description (2295659037509008453) -->
<skip />
- <!-- no translation found for storage_internal (7556050805474115618) -->
+ <!-- no translation found for storage_internal (4891916833657929263) -->
<skip />
- <!-- no translation found for storage_sd_card (8921771478629812343) -->
+ <!-- no translation found for storage_sd_card (3282948861378286745) -->
<skip />
<!-- no translation found for storage_usb (3017954059538517278) -->
<skip />
- <!-- no translation found for extract_edit_menu_button (302060189057163906) -->
+ <!-- no translation found for extract_edit_menu_button (8940478730496610137) -->
<skip />
<!-- no translation found for data_usage_warning_title (1955638862122232342) -->
<skip />
- <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+ <!-- no translation found for data_usage_warning_body (2814673551471969954) -->
<skip />
<!-- no translation found for data_usage_3g_limit_title (7093334419518706686) -->
<skip />
@@ -1470,7 +1814,7 @@
<skip />
<!-- no translation found for data_usage_wifi_limit_title (8992154736441284865) -->
<skip />
- <!-- no translation found for data_usage_limit_body (4313857592916426843) -->
+ <!-- no translation found for data_usage_limit_body (3317964706973601386) -->
<skip />
<!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
<skip />
@@ -1480,11 +1824,11 @@
<skip />
<!-- no translation found for data_usage_wifi_limit_snoozed_title (8743856006384825974) -->
<skip />
- <!-- no translation found for data_usage_limit_snoozed_body (2932736326652880660) -->
+ <!-- no translation found for data_usage_limit_snoozed_body (7035490278298441767) -->
<skip />
<!-- no translation found for data_usage_restricted_title (5965157361036321914) -->
<skip />
- <!-- no translation found for data_usage_restricted_body (5087354814839059798) -->
+ <!-- no translation found for data_usage_restricted_body (6741521330997452990) -->
<skip />
<!-- no translation found for ssl_certificate (6510040486049237639) -->
<skip />
@@ -1524,4 +1868,10 @@
<skip />
<!-- no translation found for list_delimeter (3975117572185494152) -->
<skip />
+ <!-- no translation found for sending (3245653681008218030) -->
+ <skip />
+ <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
+ <skip />
+ <!-- no translation found for SetupCallDefault (5834948469253758575) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index bc7f619393aa..ecee96d04a04 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Raportaţi"</string>
<string name="wait" msgid="7147118217226317732">"Aşteptaţi"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Pagina a devenit inactivă."\n\n"Doriţi să o închideţi?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Aplicaţie redirecţionată"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> funcţionează acum."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost lansată iniţial."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 1d71fd67a257..7b95291a11f9 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"ОК"</string>
<string name="report" msgid="4060218260984795706">"Отзыв"</string>
<string name="wait" msgid="7147118217226317732">"Подождать"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Страница не отвечает."\n\n"Закрыть ее?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Приложение перенаправлено"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> выполняется."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Изначально было запущено приложение <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index cb2e764f5126..aafaa9e4bd8b 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Prehľad"</string>
<string name="wait" msgid="7147118217226317732">"Čakajte"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Stránka nereaguje."\n\n"Chcete ju zavrieť?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Presmerovaná aplikácia"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Je spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Pôvodne bola spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 5e7c1360af7a..aa98c803fba4 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"V redu"</string>
<string name="report" msgid="4060218260984795706">"Poročaj"</string>
<string name="wait" msgid="7147118217226317732">"Čakaj"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Stran se ne odziva."\n" "\n"Ali jo želite zapreti?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Program preusmerjen"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Prvotno je bil zagnan program <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index bea78cec098b..7ba850331357 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -50,7 +50,7 @@
<string name="invalidPuk" msgid="8761456210898036513">"Унесите PUK који се састоји од 8 цифара или више."</string>
<string name="needPuk" msgid="919668385956251611">"SIM картица је закључана PUK кодом. Унесите PUK кôд да бисте је откључали."</string>
<string name="needPuk2" msgid="4526033371987193070">"Унесите PUK2 да бисте деблокирали SIM картицу."</string>
- <string name="ClipMmi" msgid="6952821216480289285">"Долазећи ИД позиваоца"</string>
+ <string name="ClipMmi" msgid="6952821216480289285">"Долазни ИД позиваоца"</string>
<string name="ClirMmi" msgid="7784673673446833091">"Одлазни ИД позиваоца"</string>
<string name="CfMmi" msgid="5123218989141573515">"Преусмеравање позива"</string>
<string name="CwMmi" msgid="9129678056795016867">"Позив на чекању"</string>
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"Потврди"</string>
<string name="report" msgid="4060218260984795706">"Пријави"</string>
<string name="wait" msgid="7147118217226317732">"Сачекај"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Страница је престала да се одазива."\n\n" Да ли желите да је затворите?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Апликација је преусмерена"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је сада покренута."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Првобитно је покренута апликација <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index bc59298018b7..4d3cea550e70 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Rapportera"</string>
<string name="wait" msgid="7147118217226317732">"Vänta"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Sidan har slutat svara."\n\n"Vill du stänga sidan?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Appen omdirigeras"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> startades först."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 5077d1fa91a0..a9a86799e335 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"Sawa"</string>
<string name="report" msgid="4060218260984795706">"Ripoti"</string>
<string name="wait" msgid="7147118217226317732">"Subiri"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Ukurasa umekwama. "\n" "\n" Je, unataka kuufunga?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Programu imeelekezwa kwingine"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>inaendesha sasa."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilizinduliwa mwanzoni."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 0babb00ae639..6a8431cd3af7 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"ตกลง"</string>
<string name="report" msgid="4060218260984795706">"รายงาน"</string>
<string name="wait" msgid="7147118217226317732">"รอ"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"หน้าเว็บนี้ไม่ตอบสนอง"\n\n"คุณต้องการปิดหรือไม่"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"แอปฯ ที่เปลี่ยนเส้นทาง"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงานอยู่ในขณะนี้"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> เปิดใช้ไว้แล้ว"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index b31fbf7d673d..04635c842f52 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Ulat"</string>
<string name="wait" msgid="7147118217226317732">"Maghintay"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Hindi na tumutugon ang pahina."\n\n"Nais mo ba itong isara?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Na-redirect ang app"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Tumatakbo na ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Orihinal na nalunsad ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index ebade95aaa8d..bfe9c0a4333d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"Tamam"</string>
<string name="report" msgid="4060218260984795706">"Bildir"</string>
<string name="wait" msgid="7147118217226317732">"Bekle"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Sayfa yanıt vermiyor."\n\n"Kapatmak ister misiniz?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Uygulama yönlendirildi"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> şimdi çalışıyor."</string>
<string name="launch_warning_original" msgid="188102023021668683">"İlk olarak <xliff:g id="APP_NAME">%1$s</xliff:g> başlatıldı."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index bc5456b09d45..670889344577 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Повідом."</string>
<string name="wait" msgid="7147118217226317732">"Чекати"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Сторінка не відповідає."\n\n"Закрити її?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Програму переадресовано"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"Зараз працює <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="launch_warning_original" msgid="188102023021668683">"Спочатку було запущено <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 177c4740c413..6da402cec65b 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"OK"</string>
<string name="report" msgid="4060218260984795706">"Báo cáo"</string>
<string name="wait" msgid="7147118217226317732">"Đợi"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Trang không phản hồi."\n\n"Bạn có muốn đóng trang không?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Đã chuyển hướng ứng dụng"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện đang chạy."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> được khởi chạy trước tiên."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b682eac98fac..6c4020261be3 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"确定"</string>
<string name="report" msgid="4060218260984795706">"报告"</string>
<string name="wait" msgid="7147118217226317732">"等待"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"该网页已无响应。"\n\n"要将其关闭吗?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"应用程序已重定向"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>目前正在运行。"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g>已启动。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 0928de80708e..131c2f7f2ccf 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -697,7 +697,7 @@
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"您嘗試解除這支手機的鎖定已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次,手機現在將恢復原廠設定。"</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> 秒後再試一次。"</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘記解鎖圖形?"</string>
- <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"解除封鎖帳戶"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帳戶解鎖"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"圖形嘗試次數過多"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"如要解除鎖定,請使用 Google 帳戶登入。"</string>
<string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"使用者名稱 (電子郵件)"</string>
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"確定"</string>
<string name="report" msgid="4060218260984795706">"回報"</string>
<string name="wait" msgid="7147118217226317732">"等待"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"網頁沒有回應。"\n\n"您要結束嗎?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"應用程式已重新導向"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在正在執行。"</string>
<string name="launch_warning_original" msgid="188102023021668683">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」原先已啟動。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index fc01c1df0388..1068b6675076 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -915,6 +915,7 @@
<string name="force_close" msgid="8346072094521265605">"KULUNGILE"</string>
<string name="report" msgid="4060218260984795706">"Umbiko"</string>
<string name="wait" msgid="7147118217226317732">"Linda"</string>
+ <string name="webpage_unresponsive" msgid="3272758351138122503">"Leli khasi alisaphenduli."\n\n"Ingabe ufuna ukulivala na?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Insiza idluliselwe phambili"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza."</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> iqalisiwe."</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f9e1f5bd5d5f..ce734fce8bb6 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -22,19 +22,9 @@
<!-- Do not translate. These are all of the drawable resources that should be preloaded by
the zygote process before it starts forking application processes. -->
<array name="preloaded_drawables">
- <item>@drawable/spinner_black_16</item>
- <item>@drawable/spinner_black_20</item>
- <item>@drawable/spinner_black_48</item>
- <item>@drawable/spinner_black_76</item>
- <item>@drawable/spinner_white_16</item>
- <item>@drawable/spinner_white_48</item>
- <item>@drawable/spinner_white_76</item>
- <item>@drawable/toast_frame</item>
<item>@drawable/toast_frame_holo</item>
- <item>@drawable/btn_check_on_selected</item>
<item>@drawable/btn_check_on_pressed_holo_light</item>
<item>@drawable/btn_check_on_pressed_holo_dark</item>
- <item>@drawable/btn_check_on_pressed</item>
<item>@drawable/btn_check_on_holo_light</item>
<item>@drawable/btn_check_on_holo_dark</item>
<item>@drawable/btn_check_on_focused_holo_light</item>
@@ -43,13 +33,8 @@
<item>@drawable/btn_check_on_disabled_holo_dark</item>
<item>@drawable/btn_check_on_disabled_focused_holo_light</item>
<item>@drawable/btn_check_on_disabled_focused_holo_dark</item>
- <item>@drawable/btn_check_on_disable_focused</item>
- <item>@drawable/btn_check_on_disable</item>
- <item>@drawable/btn_check_on</item>
- <item>@drawable/btn_check_off_selected</item>
<item>@drawable/btn_check_off_pressed_holo_light</item>
<item>@drawable/btn_check_off_pressed_holo_dark</item>
- <item>@drawable/btn_check_off_pressed</item>
<item>@drawable/btn_check_off_holo_light</item>
<item>@drawable/btn_check_off_holo_dark</item>
<item>@drawable/btn_check_off_focused_holo_light</item>
@@ -58,16 +43,10 @@
<item>@drawable/btn_check_off_disabled_holo_dark</item>
<item>@drawable/btn_check_off_disabled_focused_holo_light</item>
<item>@drawable/btn_check_off_disabled_focused_holo_dark</item>
- <item>@drawable/btn_check_off_disable_focused</item>
- <item>@drawable/btn_check_off_disable</item>
- <item>@drawable/btn_check_label_background</item>
<item>@drawable/btn_check_holo_light</item>
<item>@drawable/btn_check_holo_dark</item>
- <item>@drawable/btn_check</item>
- <item>@drawable/btn_radio_on_selected</item>
<item>@drawable/btn_radio_on_pressed_holo_light</item>
<item>@drawable/btn_radio_on_pressed_holo_dark</item>
- <item>@drawable/btn_radio_on_pressed</item>
<item>@drawable/btn_radio_on_holo_light</item>
<item>@drawable/btn_radio_on_holo_dark</item>
<item>@drawable/btn_radio_on_focused_holo_light</item>
@@ -76,11 +55,8 @@
<item>@drawable/btn_radio_on_disabled_holo_dark</item>
<item>@drawable/btn_radio_on_disabled_focused_holo_light</item>
<item>@drawable/btn_radio_on_disabled_focused_holo_dark</item>
- <item>@drawable/btn_radio_on</item>
- <item>@drawable/btn_radio_off_selected</item>
<item>@drawable/btn_radio_off_pressed_holo_light</item>
<item>@drawable/btn_radio_off_pressed_holo_dark</item>
- <item>@drawable/btn_radio_off_pressed</item>
<item>@drawable/btn_radio_off_holo_light</item>
<item>@drawable/btn_radio_off_holo_dark</item>
<item>@drawable/btn_radio_off_focused_holo_light</item>
@@ -89,23 +65,10 @@
<item>@drawable/btn_radio_off_disabled_holo_dark</item>
<item>@drawable/btn_radio_off_disabled_focused_holo_light</item>
<item>@drawable/btn_radio_off_disabled_focused_holo_dark</item>
- <item>@drawable/btn_radio_label_background</item>
- <item>@drawable/btn_radio</item>
- <item>@drawable/btn_default_transparent_normal</item>
- <item>@drawable/btn_default_small_selected</item>
- <item>@drawable/btn_default_small_pressed</item>
- <item>@drawable/btn_default_small_normal_disable_focused</item>
- <item>@drawable/btn_default_small_normal_disable</item>
- <item>@drawable/btn_default_small_normal</item>
- <item>@drawable/btn_default_selected</item>
<item>@drawable/btn_default_pressed_holo_light</item>
<item>@drawable/btn_default_pressed_holo_dark</item>
- <item>@drawable/btn_default_pressed</item>
<item>@drawable/btn_default_normal_holo_light</item>
<item>@drawable/btn_default_normal_holo_dark</item>
- <item>@drawable/btn_default_normal_disable_focused</item>
- <item>@drawable/btn_default_normal_disable</item>
- <item>@drawable/btn_default_normal</item>
<item>@drawable/btn_default_focused_holo_light</item>
<item>@drawable/btn_default_focused_holo_dark</item>
<item>@drawable/btn_default_disabled_holo_light</item>
@@ -114,24 +77,6 @@
<item>@drawable/btn_default_disabled_focused_holo_dark</item>
<item>@drawable/btn_default_holo_dark</item>
<item>@drawable/btn_default_holo_light</item>
- <item>@drawable/btn_default</item>
- <item>@drawable/btn_default_small</item>
- <item>@drawable/btn_dropdown_disabled</item>
- <item>@drawable/btn_dropdown_disabled_focused</item>
- <item>@drawable/btn_dropdown_normal</item>
- <item>@drawable/btn_dropdown_pressed</item>
- <item>@drawable/btn_dropdown_selected</item>
- <item>@drawable/btn_star_label_background</item>
- <item>@drawable/btn_star_big_off</item>
- <item>@drawable/btn_star_big_on</item>
- <item>@drawable/btn_star_big_on_disable</item>
- <item>@drawable/btn_star_big_off_disable</item>
- <item>@drawable/btn_star_big_on_pressed</item>
- <item>@drawable/btn_star_big_off_pressed</item>
- <item>@drawable/btn_star_big_on_selected</item>
- <item>@drawable/btn_star_big_off_selected</item>
- <item>@drawable/btn_star_big_on_disable_focused</item>
- <item>@drawable/btn_star_big_off_disable_focused</item>
<item>@drawable/btn_star_off_normal_holo_light</item>
<item>@drawable/btn_star_on_normal_holo_light</item>
<item>@drawable/btn_star_on_disabled_holo_light</item>
@@ -154,7 +99,6 @@
<item>@drawable/btn_star_on_disabled_focused_holo_dark</item>
<item>@drawable/btn_star_off_disabled_focused_holo_dark</item>
<item>@drawable/btn_star_holo_dark</item>
- <item>@drawable/btn_star</item>
<item>@drawable/btn_toggle_on_pressed_holo_light</item>
<item>@drawable/btn_toggle_on_pressed_holo_dark</item>
<item>@drawable/btn_toggle_on_normal_holo_light</item>
@@ -165,7 +109,6 @@
<item>@drawable/btn_toggle_on_disabled_holo_dark</item>
<item>@drawable/btn_toggle_on_disabled_focused_holo_light</item>
<item>@drawable/btn_toggle_on_disabled_focused_holo_dark</item>
- <item>@drawable/btn_toggle_on</item>
<item>@drawable/btn_toggle_off_pressed_holo_light</item>
<item>@drawable/btn_toggle_off_pressed_holo_dark</item>
<item>@drawable/btn_toggle_off_normal_holo_light</item>
@@ -176,23 +119,10 @@
<item>@drawable/btn_toggle_off_disabled_holo_dark</item>
<item>@drawable/btn_toggle_off_disabled_focused_holo_light</item>
<item>@drawable/btn_toggle_off_disabled_focused_holo_dark</item>
- <item>@drawable/btn_toggle_off</item>
<item>@drawable/btn_toggle_holo_light</item>
<item>@drawable/btn_toggle_holo_dark</item>
- <item>@drawable/btn_toggle</item>
- <item>@drawable/btn_toggle_bg</item>
- <item>@drawable/btn_dropdown</item>
- <item>@drawable/btn_dropdown</item>
- <item>@drawable/light_header_dither</item>
- <item>@drawable/divider_horizontal_textfield</item>
- <item>@drawable/divider_horizontal_dark_opaque</item>
- <item>@drawable/divider_horizontal_dark</item>
- <item>@drawable/divider_horizontal_bright_opaque</item>
- <item>@drawable/divider_horizontal_bright</item>
- <item>@drawable/divider_vertical_dark</item>
<item>@drawable/edit_text_holo_light</item>
<item>@drawable/edit_text_holo_dark</item>
- <item>@drawable/edit_text</item>
<item>@drawable/text_cursor_holo_light</item>
<item>@drawable/text_cursor_holo_dark</item>
<item>@drawable/text_select_handle_left</item>
@@ -200,70 +130,45 @@
<item>@drawable/text_edit_paste_window</item>
<item>@drawable/expander_close_holo_dark</item>
<item>@drawable/expander_close_holo_light</item>
- <item>@drawable/expander_ic_maximized</item>
- <item>@drawable/expander_ic_minimized</item>
- <item>@drawable/expander_group</item>
<item>@drawable/expander_group_holo_dark</item>
<item>@drawable/expander_group_holo_light</item>
- <item>@drawable/list_selector_background</item>
- <item>@drawable/list_selector_background_light</item>
- <item>@drawable/list_selector_background_longpress</item>
- <item>@drawable/list_selector_background_longpress_light</item>
- <item>@drawable/list_selector_background_pressed</item>
- <item>@drawable/list_selector_background_pressed_light</item>
- <item>@drawable/list_selector_background_selected</item>
<item>@drawable/list_selector_holo_dark</item>
<item>@drawable/list_selector_holo_light</item>
<item>@drawable/list_section_divider_holo_light</item>
<item>@drawable/list_section_divider_holo_dark</item>
- <item>@drawable/menu_background</item>
- <item>@drawable/menu_background_fill_parent_width</item>
<item>@drawable/menu_hardkey_panel_holo_dark</item>
<item>@drawable/menu_hardkey_panel_holo_light</item>
<item>@drawable/menu_submenu_background</item>
- <item>@drawable/menu_selector</item>
<item>@drawable/menu_dropdown_panel_holo_light</item>
<item>@drawable/menu_dropdown_panel_holo_dark</item>
<item>@drawable/overscroll_edge</item>
<item>@drawable/overscroll_glow</item>
- <item>@drawable/panel_background</item>
- <item>@drawable/popup_bottom_bright</item>
- <item>@drawable/popup_bottom_dark</item>
- <item>@drawable/popup_bottom_medium</item>
- <item>@drawable/popup_center_bright</item>
- <item>@drawable/popup_center_dark</item>
- <item>@drawable/popup_center_medium</item>
- <item>@drawable/popup_full_bright</item>
- <item>@drawable/popup_full_dark</item>
- <item>@drawable/popup_top_bright</item>
- <item>@drawable/popup_top_dark</item>
<item>@drawable/popup_inline_error_above_holo_dark</item>
<item>@drawable/popup_inline_error_above_holo_light</item>
<item>@drawable/popup_inline_error_holo_dark</item>
<item>@drawable/popup_inline_error_holo_light</item>
+ <item>@drawable/spinner_16_outer_holo</item>
+ <item>@drawable/spinner_16_inner_holo</item>
+ <item>@drawable/spinner_48_outer_holo</item>
+ <item>@drawable/spinner_48_inner_holo</item>
+ <item>@drawable/spinner_76_outer_holo</item>
+ <item>@drawable/spinner_76_inner_holo</item>
<item>@drawable/progress_bg_holo_dark</item>
<item>@drawable/progress_bg_holo_light</item>
- <item>@drawable/progress_horizontal</item>
<item>@drawable/progress_horizontal_holo_dark</item>
<item>@drawable/progress_horizontal_holo_light</item>
- <item>@drawable/progress_indeterminate_horizontal</item>
<item>@drawable/progress_indeterminate_horizontal_holo</item>
- <item>@drawable/progress_large</item>
<item>@drawable/progress_large_holo</item>
- <item>@drawable/progress_large_white</item>
- <item>@drawable/progress_medium</item>
<item>@drawable/progress_medium_holo</item>
- <item>@drawable/progress_medium_white</item>
<item>@drawable/progress_primary_holo_dark</item>
<item>@drawable/progress_primary_holo_light</item>
<item>@drawable/progress_secondary_holo_dark</item>
<item>@drawable/progress_secondary_holo_light</item>
- <item>@drawable/progress_small</item>
<item>@drawable/progress_small_holo</item>
- <item>@drawable/progress_small_titlebar</item>
- <item>@drawable/progress_small_white</item>
<item>@drawable/scrubber_progress_horizontal_holo_dark</item>
<item>@drawable/scrubber_progress_horizontal_holo_light</item>
+ <item>@drawable/background_holo_light</item>
+ <item>@drawable/background_holo_dark</item>
<item>@drawable/screen_background_dark</item>
<item>@drawable/screen_background_dark_transparent</item>
<item>@drawable/screen_background_light</item>
@@ -272,8 +177,6 @@
<item>@drawable/screen_background_selector_light</item>
<item>@drawable/scrollbar_handle_holo_dark</item>
<item>@drawable/scrollbar_handle_holo_light</item>
- <item>@drawable/scrollbar_handle_horizontal</item>
- <item>@drawable/scrollbar_handle_vertical</item>
<item>@drawable/spinner_background_holo_dark</item>
<item>@drawable/spinner_background_holo_light</item>
<item>@drawable/spinner_ab_default_holo_dark</item>
@@ -290,9 +193,6 @@
<item>@drawable/spinner_default_holo_light</item>
<item>@drawable/spinner_disabled_holo_dark</item>
<item>@drawable/spinner_disabled_holo_light</item>
- <item>@drawable/spinner_dropdown_background</item>
- <item>@drawable/spinner_dropdown_background_down</item>
- <item>@drawable/spinner_dropdown_background_up</item>
<item>@drawable/spinner_focused_holo_dark</item>
<item>@drawable/spinner_focused_holo_light</item>
<item>@drawable/spinner_pressed_holo_dark</item>
@@ -337,7 +237,6 @@
<item>@drawable/dialog_middle_holo_light</item>
<item>@drawable/dialog_top_holo_dark</item>
<item>@drawable/dialog_top_holo_light</item>
- <item>@drawable/ic_dialog_alert</item>
<item>@drawable/ic_dialog_alert_holo_dark</item>
<item>@drawable/ic_dialog_alert_holo_light</item>
<item>@drawable/list_divider_holo_dark</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 545a55529a8a..b514bf5311cc 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1830,12 +1830,12 @@
<!-- Defines whether the vertical scrollbar track should always be drawn. -->
<attr name="scrollbarAlwaysDrawVerticalTrack" format="boolean" />
- <!-- {@deprecated This attribute is deprecated and will be ignored as of
- API level 14 (<code>android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH</code>).
+ <!-- This attribute is deprecated and will be ignored as of
+ API level 14 ({@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}).
Using fading edges may introduce noticeable performance
degradations and should be used only when required by the application's
visual design. To request fading edges with API level 14 and above,
- use the <code>requiresFadingEdge</code> attribute instead.} -->
+ use the <code>android:requiresFadingEdge</code> attribute instead. -->
<attr name="fadingEdge">
<!-- No edge is faded. -->
<flag name="none" value="0x00000000" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bc132ebce98b..0511b7501328 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -361,7 +361,7 @@
with the modem or some other restricted hardware, add "/dev/bus/usb/001/"
to this list. If this is empty, no parts of the host USB bus will be excluded.
-->
- <string-array name="config_usbHostBlacklist">
+ <string-array name="config_usbHostBlacklist" translatable="false">
</string-array>
<!-- Vibrator pattern for feedback about a long screen/key press -->
@@ -533,13 +533,13 @@
<!-- Component name of the default wallpaper. This will be ImageWallpaper if not
specified -->
- <string name="default_wallpaper_component">@null</string>
+ <string name="default_wallpaper_component" translatable="false">@null</string>
<!-- Component name of the service providing network location support. -->
- <string name="config_networkLocationProvider">@null</string>
+ <string name="config_networkLocationProvider" translatable="false">@null</string>
<!-- Component name of the service providing geocoder API support. -->
- <string name="config_geocodeProvider">@null</string>
+ <string name="config_geocodeProvider" translatable="false">@null</string>
<!-- Boolean indicating if current platform supports bluetooth SCO for off call
use cases -->
@@ -563,7 +563,7 @@
<integer name="config_datause_throttle_kbitsps">300</integer>
<!-- The default iface on which to monitor data use -->
- <string name="config_datause_iface">rmnet0</string>
+ <string name="config_datause_iface" translatable="false">rmnet0</string>
<!-- The default reduced-datarate notification mask -->
<!-- 2 means give warning -->
@@ -593,11 +593,11 @@
<bool name="config_sms_capable">true</bool>
<!-- IP address of the dns server to use if nobody else suggests one -->
- <string name="config_default_dns_server">8.8.8.8</string>
+ <string name="config_default_dns_server" translatable="false">8.8.8.8</string>
<!-- The default character set for GsmAlphabet -->
<!-- Empty string means MBCS is not considered -->
- <string name="gsm_alphabet_default_charset"></string>
+ <string name="gsm_alphabet_default_charset" translatable="false"></string>
<!-- Enables SIP on WIFI only -->
<bool name="config_sip_wifi_only">false</bool>
@@ -632,7 +632,7 @@
OMA-TS-UAProf-V2_0-20060206-A Section 8.1.1.1. If the URL contains a '%s'
format string then that substring will be replaced with the value of
Build.MODEL. The format string shall not be escaped. -->
- <string name="config_useragentprofile_url"></string>
+ <string name="config_useragentprofile_url" translatable="false"></string>
<!-- When a database query is executed, the results retuned are paginated
in pages of size (in KB) indicated by this value -->
@@ -643,7 +643,7 @@
<bool name="config_showMenuShortcutsWhenKeyboardPresent">false</bool>
<!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD -->
- <string-array name="config_twoDigitNumberPattern">
+ <string-array name="config_twoDigitNumberPattern" translatable="false">
</string-array>
<!-- The VoiceMail default value is displayed to my own number if it is true -->
@@ -743,18 +743,18 @@
<!-- Set and Unsets WiMAX -->
<bool name="config_wimaxEnabled">false</bool>
<!-- Location of the wimax framwork jar location -->
- <string name="config_wimaxServiceJarLocation"></string>
+ <string name="config_wimaxServiceJarLocation" translatable="false"></string>
<!-- Location of the wimax native library locaiton -->
- <string name="config_wimaxNativeLibLocation"></string>
+ <string name="config_wimaxNativeLibLocation" translatable="false"></string>
<!-- Name of the wimax manager class -->
- <string name="config_wimaxManagerClassname"></string>
+ <string name="config_wimaxManagerClassname" translatable="false"></string>
<!-- Name of the wimax service class -->
- <string name="config_wimaxServiceClassname"></string>
+ <string name="config_wimaxServiceClassname" translatable="false"></string>
<!-- Name of the wimax state tracker clas -->
- <string name="config_wimaxStateTrackerClassname"></string>
+ <string name="config_wimaxStateTrackerClassname" translatable="false"></string>
<!-- Name of screensaver components to look for if none has been chosen by the user -->
- <string name="config_defaultDreamComponent">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
+ <string name="config_defaultDreamComponent" translatable="false">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
<!-- Base "touch slop" value used by ViewConfiguration as a
movement threshold where scrolling should begin. -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 3b6d6f1a66f0..571c4ad9e447 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -112,7 +112,7 @@ please see styles_device_defaults.xml.
</style>
<!-- Standard animations for a translucent window or activity. This
- style is <em>not<em> used by default for the translucent theme
+ style is <em>not</em> used by default for the translucent theme
(since translucent activities are a special case that have no
clear UI paradigm), but you can make your own specialized theme
with this animation style if you would like to have the standard
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index fe5388bdcd83..7046fc551002 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -29,15 +29,16 @@ please see themes_device_defaults.xml.
===============================================================
-->
<resources>
- <!-- The default system theme. This is the theme used for activities
- that have not explicitly set their own theme.
-
+ <!-- The default theme for apps on API level 10 and lower. This is the theme used for
+ activities that have not explicitly set their own theme.
<p>You can count on this being a dark
background with light text on top, but should try to make no
other assumptions about its appearance. In particular, the text
inside of widgets using this theme may be completely different,
with the widget container being a light color and the text on top
of it a dark color.
+ <p>If you're developing for API level 11 and higher, you should instead use {@link
+ #Theme_Holo} or {@link #Theme_DeviceDefault}.</p>
-->
<style name="Theme">
@@ -370,13 +371,12 @@ please see themes_device_defaults.xml.
<item name="pointerStyle">@android:style/Pointer</item>
</style>
- <!-- Variant of the default (dark) theme with no title bar -->
+ <!-- Variant of {@link #Theme} with no title bar -->
<style name="Theme.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Variant of the default (dark) theme that has no title bar and
- fills the entire screen -->
+ <!-- Variant of {@link #Theme} that has no title bar and no status bar -->
<style name="Theme.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
@@ -385,7 +385,8 @@ please see themes_device_defaults.xml.
<!-- Theme for a light background with dark text on top. Set your activity
to this theme if you would like such an appearance. As with the
default theme, you should try to assume little more than that the
- background will be a light color. -->
+ background will be a light color.
+ <p>This is designed for API level 10 and lower.</p>-->
<style name="Theme.Light">
<item name="windowBackground">@android:drawable/screen_background_selector_light</item>
<item name="colorBackground">@android:color/background_light</item>
@@ -457,19 +458,19 @@ please see themes_device_defaults.xml.
<item name="detailsElementBackground">@android:drawable/panel_bg_holo_light</item>
</style>
- <!-- Variant of the light theme with no title bar -->
+ <!-- Variant of {@link #Theme_Light} with no title bar -->
<style name="Theme.Light.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Variant of the light theme that has no title bar and
- fills the entire screen -->
+ <!-- Variant of {@link #Theme_Light} that has no title bar and
+ no status bar -->
<style name="Theme.Light.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
- <!-- Special variation on the default theme that ensures the background is
+ <!-- Variant on {@link #Theme} that ensures the background is
completely black. This is useful for things like image viewers and
media players. If you want the normal (dark background) theme
do <em>not</em> use this, use {@link #Theme}. -->
@@ -478,40 +479,40 @@ please see themes_device_defaults.xml.
<item name="android:colorBackground">@android:color/black</item>
</style>
- <!-- Variant of the black theme with no title bar -->
+ <!-- Variant of {@link #Theme_Black} with no title bar -->
<style name="Theme.Black.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Variant of the black theme that has no title bar and
- fills the entire screen -->
+ <!-- Variant of {@link #Theme_Black} that has no title bar and
+ no status bar -->
<style name="Theme.Black.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
- <!-- Default theme for windows that want to have the user's selected
- wallpaper appear behind them. -->
+ <!-- Theme for windows that want to have the user's selected
+ wallpaper appear behind them (for API level 10 and lower). -->
<style name="Theme.Wallpaper">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowShowWallpaper">true</item>
</style>
- <!-- Variant of the translucent theme with no title bar -->
+ <!-- Variant of {@link #Theme_Wallpaper} that has no title bar -->
<style name="Theme.Wallpaper.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Variant of the translucent theme that has no title bar and
- fills the entire screen -->
+ <!-- Variant of {@link #Theme_Wallpaper} that
+ has no title bar or status bar. -->
<style name="Theme.Wallpaper.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
- <!-- Theme for a wallpaper's setting activity that is designed to be on
- top of a dark background. -->
+ <!-- Theme for a wallpaper's setting activity, which is designed to be a transparent
+ background with a dark shade, so the previous Activity is visible in the background. -->
<style name="Theme.WallpaperSettings">
<item name="android:windowBackground">@android:drawable/screen_background_dark_transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
@@ -519,8 +520,8 @@ please see themes_device_defaults.xml.
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
</style>
- <!-- Theme for a wallpaper's setting activity that is designed to be on
- top of a light background. -->
+ <!-- Theme for a wallpaper's setting activity, which is designed to be a transparent
+ background with a light shade, so the previous Activity is visible in the background. -->
<style name="Theme.Light.WallpaperSettings">
<item name="android:windowBackground">@android:drawable/screen_background_light_transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
@@ -538,8 +539,8 @@ please see themes_device_defaults.xml.
<style name="PreviewWallpaperSettings">
</style>
- <!-- Default theme for translucent activities, that is windows that allow you
- to see through them to the windows behind. This sets up the translucent
+ <!-- Theme for translucent activities (on API level 10 and lower). That is, windows
+ that allow you to see through them to the windows behind. This sets up the translucent
flag and appropriate animations for your windows. -->
<style name="Theme.Translucent">
<item name="android:windowBackground">@android:color/transparent</item>
@@ -551,14 +552,14 @@ please see themes_device_defaults.xml.
<item name="android:windowAnimationStyle">@android:style/Animation</item>
</style>
- <!-- Variant of the translucent theme with no title bar -->
+ <!-- Variant of {@link #Theme_Translucent} with no title bar -->
<style name="Theme.Translucent.NoTitleBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
- <!-- Variant of the translucent theme that has no title bar and
- fills the entire screen -->
+ <!-- Variant of {@link #Theme_Translucent} that has no title bar and
+ no status bar -->
<style name="Theme.Translucent.NoTitleBar.Fullscreen">
<item name="android:windowFullscreen">true</item>
</style>
@@ -574,7 +575,8 @@ please see themes_device_defaults.xml.
<item name="android:windowNoDisplay">true</item>
</style>
- <!-- Default theme for dialog windows and activities, which is used by the
+ <!-- Default theme for dialog windows and activities (on API level 10 and lower),
+ which is used by the
{@link android.app.Dialog} class. This changes the window to be
floating (not fill the entire screen), and puts a frame around its
contents. You can set this theme on an activity if you would like to
@@ -622,7 +624,7 @@ please see themes_device_defaults.xml.
<item name="listPreferredItemPaddingRight">10dip</item>
</style>
- <!-- Variation of Theme.Dialog that does not include a frame (or background).
+ <!-- Variant of {@link Theme_Dialog} that does not include a frame (or background).
The view hierarchy of the dialog is responsible for drawing all of
its pixels. -->
<style name="Theme.Dialog.NoFrame">
@@ -636,7 +638,7 @@ please see themes_device_defaults.xml.
<item name="android:windowCloseOnTouchOutside">false</item>
</style>
- <!-- Default theme for alert dialog windows, which is used by the
+ <!-- Default theme for alert dialog windows (on API level 10 and lower), which is used by the
{@link android.app.AlertDialog} class. This is basically a dialog
but sets the background to empty so it can do two-tone backgrounds. -->
<style name="Theme.Dialog.Alert">
@@ -648,8 +650,8 @@ please see themes_device_defaults.xml.
<item name="textAppearanceListItemSmall">@android:style/TextAppearance.Large.Inverse</item>
</style>
- <!-- Default dark theme for panel windows. This removes all extraneous
- window decorations, so you basically have an empty rectangle in which
+ <!-- Default dark theme for panel windows (on API level 10 and lower). This removes all
+ extraneous window decorations, so you basically have an empty rectangle in which
to place your content. It makes the window floating, with a transparent
background, and turns off dimming behind the window. -->
<style name="Theme.Panel">
@@ -664,8 +666,8 @@ please see themes_device_defaults.xml.
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Default light theme for panel windows. This removes all extraneous
- window decorations, so you basically have an empty rectangle in which
+ <!-- Default light theme for panel windows (on API level 10 and lower). This removes all
+ extraneous window decorations, so you basically have an empty rectangle in which
to place your content. It makes the window floating, with a transparent
background, and turns off dimming behind the window. -->
<style name="Theme.Light.Panel">
@@ -712,7 +714,7 @@ please see themes_device_defaults.xml.
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Default theme for input methods, which is used by the
+ <!-- Default theme for input methods (on API level 10 and lower), which is used by the
{@link android.inputmethodservice.InputMethodService} class.
this inherits from Theme.Panel, but sets up IME appropriate animations
and a few custom attributes. -->
@@ -723,7 +725,7 @@ please see themes_device_defaults.xml.
<item name="android:imeExtractExitAnimation">@android:anim/input_method_extract_exit</item>
</style>
- <!-- Default theme for modern holo style input methods, which is used by the
+ <!-- Default theme for holo style input methods, which is used by the
{@link android.inputmethodservice.InputMethodService} class.
this inherits from Theme.Panel, but sets up IME appropriate animations
and a few custom attributes. -->
@@ -842,14 +844,23 @@ please see themes_device_defaults.xml.
<item name="android:windowActionModeOverlay">true</item>
</style>
- <!-- New Honeycomb holographic theme. Dark version. The widgets in the
- holographic theme are translucent on their brackground, so applications
- must ensure that any background they use with this theme is itself
- dark; otherwise, it will be difficult to see the widgets. The new
- UI style also includes a full action bar by default.
-
- Styles used by the Holo theme are named using the convention Type.Holo.Etc.
- (For example, Widget.Holo.Button, TextAppearance.Holo.Widget.PopupMenu.Large.)
+ <!-- Honeycomb holographic theme (dark version).
+ <p>This is the default system theme for apps that target API level 11 - 13. Starting
+ with API level 14, the default system theme is supplied by {@link #Theme_DeviceDefault},
+ which might apply a different style on different devices. If you want to ensure that your
+ app consistenly uses the Holo theme at all times, you must explicitly declare it in your
+ manifest. For example, {@code &lt;application android:theme="@android:style/Theme.Holo"&gt;}.
+ For more information, read <a
+ href="http://android-developers.blogspot.com/2012/01/holo-everywhere.html">Holo
+ Everywhere</a>.</p>
+ <p>The widgets in the holographic theme are translucent on their brackground, so
+ applications must ensure that any background they use with this theme is itself
+ dark; otherwise, it will be difficult to see the widgets. This UI style also includes a
+ full action bar by default.</p>
+
+ <p>Styles used by the Holo theme are named using the convention Type.Holo.Etc
+ (for example, {@code Widget.Holo.Button} and {@code
+ TextAppearance.Holo.Widget.PopupMenu.Large}).
Specific resources used by Holo are named using the convention @type/foo_bar_baz_holo
with trailing _dark or _light specifiers if they are not shared between both light and
dark versions of the theme. -->
@@ -951,15 +962,12 @@ please see themes_device_defaults.xml.
<item name="listDividerAlertDialog">@android:drawable/list_divider_holo_dark</item>
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
- <item name="expandableListPreferredChildPaddingLeft">
- ?android:attr/expandableListPreferredItemPaddingLeft</item>
+ <item name="expandableListPreferredChildPaddingLeft">?android:attr/expandableListPreferredItemPaddingLeft</item>
<item name="expandableListPreferredItemIndicatorLeft">3dip</item>
<item name="expandableListPreferredItemIndicatorRight">0dip</item>
- <item name="expandableListPreferredChildIndicatorLeft">
- ?android:attr/expandableListPreferredItemIndicatorLeft</item>
- <item name="expandableListPreferredChildIndicatorRight">
- ?android:attr/expandableListPreferredItemIndicatorRight</item>
+ <item name="expandableListPreferredChildIndicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
+ <item name="expandableListPreferredChildIndicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
<!-- Gallery attributes -->
<item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
@@ -1156,10 +1164,10 @@ please see themes_device_defaults.xml.
</style>
- <!-- New Honeycomb holographic theme. Light version. The widgets in the
+ <!-- Honeycomb holographic theme (light version). The widgets in the
holographic theme are translucent on their brackground, so applications
must ensure that any background they use with this theme is itself
- light; otherwise, it will be difficult to see the widgets. The new
+ light; otherwise, it will be difficult to see the widgets. This
UI style also includes a full action bar by default. -->
<style name="Theme.Holo.Light" parent="Theme.Light">
<item name="colorForeground">@android:color/bright_foreground_holo_light</item>
@@ -1257,15 +1265,12 @@ please see themes_device_defaults.xml.
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_holo_light</item>
<item name="expandableListPreferredItemPaddingLeft">40dip</item>
- <item name="expandableListPreferredChildPaddingLeft">
- ?android:attr/expandableListPreferredItemPaddingLeft</item>
+ <item name="expandableListPreferredChildPaddingLeft">?android:attr/expandableListPreferredItemPaddingLeft</item>
<item name="expandableListPreferredItemIndicatorLeft">3dip</item>
<item name="expandableListPreferredItemIndicatorRight">0dip</item>
- <item name="expandableListPreferredChildIndicatorLeft">
- ?android:attr/expandableListPreferredItemIndicatorLeft</item>
- <item name="expandableListPreferredChildIndicatorRight">
- ?android:attr/expandableListPreferredItemIndicatorRight</item>
+ <item name="expandableListPreferredChildIndicatorLeft">?android:attr/expandableListPreferredItemIndicatorLeft</item>
+ <item name="expandableListPreferredChildIndicatorRight">?android:attr/expandableListPreferredItemIndicatorRight</item>
<item name="listDividerAlertDialog">@android:drawable/list_divider_holo_light</item>
@@ -1522,6 +1527,7 @@ please see themes_device_defaults.xml.
</style>
<!-- Dialog themes for Holo -->
+ <eat-comment />
<!-- Holo theme for dialog windows and activities, which is used by the
{@link android.app.Dialog} class. This changes the window to be
@@ -1554,27 +1560,27 @@ please see themes_device_defaults.xml.
<item name="listPreferredItemPaddingRight">16dip</item>
</style>
- <!-- Variation of Theme.Holo.Dialog that has a nice minumum width for
+ <!-- Variant of Theme.Holo.Dialog that has a nice minimum width for
a regular dialog. -->
<style name="Theme.Holo.Dialog.MinWidth">
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
- <!-- Variation of Theme.Holo.Dialog that does not include a title bar. -->
+ <!-- Variant of Theme.Holo.Dialog that does not include a title bar. -->
<style name="Theme.Holo.Dialog.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Variation of Theme.Holo.Dialog.NoActionVar that has a nice minumum width for
+ <!-- Variant of Theme.Holo.Dialog.NoActionBar that has a nice minimum width for
a regular dialog. -->
<style name="Theme.Holo.Dialog.NoActionBar.MinWidth">
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
- <!-- Variation of Theme.Holo.Dialog that does not include a frame (or background).
+ <!-- Variant of Theme.Holo.Dialog that does not include a frame (or background).
The view hierarchy of the dialog is responsible for drawing all of
its pixels. -->
<style name="Theme.Holo.Dialog.NoFrame">
@@ -1646,20 +1652,20 @@ please see themes_device_defaults.xml.
<item name="listPreferredItemPaddingRight">16dip</item>
</style>
- <!-- Variation of Theme.Holo.Light.Dialog that has a nice minumum width for
+ <!-- Variant of Theme.Holo.Light.Dialog that has a nice minimum width for
a regular dialog. -->
<style name="Theme.Holo.Light.Dialog.MinWidth">
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
- <!-- Variation of Theme.Holo.Light.Dialog that does not include a title bar. -->
+ <!-- Variant of Theme.Holo.Light.Dialog that does not include a title bar. -->
<style name="Theme.Holo.Light.Dialog.NoActionBar">
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style>
- <!-- Variation of Theme.Holo.Light.Dialog.NoActionBar that has a nice minumum width for
+ <!-- Variant of Theme.Holo.Light.Dialog.NoActionBar that has a nice minimum width for
a regular dialog. -->
<style name="Theme.Holo.Light.Dialog.NoActionBar.MinWidth">
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
@@ -1700,7 +1706,8 @@ please see themes_device_defaults.xml.
<item name="android:windowShowWallpaper">true</item>
</style>
- <!-- Variant of the holographic (dark) theme with no title bar -->
+ <!--Default holographic (dark) for windows that want to have the user's selected
+ wallpaper appear behind them and without an action bar. -->
<style name="Theme.Holo.Wallpaper.NoTitleBar">
<item name="android:windowNoTitle">true</item>
</style>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 813598641184..abe4aad71e4e 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -31,6 +31,24 @@ easier.
===============================================================
-->
<resources>
+
+ <!-- The default theme for apps that target API level 14 and higher.
+ <p>The DeviceDefault themes are aliases for a specific device’s native look and feel. The
+ DeviceDefault theme family and widget style family offer ways for you to target your app
+ to a device’s native theme with all device customizations intact.</p>
+ <p>For example, when you set your app's {@code targetSdkVersion} to 14 or higher, this
+ theme is applied to your application by default. As such, your app might appear with the
+ {@link #Theme_Holo Holo} styles on one device, but with a different set of styles on
+ another device. This is great if you want your app to fit with the device's native look and
+ feel. If, however, you prefer to keep your UI style the same across all devices, you should
+ apply a specific theme such as {@link #Theme_Holo Holo} or one of your own design. For more
+ information, read <a
+ href="http://android-developers.blogspot.com/2012/01/holo-everywhere.html">Holo
+ Everywhere</a>.</p>
+ <p>Styles used by the DeviceDefault theme are named using the convention
+ Type.DeviceDefault.Etc (for example, {@code Widget.DeviceDefault.Button} and
+ {@code TextAppearance.DeviceDefault.Widget.PopupMenu.Large}).</p>
+ -->
<style name="Theme.DeviceDefault" parent="Theme.Holo" >
<!-- Text styles -->
<item name="textAppearance">@android:style/TextAppearance.DeviceDefault</item>
@@ -176,12 +194,16 @@ easier.
<!-- DatePicker style -->
<item name="datePickerStyle">@style/Widget.DeviceDefault.DatePicker</item>
</style>
+
+ <!-- Variant of {@link #Theme_DeviceDefault} with no action bar -->
<style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Holo.NoActionBar" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar -->
<style name="Theme.DeviceDefault.NoActionBar.Fullscreen" parent="Theme.Holo.NoActionBar.Fullscreen" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
<style name="Theme.DeviceDefault.Light" parent="Theme.Holo.Light" >
<!-- Text styles -->
<item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Light</item>
@@ -322,12 +344,17 @@ easier.
<!-- DatePicker style -->
<item name="datePickerStyle">@style/Widget.DeviceDefault.Light.DatePicker</item>
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
<style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Holo.Light.NoActionBar" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar -->
<style name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" parent="Theme.Holo.Light.NoActionBar.Fullscreen" >
</style>
+ <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
+ floating (not fill the entire screen), and puts a frame around its contents. You can set this
+ theme on an activity if you would like to make an activity that looks like a Dialog. -->
<style name="Theme.DeviceDefault.Dialog" parent="Theme.Holo.Dialog" >
<item name="android:windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault</item>
<item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Dialog</item>
@@ -338,15 +365,23 @@ easier.
<item name="textAppearance">@android:style/TextAppearance.DeviceDefault</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item>
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
+ regular dialog. -->
<style name="Theme.DeviceDefault.Dialog.MinWidth" parent="Theme.Holo.Dialog.MinWidth" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
<style name="Theme.DeviceDefault.Dialog.NoActionBar" parent="Theme.Holo.Dialog.NoActionBar" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
+ for a regular dialog. -->
<style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Dialog.NoActionBar.MinWidth" >
</style>
+ <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
+ floating (not fill the entire screen), and puts a frame around its contents. You can set this
+ theme on an activity if you would like to make an activity that looks like a Dialog.-->
<style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Holo.Light.Dialog" >
<item name="android:windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault.Light</item>
<item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Dialog</item>
@@ -357,42 +392,71 @@ easier.
<item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Light</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Light.Inverse</item>
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
+ regular dialog. -->
<style name="Theme.DeviceDefault.Light.Dialog.MinWidth" parent="Theme.Holo.Light.Dialog.MinWidth" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
<style name="Theme.DeviceDefault.Light.Dialog.NoActionBar" parent="Theme.Holo.Light.Dialog.NoActionBar" >
</style>
+ <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
+ width for a regular dialog. -->
<style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Light.Dialog.NoActionBar.MinWidth" >
</style>
+ <!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
+ screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
<style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Holo.DialogWhenLarge" >
</style>
+ <!-- DeviceDefault theme for a window without an action bar that will be displayed either
+ full-screen on smaller screens (small, normal) or as a dialog on larger screens (large,
+ xlarge). -->
<style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="Theme.Holo.DialogWhenLarge.NoActionBar" >
</style>
+ <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
+ screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
<style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Holo.Light.DialogWhenLarge" >
</style>
+ <!-- DeviceDefault light theme for a window without an action bar that will be displayed either
+ full-screen on smaller screens (small, normal) or as a dialog on larger screens (large,
+ xlarge). -->
<style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Holo.Light.DialogWhenLarge.NoActionBar" >
</style>
+ <!-- DeviceDefault theme for panel windows. This removes all extraneous window
+ decorations, so you basically have an empty rectangle in which to place your content. It makes
+ the window floating, with a transparent background, and turns off dimming behind the window. -->
<style name="Theme.DeviceDefault.Panel" parent="Theme.Holo.Panel" >
</style>
+ <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
+ decorations, so you basically have an empty rectangle in which to place your content. It makes
+ the window floating, with a transparent background, and turns off dimming behind the window. -->
<style name="Theme.DeviceDefault.Light.Panel" parent="Theme.Holo.Light.Panel" >
</style>
+ <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
+ behind them. -->
<style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Holo.Wallpaper" >
</style>
+ <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
+ behind them and without an action bar. -->
<style name="Theme.DeviceDefault.Wallpaper.NoTitleBar" parent="Theme.Holo.Wallpaper.NoTitleBar" >
</style>
+ <!-- DeviceDefault style for input methods, which is used by the
+ {@link android.inputmethodservice.InputMethodService} class.-->
<style name="Theme.DeviceDefault.InputMethod" parent="Theme.Holo.InputMethod" >
</style>
+ <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
+ inverse color profile. -->
<style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Holo.Light.DarkActionBar" >
<item name="android:actionBarStyle">@android:style/Widget.DeviceDefault.Light.ActionBar.Solid.Inverse</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 3ffa085ae0b7..7233e7fdfa67 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -46,7 +46,7 @@ public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunn
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
- if (!UtilHelper.isWifiOnly()) {
+ if (!UtilHelper.isWifiOnly(getContext())) {
suite.addTestSuite(WifiApStress.class);
suite.addTestSuite(WifiStressTest.class);
} else {
@@ -64,7 +64,7 @@ public class ConnectivityManagerStressTestRunner extends InstrumentationTestRunn
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- if (!UtilHelper.isWifiOnly()) {
+ if (!UtilHelper.isWifiOnly(getContext())) {
String valueStr = (String) icicle.get("softap_iterations");
if (valueStr != null) {
int iteration = Integer.parseInt(valueStr);
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index 20aae47077a3..9819c54aad6d 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -40,7 +40,7 @@ public class ConnectivityManagerTestRunner extends InstrumentationTestRunner {
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
- if (!UtilHelper.isWifiOnly()) {
+ if (!UtilHelper.isWifiOnly(getContext())) {
suite.addTestSuite(ConnectivityManagerMobileTest.class);
} else {
// create a new test suite
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
index 1b966bfb42e3..b9fe6edf7e2a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/UtilHelper.java
@@ -16,12 +16,31 @@
package com.android.connectivitymanagertest;
-import android.os.SystemProperties;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.util.Log;
public class UtilHelper {
- public static boolean isWifiOnly() {
- return "wifi-only".equals(SystemProperties.get("ro.carrier"));
- }
+ private static Boolean mIsWifiOnly = null;
+ private static final Object sLock = new Object();
+ /**
+ * Return true if device is a wifi only device.
+ */
+ public static boolean isWifiOnly(Context context) {
+ synchronized (sLock) {
+ // cache the result from pkgMgr statically. It will never change, since its a
+ // device configuration setting
+ if (mIsWifiOnly == null) {
+ PackageManager pkgMgr = context.getPackageManager();
+ mIsWifiOnly = Boolean.valueOf(!pkgMgr
+ .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
+ && pkgMgr.hasSystemFeature(PackageManager.FEATURE_WIFI));
+ String deviceType = mIsWifiOnly ? "wifi-only" : "telephony";
+ Log.d("ConnectivityManagerTest", String.format("detected a %s device", deviceType));
+ }
+ }
+ return mIsWifiOnly;
+ }
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index b1f4bf122a4f..52326d577496 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -16,37 +16,31 @@
package com.android.connectivitymanagertest.functional;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
-import com.android.connectivitymanagertest.UtilHelper;
-
-import android.content.Intent;
import android.content.Context;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.app.Instrumentation;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
-import android.net.NetworkInfo.DetailedState;
import android.net.wifi.WifiManager;
-
-import android.test.suitebuilder.annotation.LargeTest;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.provider.Settings;
import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
import com.android.connectivitymanagertest.NetworkState;
-import android.util.Log;
+import com.android.connectivitymanagertest.UtilHelper;
-public class ConnectivityManagerMobileTest
- extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
+public class ConnectivityManagerMobileTest extends
+ ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
private static final String LOG_TAG = "ConnectivityManagerMobileTest";
- private static final String PKG_NAME = "com.android.connectivitymanagertest";
private String TEST_ACCESS_POINT;
private ConnectivityManagerTestActivity cmActivity;
private WakeLock wl;
+ private boolean mIsWifiOnlyDevice;
public ConnectivityManagerMobileTest() {
super(ConnectivityManagerTestActivity.class);
@@ -69,7 +63,8 @@ public class ConnectivityManagerMobileTest
log("airplane is not disabled, disable it.");
cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
}
- if (!UtilHelper.isWifiOnly()) {
+ mIsWifiOnlyDevice = UtilHelper.isWifiOnly(mRunner.getTargetContext());
+ if (!mIsWifiOnlyDevice) {
if (!cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT)) {
// Note: When the test fails in setUp(), tearDown is not called. In that case,
@@ -166,7 +161,7 @@ public class ConnectivityManagerMobileTest
public void testConnectToWifi() {
assertNotNull("SSID is null", TEST_ACCESS_POINT);
NetworkInfo networkInfo;
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
//Prepare for connectivity verification
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -185,7 +180,7 @@ public class ConnectivityManagerMobileTest
log("wifi state is enabled");
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -197,7 +192,7 @@ public class ConnectivityManagerMobileTest
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
@@ -232,13 +227,13 @@ public class ConnectivityManagerMobileTest
ConnectivityManagerTestActivity.LONG_TIMEOUT));
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
NetworkInfo networkInfo;
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
//Prepare for connectivity state verification
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
@@ -258,7 +253,7 @@ public class ConnectivityManagerMobileTest
// Wait for Wifi to be connected and mobile to be disconnected
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -288,7 +283,7 @@ public class ConnectivityManagerMobileTest
sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
NetworkInfo networkInfo;
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
networkInfo.getState(),
@@ -304,7 +299,7 @@ public class ConnectivityManagerMobileTest
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
@@ -316,7 +311,7 @@ public class ConnectivityManagerMobileTest
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue(false);
}
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("Mobile state transition validation failed.");
log("reason: " +
@@ -393,7 +388,7 @@ public class ConnectivityManagerMobileTest
cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
NetworkInfo networkInfo;
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
@@ -419,7 +414,7 @@ public class ConnectivityManagerMobileTest
cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
assertTrue("State validation failed", false);
}
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
log("state validation for Mobile failed");
log("reason: " +
@@ -471,7 +466,7 @@ public class ConnectivityManagerMobileTest
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 2069789c37c6..feb63cd8dfab 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -16,10 +16,6 @@
package com.android.connectivitymanagertest.stress;
-import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
-import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
-import com.android.connectivitymanagertest.UtilHelper;
-
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo.State;
@@ -31,15 +27,15 @@ import android.net.wifi.WifiConfiguration.ProxySettings;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.PowerManager;
-import android.os.IPowerManager;
-import android.os.SystemClock;
-import android.os.ServiceManager;
import android.provider.Settings;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
-
import android.util.Log;
+import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
+import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
+import com.android.connectivitymanagertest.UtilHelper;
+
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
@@ -79,6 +75,7 @@ public class WifiStressTest
private String mPassword;
private ConnectivityManagerStressTestRunner mRunner;
private BufferedWriter mOutputWriter = null;
+ private boolean mIsWifiOnlyDevice;
public WifiStressTest() {
super(ConnectivityManagerTestActivity.class);
@@ -100,6 +97,7 @@ public class WifiStressTest
mOutputWriter = new BufferedWriter(new FileWriter(new File(
Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
mAct.turnScreenOn();
+ mIsWifiOnlyDevice = UtilHelper.isWifiOnly(mRunner.getTargetContext());
if (!mAct.mWifiManager.isWifiEnabled()) {
log("Enable wi-fi before stress tests.");
if (!mAct.enableWifi()) {
@@ -271,7 +269,7 @@ public class WifiStressTest
assertTrue("Wait for Wi-Fi to idle timeout",
mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
// use long timeout as the pppd startup may take several retries.
assertTrue("Wait for cellular connection timeout",
mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
@@ -282,7 +280,7 @@ public class WifiStressTest
assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
- if (!UtilHelper.isWifiOnly()) {
+ if (!mIsWifiOnlyDevice) {
assertEquals("Cellular connection is down", State.CONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
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 a5e5ab0e77b9..dfcbba950b99 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java
@@ -146,10 +146,10 @@ public class ConnectionUtil {
Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
return;
}
- if (intent.hasExtra(ConnectivityManager.EXTRA_NETWORK_INFO)) {
- mNetworkInfo = (NetworkInfo)
- intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
- }
+
+ final ConnectivityManager connManager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ mNetworkInfo = connManager.getActiveNetworkInfo();
if (intent.hasExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO)) {
mOtherNetworkInfo = (NetworkInfo)
diff --git a/core/tests/coretests/src/android/util/InternalSelectionView.java b/core/tests/coretests/src/android/util/InternalSelectionView.java
index babf38d308ec..a0fb0f18a4fa 100644
--- a/core/tests/coretests/src/android/util/InternalSelectionView.java
+++ b/core/tests/coretests/src/android/util/InternalSelectionView.java
@@ -36,6 +36,11 @@ import android.util.AttributeSet;
* entire width of the view. The height of the view is divided evenly among
* the rows.
*
+ * Note: If the height of the view does not divide exactly to the number of rows,
+ * the last row's height is inflated with the remainder. For example, if the
+ * view height is 22 and there are two rows, the height of the first row is
+ * 10 and the second 22.
+ *
* Notice what this view does to be a good citizen w.r.t its internal selection:
* 1) calls {@link View#requestRectangleOnScreen} each time the selection changes due to
* internal navigation.
@@ -138,9 +143,6 @@ public class InternalSelectionView extends View {
@Override
protected void onDraw(Canvas canvas) {
-
- int rowHeight = getRowHeight();
-
int rectTop = mPaddingTop;
int rectLeft = mPaddingLeft;
int rectRight = getWidth() - mPaddingRight;
@@ -149,6 +151,8 @@ public class InternalSelectionView extends View {
mPainter.setColor(Color.BLACK);
mPainter.setAlpha(0x20);
+ int rowHeight = getRowHeight(i);
+
// draw background rect
mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight);
canvas.drawRect(mTempRect, mPainter);
@@ -178,12 +182,19 @@ public class InternalSelectionView extends View {
}
}
- private int getRowHeight() {
- return (getHeight() - mPaddingTop - mPaddingBottom) / mNumRows;
+ private int getRowHeight(int row) {
+ final int availableHeight = getHeight() - mPaddingTop - mPaddingBottom;
+ final int desiredRowHeight = availableHeight / mNumRows;
+ if (row < mNumRows - 1) {
+ return desiredRowHeight;
+ } else {
+ final int residualHeight = availableHeight % mNumRows;
+ return desiredRowHeight + residualHeight;
+ }
}
public void getRectForRow(Rect rect, int row) {
- final int rowHeight = getRowHeight();
+ final int rowHeight = getRowHeight(row);
final int top = mPaddingTop + row * rowHeight;
rect.set(mPaddingLeft,
top,
@@ -197,10 +208,7 @@ public class InternalSelectionView extends View {
requestRectangleOnScreen(mTempRect);
}
-
- /* (non-Javadoc)
- * @see android.view.KeyEvent.Callback#onKeyDown(int, android.view.KeyEvent)
- */
+ @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch(event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_UP:
diff --git a/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java b/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java
index 6518341c7ac3..53b866c92ef8 100644
--- a/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java
+++ b/core/tests/coretests/src/android/widget/focus/ListOfInternalSelectionViews.java
@@ -17,6 +17,7 @@
package android.widget.focus;
import android.app.Activity;
+import android.graphics.Point;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
@@ -110,7 +111,10 @@ public class ListOfInternalSelectionViews extends Activity {
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
- mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
+
+ Point size = new Point();
+ getWindowManager().getDefaultDisplay().getSize(size);
+ mScreenHeight = size.y;
Bundle extras = getIntent().getExtras();
if (extras != null) {
diff --git a/core/tests/coretests/src/android/widget/focus/RequestFocus.java b/core/tests/coretests/src/android/widget/focus/RequestFocus.java
index af9ee170abe4..21d762a55061 100644
--- a/core/tests/coretests/src/android/widget/focus/RequestFocus.java
+++ b/core/tests/coretests/src/android/widget/focus/RequestFocus.java
@@ -21,9 +21,7 @@ import com.android.frameworks.coretests.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.widget.LinearLayout;
import android.widget.Button;
-import android.view.View;
/**
* Exercises cases where elements of the UI are requestFocus()ed.
diff --git a/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java b/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java
index 909a8c9a845d..baf587e39c1b 100644
--- a/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java
+++ b/core/tests/coretests/src/android/widget/focus/RequestFocusTest.java
@@ -16,21 +16,27 @@
package android.widget.focus;
-import android.widget.focus.RequestFocus;
-import com.android.frameworks.coretests.R;
-
import android.os.Handler;
-import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
-import android.widget.Button;
import android.util.AndroidRuntimeException;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
+import android.widget.Button;
+
+import com.android.frameworks.coretests.R;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* {@link RequestFocusTest} is set up to exercise cases where the views that
* have focus become invisible or GONE.
*/
-public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFocus> {
+public class RequestFocusTest extends ActivityInstrumentationTestCase2<RequestFocus> {
private Button mTopLeftButton;
private Button mBottomLeftButton;
@@ -39,7 +45,7 @@ public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFoc
private Handler mHandler;
public RequestFocusTest() {
- super("com.android.frameworks.coretests", RequestFocus.class);
+ super(RequestFocus.class);
}
@Override
@@ -90,8 +96,149 @@ public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFoc
fail("requestFocus from wrong thread should raise exception.");
} catch (AndroidRuntimeException e) {
// Expected. The actual exception is not public, so we can't catch it.
- assertEquals("android.view.ViewAncestor$CalledFromWrongThreadException",
+ assertEquals("android.view.ViewRootImpl$CalledFromWrongThreadException",
e.getClass().getName());
}
}
+
+ /**
+ * This tests checks the case in which the first focusable View clears focus.
+ * In such a case the framework tries to give the focus to another View starting
+ * from the top. Hence, the framework will try to give focus to the view that
+ * wants to clear its focus. From a client perspective, the view does not loose
+ * focus after the call, therefore no callback for focus change should be invoked.
+ *
+ * @throws Exception If an error occurs.
+ */
+ @UiThreadTest
+ public void testOnFocusChangeNotCalledIfFocusDoesNotMove() throws Exception {
+ // Get the first focusable.
+ Button button = mTopLeftButton;
+
+ // Make sure that the button is the first focusable and focus it.
+ button.getRootView().requestFocus(View.FOCUS_DOWN);
+ assertTrue(button.hasFocus());
+
+ // Attach on focus change listener that should not be called.
+ button.setOnFocusChangeListener(new OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ throw new IllegalStateException("Unexpeced call to"
+ + "OnFocusChangeListener#onFocusChange");
+ }
+ });
+
+ // Attach on global focus change listener that should not be called.
+ button.getViewTreeObserver().addOnGlobalFocusChangeListener(
+ new OnGlobalFocusChangeListener() {
+ @Override
+ public void onGlobalFocusChanged(View oldFocus, View newFocus) {
+ throw new IllegalStateException("Unexpeced call to"
+ + "OnFocusChangeListener#onFocusChange");
+ }
+ });
+
+ // Try to clear focus.
+ button.clearFocus();
+ }
+
+ /**
+ * This tests check whether the on focus change callbacks are invoked in
+ * the proper order when a View loses focus and the framework gives it to
+ * the fist focusable one.
+ *
+ * @throws Exception
+ */
+ @UiThreadTest
+ public void testOnFocusChangeCallbackOrder() throws Exception {
+ // Get the first focusable.
+ Button clearingFocusButton = mTopRightButton;
+ Button gainingFocusButton = mTopLeftButton;
+
+ // Make sure that the clearing focus is not the first focusable.
+ View focusCandidate = clearingFocusButton.getRootView().getParent().focusSearch(null,
+ View.FOCUS_FORWARD);
+ assertNotSame("The clearing focus button is not the first focusable.",
+ clearingFocusButton, focusCandidate);
+ assertSame("The gaining focus button is the first focusable.",
+ gainingFocusButton, focusCandidate);
+
+ // Focus the clearing focus button.
+ clearingFocusButton.requestFocus();
+ assertTrue(clearingFocusButton.hasFocus());
+
+ // Register the invocation order checker.
+ CallbackOrderChecker checker = new CallbackOrderChecker(clearingFocusButton,
+ gainingFocusButton);
+ clearingFocusButton.setOnFocusChangeListener(checker);
+ gainingFocusButton.setOnFocusChangeListener(checker);
+ clearingFocusButton.getViewTreeObserver().addOnGlobalFocusChangeListener(checker);
+
+ // Try to clear focus.
+ clearingFocusButton.clearFocus();
+
+ // Check that no callback was invoked since focus did not move.
+ checker.verify();
+ }
+
+ /**
+ * This class check whether the focus change callback are invoked in order.
+ */
+ private class CallbackOrderChecker implements OnFocusChangeListener,
+ OnGlobalFocusChangeListener {
+
+ private class CallbackInvocation {
+ final String mMethodName;
+ final Object[] mArguments;
+
+ CallbackInvocation(String methodName, Object[] arguments) {
+ mMethodName = methodName;
+ mArguments = arguments;
+ }
+ }
+
+ private final View mClearingFocusView;
+ private final View mGainingFocusView;
+
+ private final List<CallbackInvocation> mInvocations = new ArrayList<CallbackInvocation>();
+
+ public CallbackOrderChecker(View clearingFocusView, View gainingFocusView) {
+ mClearingFocusView = clearingFocusView;
+ mGainingFocusView = gainingFocusView;
+ }
+
+ @Override
+ public void onFocusChange(View view, boolean hasFocus) {
+ CallbackInvocation invocation = new CallbackInvocation(
+ "OnFocusChangeListener#onFocusChange", new Object[] {view, hasFocus});
+ mInvocations.add(invocation);
+ }
+
+ @Override
+ public void onGlobalFocusChanged(View oldFocus, View newFocus) {
+ CallbackInvocation invocation = new CallbackInvocation(
+ "OnFocusChangeListener#onFocusChange", new Object[] {oldFocus, newFocus});
+ mInvocations.add(invocation);
+ }
+
+ public void verify() {
+ assertSame("All focus change callback should be invoked.", 3, mInvocations.size());
+ assertInvioked("Callback for View clearing focus explected.", 0,
+ "OnFocusChangeListener#onFocusChange",
+ new Object[] {mClearingFocusView, false});
+ assertInvioked("Callback for View global focus change explected.", 1,
+ "OnFocusChangeListener#onFocusChange", new Object[] {mClearingFocusView,
+ mGainingFocusView});
+ assertInvioked("Callback for View gaining focus explected.", 2,
+ "OnFocusChangeListener#onFocusChange", new Object[] {mGainingFocusView, true});
+ }
+
+ private void assertInvioked(String message, int order, String methodName,
+ Object[] arguments) {
+ CallbackInvocation invocation = mInvocations.get(order);
+ assertEquals(message, methodName, invocation.mMethodName);
+ assertEquals(message, arguments[0], invocation.mArguments[0]);
+ assertEquals(message, arguments[1], invocation.mArguments[1]);
+ }
+ }
}
diff --git a/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java b/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java
index eb9192a43c13..795e09ca0c60 100644
--- a/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java
+++ b/core/tests/coretests/src/android/widget/focus/ScrollingThroughListOfFocusablesTest.java
@@ -20,10 +20,9 @@ import android.graphics.Rect;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.util.InternalSelectionView;
import android.view.KeyEvent;
import android.widget.ListView;
-import android.widget.focus.ListOfInternalSelectionViews;
-import android.util.InternalSelectionView;
/**
@@ -51,6 +50,10 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
mNumRowsPerItem, // 5 internally selectable rows per item
mScreenHeightFactor)); // each item is 5 / 4 screen height tall
mListView = mActivity.getListView();
+ // Make sure we have some fading edge regardless of ListView style.
+ mListView.setVerticalFadingEdgeEnabled(true);
+ mListView.setFadingEdgeLength(10);
+ ensureNotInTouchMode();
}
@Override
@@ -67,12 +70,12 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
assertEquals(mNumRowsPerItem, mActivity.getNumRowsPerItem());
}
- // TODO: needs to be adjusted to pass on non-HVGA displays
- // @MediumTest
+ @MediumTest
public void testScrollingDownInFirstItem() throws Exception {
for (int i = 0; i < mNumRowsPerItem; i++) {
assertEquals(0, mListView.getSelectedItemPosition());
+
InternalSelectionView view = mActivity.getSelectedView();
assertInternallySelectedRowOnScreen(view, i);
@@ -90,13 +93,12 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
mListView.getSelectedView();
// 1 pixel tolerance in case height / 4 is not an even number
- final int fadingEdge = mListView.getBottom() - mListView.getVerticalFadingEdgeLength();
+ final int bottomFadingEdgeTop =
+ mListView.getBottom() - mListView.getVerticalFadingEdgeLength();
assertTrue("bottom of view should be just above fading edge",
- view.getBottom() >= fadingEdge - 1 &&
- view.getBottom() <= fadingEdge);
+ view.getBottom() == bottomFadingEdgeTop);
}
-
// make sure fading edge is the expected view
{
assertEquals("should be a second view visible due to the fading edge",
@@ -109,7 +111,6 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
}
}
-
@MediumTest
public void testScrollingToSecondItem() throws Exception {
@@ -223,4 +224,12 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
assertTrue("bottom of row " + row + " should be on sreen",
mTempRect.bottom < mActivity.getScreenHeight());
}
+
+ private void ensureNotInTouchMode() {
+ // If in touch mode inject a DPAD down event to exit that mode.
+ if (mListView.isInTouchMode()) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+ }
+ }
}
diff --git a/docs/html/design/get-started/ui-overview.html b/docs/html/design/get-started/ui-overview.html
index b08c7430827b..bd5ff9c84bac 100644
--- a/docs/html/design/get-started/ui-overview.html
+++ b/docs/html/design/get-started/ui-overview.html
@@ -153,12 +153,12 @@ recently used app at the bottom.</p>
</div>
</div>
-<h2>UI Bars</h2>
+<h2>System Bars</h2>
-<p>The UI bars are screen areas dedicated to the display of notifications, communication of device
-status, and device navigation. Typically the UI bars are displayed concurrently with your app. Apps
-that display immersive content, such as movies or images, can temporarily hide the UI bars to allow
-the user to enjoy full screen content without distraction.</p>
+<p>The system bars are screen areas dedicated to the display of notifications, communication of device
+status, and device navigation. Typically the system bars are displayed concurrently with your app.
+Apps that display immersive content, such as movies or images, can temporarily hide the system bars
+to allow the user to enjoy full screen content without distraction.</p>
<img src="../static/content/ui_overview_system_ui.png">
@@ -177,8 +177,9 @@ the user to enjoy full screen content without distraction.</p>
Recents, and also displays a menu for apps written for Android 2.3 or earlier.</p>
</li>
<li>
-<h4>System Bar</h4>
-<p>Combines the status and navigation bars for display on tablet form factors.</p>
+<h4>Combined Bar</h4>
+<p>On tablet form factors the status and navigation bars are combined into a single bar at the
+ bottom of the screen.</p>
</li>
</ol>
diff --git a/docs/html/design/patterns/actionbar.html b/docs/html/design/patterns/actionbar.html
index 99ae2d75ee73..911c549df7db 100644
--- a/docs/html/design/patterns/actionbar.html
+++ b/docs/html/design/patterns/actionbar.html
@@ -133,7 +133,7 @@ The app icon establishes your app's identity. It can be replaced with a differen
you wish.
Important: If the app is currently not displaying the top-level screen, be sure to display the Up
caret to the left of the app icon, so the user can navigate up the hierarchy. For more discussion of
-Up navigation, see the "Navigation" pattern.
+Up navigation, see the <a href="../patterns/navigation.html">Navigation</a> pattern.
<div class="figure">
<img src="../static/content/action_bar_pattern_up_app_icon.png">
@@ -369,6 +369,22 @@ action overflow.</p>
<p>If either F, I, or T apply, then it's appropriate for the action bar. Otherwise, it belongs in the
action overflow.</p>
+<p>
+
+Pre-defined glyphs should be used for certain common actions such as "refresh" and "share." The
+download link below provides a package with icons that are scaled for various screen densities and
+are suitable for use with the Holo Light and Holo Dark themes. The package also includes unstyled
+icons that you can modify to match your theme, in addition to Adobe&reg; Illustrator&reg; source
+files for further customization.
+
+</p>
+<p>
+
+<a href="../static/download/action_bar_icons-v4.0.zip">Download the Action Bar Icon
+Pack</a>
+
+</p>
+
<div class="layout-content-row">
<div class="layout-content-col span-6">
diff --git a/docs/html/design/patterns/app-structure.html b/docs/html/design/patterns/app-structure.html
index b87f4021879e..fb9205b4bf81 100644
--- a/docs/html/design/patterns/app-structure.html
+++ b/docs/html/design/patterns/app-structure.html
@@ -159,9 +159,9 @@ layouts that are visually engaging and appropriate for the data type and screen
<img src="../static/content/app_structure_market.png">
<div class="figure-caption">
- Market's start screen primarily allows navigation into the stores for Apps, Music, Books, and
- Games. It is also enriched with tailored recommendations and promotions that surface content
- of interest to the user. Search is readily available from the action bar.
+ Market's start screen primarily allows navigation into the stores for Apps, Music, Books,
+ Movies and Games. It is also enriched with tailored recommendations and promotions that
+ surface content of interest to the user. Search is readily available from the action bar.
</div>
</div>
diff --git a/docs/html/design/patterns/navigation.html b/docs/html/design/patterns/navigation.html
index aabfc39c8373..cad36828ada6 100644
--- a/docs/html/design/patterns/navigation.html
+++ b/docs/html/design/patterns/navigation.html
@@ -131,7 +131,7 @@ return the user to the Home screen, or even to a different application.</p>
<p>The Back key also supports a few behaviors not directly tied to screen-to-screen navigation:</p>
<ul>
<li>Back dismisses floating windows (dialogs, popups)</li>
-<li>Back dismisses contextual action bars, and remove highlight from selected items</li>
+<li>Back dismisses contextual action bars, and removes the highlight from the selected items</li>
<li>Back hides the onscreen keyboard (IME)</li>
</ul>
<h2>Navigation Within Your App</h2>
@@ -189,18 +189,19 @@ screen widget can bypass the Inbox screen, taking the user directly to a convers
<h4>App-to-app navigation</h4>
<p>When navigating deep into your app's hierarchy directly from another app via an intent, Back will
return to the referring app.</p>
-<p>The Up button is handled is follows:
+<p>The Up button is handled as follows:
- If the destination screen is typically reached from one particular screen within your app, Up
should navigate to that screen.
- Otherwise, Up should navigate to the topmost ("Home") screen of your app.</p>
-<p>For example, after choosing to share a book being view in Market, the user navigates directly to the
-Gmail's compose screen. From there, Up returns to the Inbox (which happens to be both the typical
-referrer to compose, as well as the topmost screen of the app), while Back returns to Market.</p>
+<p>For example, after choosing to share a book being viewed in Market, the user navigates directly to
+Gmail's compose screen. From there, Up returns to the Inbox (which happens to be both the
+typical referrer to compose, as well as the topmost screen of the app), while Back returns to
+Market.</p>
<img src="../static/content/navigation_from_outside_up.png">
<h4>System-to-app navigation</h4>
-<p>If the your app was reached via the system mechanisms of notifications or home screen widgets, Up
+<p>If your app was reached via the system mechanisms of notifications or home screen widgets, Up
behaves as described for app-to-app navigation, above.</p>
<p>For the Back key, you should make navigation more predictably by inserting into the task's back
stack the complete upward navigation path to the app's topmost screen. This way, a user who has
diff --git a/docs/html/design/patterns/notifications.html b/docs/html/design/patterns/notifications.html
index acec30647263..c5045aed9e77 100644
--- a/docs/html/design/patterns/notifications.html
+++ b/docs/html/design/patterns/notifications.html
@@ -200,7 +200,7 @@ stacked (see <em>Stacked notifications</em> below) and references multiple items
the user is taken to a hierarchy level below your app's top-level, insert navigation into your app's
back stack to allow them to navigate to your app's top level using the system back key. For more
information, see the chapter on <em>System-to-app navigation</em> in the
-<a href="../patterns/notifications.html">Navigation</a> design pattern.</p>
+<a href="../patterns/navigation.html">Navigation</a> design pattern.</p>
<h4>Timestamps for time sensitive events</h4>
<p>By default, standard Android notifications include a timestamp in the upper right corner. Consider
whether the timestamp is valuable in the context of your notification. If the timestamp is not
diff --git a/docs/html/design/static/download/action_bar_icons-v4.0.zip b/docs/html/design/static/download/action_bar_icons-v4.0.zip
new file mode 100644
index 000000000000..456889405687
--- /dev/null
+++ b/docs/html/design/static/download/action_bar_icons-v4.0.zip
Binary files differ
diff --git a/docs/html/design/style/iconography.html b/docs/html/design/style/iconography.html
index 663770b6933d..5d5d200af75e 100644
--- a/docs/html/design/style/iconography.html
+++ b/docs/html/design/style/iconography.html
@@ -193,10 +193,28 @@ from above, so that users perceive some depth.</p>
<h2 id="actionbar">Action Bar</h2>
-<p>Action bar icons are graphic buttons that represent the most important actions people can take
+<p>
+
+Action bar icons are graphic buttons that represent the most important actions people can take
within your app. Each one should employ a simple metaphor representing a single concept that most
-people can grasp at a glance.</p>
+people can grasp at a glance.
+
+</p>
+<p>
+
+Pre-defined glyphs should be used for certain common actions such as "refresh" and "share." The
+download link below provides a package with icons that are scaled for various screen densities and
+are suitable for use with the Holo Light and Holo Dark themes. The package also includes unstyled
+icons that you can modify to match your theme, in addition to Adobe&reg; Illustrator&reg; source
+files for further customization.
+
+</p>
+<p>
+
+<a href="../static/download/action_bar_icons-v4.0.zip">Download the Action Bar Icon
+Pack</a>
+</p>
<div class="layout-content-row">
<div class="layout-content-col span-4">
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 07b9370d6740..d9b2155f8e46 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -165,10 +165,10 @@ default.</li>
<p><strong>Example 1</strong><br />
The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"&gt;</code>
- and does not does not include a <code>&lt;supports-screens&gt;</code> element.
- <strong>Result</strong>: Android Market will not show the app to a user of a
- small-screen device, but will show it to users of normal and large-screen
- devices, users, unless other filters apply. </p>
+ and does not include a <code>&lt;supports-screens&gt;</code> element.
+ <strong>Result</strong>: Android Market does not show the app to a user of a
+ small-screen device, but does show it to users of normal and large-screen
+ devices, unless other filters also exclude those devices. </p>
<p><strong>Example 2<br />
</strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"
android:targetSdkVersion="4"&gt;</code> and does not include a
diff --git a/docs/html/guide/developing/device.jd b/docs/html/guide/developing/device.jd
index c4d08edd6b73..e46d07c86df2 100644
--- a/docs/html/guide/developing/device.jd
+++ b/docs/html/guide/developing/device.jd
@@ -154,6 +154,14 @@ above.</p>
<td><code>0489</code></td>
</tr>
<tr>
+ <td>Fujitsu</td>
+ <td><code>04C5</code></td>
+ </tr>
+ <tr>
+ <td>Fujitsu Toshiba</td>
+ <td><code>04C5</code></td>
+ </tr>
+ <tr>
<td>Garmin-Asus</td>
<td><code>091E</code></td>
</tr>
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index ee4c48ecd846..4a9a6848632a 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -8,15 +8,16 @@
<ul>
<li>
- <h2><span class="en">Android Basics</span>
- <span class="de" style="display:none">Einführung in Android</span>
- <span class="es" style="display:none">Información básica sobre Android</span>
- <span class="fr" style="display:none">Présentation d'Android</span>
- <span class="it" style="display:none">Nozioni di base su Android</span>
- <span class="ja" style="display:none">Android の基本</span>
- <span class="zh-CN" style="display:none">Android 基础知识</span>
- <span class="zh-TW" style="display:none">Android 簡介</span>
- </h2>
+ <span class="heading">
+ <span class="en">Android Basics</span>
+ <span class="de" style="display:none">Einführung in Android</span>
+ <span class="es" style="display:none">Información básica sobre Android</span>
+ <span class="fr" style="display:none">Présentation d'Android</span>
+ <span class="it" style="display:none">Nozioni di base su Android</span>
+ <span class="ja" style="display:none">Android の基本</span>
+ <span class="zh-CN" style="display:none">Android 基础知识</span>
+ <span class="zh-TW" style="display:none">Android 簡介</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>guide/basics/what-is-android.html">
<span class="en">What Is Android?</span>
@@ -46,7 +47,7 @@
</li>
<li>
- <h2>
+ <span class="heading">
<span class="en">Framework Topics</span>
<span class="de" style="display:none">Framework-Themen</span>
<span class="es" style="display:none">Temas sobre el framework</span>
@@ -55,7 +56,7 @@
<span class="ja" style="display:none">フレームワーク トピック</span>
<span class="zh-CN" style="display:none">框架主题</span>
<span class="zh-TW" style="display:none">架構主題</span>
- </h2>
+ </span>
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/fundamentals/activities.html">
@@ -87,10 +88,24 @@
<span class="en">Content Providers</span>
</a></div>
<ul>
- <li><a href="<?cs var:toroot ?>guide/topics/providers/calendar-provider.html">
- <span class="en">Calendar Provider</span></a>
- <span class="new">new!</span>
- </li>
+ <li>
+ <a href="<?cs var:toroot ?>guide/topics/providers/content-provider-basics.html">
+ <span class="en">Content Provider Basics</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>guide/topics/providers/content-provider-creating.html">
+ <span class="en">Creating a Content Provider</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
+ <li>
+ <a href="<?cs var:toroot ?>guide/topics/providers/calendar-provider.html">
+ <span class="en">Calendar Provider</span>
+ </a>
+ <span class="new">new!</span>
+ </li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/intents/intents-filters.html">
@@ -116,7 +131,7 @@
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html">
<span class="en">Menus</span>
- </a></li>
+ </a> <span class="new">updated</span></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
<span class="en">Action Bar</span>
</a></li>
@@ -429,9 +444,9 @@
</li>
<li>
- <h2>
+ <span class="heading">
<span class="en">Android Market Topics</span>
- </h2>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>guide/publishing/publishing.html">
<span class="en">Publishing on Android Market</span>
@@ -475,15 +490,16 @@
<li>
- <h2><span class="en">Developing</span>
- <span class="de" style="display:none">Entwicklung</span>
- <span class="es" style="display:none">Desarrollo</span>
- <span class="fr" style="display:none">Développement</span>
- <span class="it" style="display:none">Sviluppo</span>
- <span class="ja" style="display:none">開発</span>
- <span class="zh-CN" style="display:none">开发</span>
- <span class="zh-TW" style="display:none">開發</span>
- </h2>
+ <span class="heading">
+ <span class="en">Developing</span>
+ <span class="de" style="display:none">Entwicklung</span>
+ <span class="es" style="display:none">Desarrollo</span>
+ <span class="fr" style="display:none">Développement</span>
+ <span class="it" style="display:none">Sviluppo</span>
+ <span class="ja" style="display:none">開発</span>
+ <span class="zh-CN" style="display:none">开发</span>
+ <span class="zh-TW" style="display:none">開發</span>
+ </span>
<ul>
<!--<li><a href="">Developing for Android</a></li>
signing, upgrading, selecting a package name, select device profile, touch, trackball, dpad available, etc. -->
@@ -669,15 +685,16 @@
</li>
<li>
- <h2><span class="en">Publishing</span>
- <span class="de" style="display:none">Veröffentlichung</span>
- <span class="es" style="display:none">Publicación</span>
- <span class="fr" style="display:none">Publication</span>
- <span class="it" style="display:none">Pubblicazione</span>
- <span class="ja" style="display:none">公開</span>
- <span class="zh-CN" style="display:none">发布</span>
- <span class="zh-TW" style="display:none">發佈</span>
- </h2>
+ <span class="heading">
+ <span class="en">Publishing</span>
+ <span class="de" style="display:none">Veröffentlichung</span>
+ <span class="es" style="display:none">Publicación</span>
+ <span class="fr" style="display:none">Publication</span>
+ <span class="it" style="display:none">Pubblicazione</span>
+ <span class="ja" style="display:none">公開</span>
+ <span class="zh-CN" style="display:none">发布</span>
+ <span class="zh-TW" style="display:none">發佈</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>guide/publishing/publishing_overview.html">
<span class="en">Publishing Overview</span>
@@ -719,15 +736,16 @@ applications</span>
</li>
<li>
- <h2><span class="en">Best Practices</span>
- <span class="de" style="display:none">Bewährte Verfahren</span>
- <span class="es" style="display:none">Prácticas recomendadas</span>
- <span class="fr" style="display:none">Meilleures pratiques</span>
- <span class="it" style="display:none">Best practice</span>
- <span class="ja" style="display:none">ベスト プラクティス</span>
- <span class="zh-CN" style="display:none">最佳实践</span>
- <span class="zh-TW" style="display:none">最佳實務</span>
- </h2>
+ <span class="heading">
+ <span class="en">Best Practices</span>
+ <span class="de" style="display:none">Bewährte Verfahren</span>
+ <span class="es" style="display:none">Prácticas recomendadas</span>
+ <span class="fr" style="display:none">Meilleures pratiques</span>
+ <span class="it" style="display:none">Best practice</span>
+ <span class="ja" style="display:none">ベスト プラクティス</span>
+ <span class="zh-CN" style="display:none">最佳实践</span>
+ <span class="zh-TW" style="display:none">最佳實務</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>guide/practices/compatibility.html">
<span class="en">Compatibility</span>
@@ -823,8 +841,9 @@ applications</span>
</li>
<li>
- <h2><span class="en">Web Applications</span>
- </h2>
+ <span class="heading">
+ <span class="en">Web Applications</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>guide/webapps/index.html">
<span class="en">Web Apps Overview</span>
@@ -845,15 +864,16 @@ applications</span>
</li>
<li>
- <h2><span class="en">Appendix</span>
- <span class="de" style="display:none">Anhang</span>
- <span class="es" style="display:none">Apéndice</span>
- <span class="fr" style="display:none">Annexes</span>
- <span class="it" style="display:none">Appendice</span>
- <span class="ja" style="display:none">付録</span>
- <span class="zh-CN" style="display:none">附录</span>
- <span class="zh-TW" style="display:none">附錄</span>
- </h2>
+ <span class="heading">
+ <span class="en">Appendix</span>
+ <span class="de" style="display:none">Anhang</span>
+ <span class="es" style="display:none">Apéndice</span>
+ <span class="fr" style="display:none">Annexes</span>
+ <span class="it" style="display:none">Appendice</span>
+ <span class="ja" style="display:none">付録</span>
+ <span class="zh-CN" style="display:none">附录</span>
+ <span class="zh-TW" style="display:none">附錄</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>guide/appendix/api-levels.html">
<span class="en">Android API Levels</span>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 96aecf5b868b..1c6618576f13 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -42,8 +42,6 @@ Templates Pack, v4.0 &raquo;</a></li>
Templates Pack, v2.3 &raquo;</a></li>
<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
Templates Pack, v2.0 &raquo;</a></li>
-<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
-Templates Pack, v1.0 &raquo;</a></li>
</ol>
<h2>See also</h2>
diff --git a/docs/html/guide/topics/providers/content-provider-basics.jd b/docs/html/guide/topics/providers/content-provider-basics.jd
new file mode 100644
index 000000000000..40b5c3fd4c7b
--- /dev/null
+++ b/docs/html/guide/topics/providers/content-provider-basics.jd
@@ -0,0 +1,1215 @@
+page.title=Content Provider Basics
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+
+ <!-- In this document -->
+<h2>In this document</h2>
+<ol>
+ <li>
+ <a href="#Basics">Overview</a>
+ <ol>
+ <li>
+ <a href="#ClientProvider">Accessing a provider</a>
+ </li>
+ <li>
+ <a href="#ContentURIs">Content URIs</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#SimpleQuery">Retrieving Data from the Provider</a>
+ <ol>
+ <li>
+ <a href="#RequestPermissions">Requesting read access permission</a>
+ </li>
+ <li>
+ <a href="#Query">Constructing the query</a>
+ </li>
+ <li>
+ <a href="#DisplayResults">Displaying query results</a>
+ </li>
+ <li>
+ <a href="#GettingResults">Getting data from query results</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#Permissions">Content Provider Permissions</a>
+ </li>
+ <li>
+ <a href="#Modifications">Inserting, Updating, and Deleting Data</a>
+ <ol>
+ <li>
+ <a href="#Inserting">Inserting data</a>
+ </li>
+ <li>
+ <a href="#Updating">Updating data</a>
+ </li>
+ <li>
+ <a href="#Deleting">Deleting data</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#DataTypes">Provider Data Types</a>
+ </li>
+ <li>
+ <a href="#AltForms">Alternative Forms of Provider Access</a>
+ <ol>
+ <li>
+ <a href="#Batch">Batch access</a>
+ </li>
+ <li>
+ <a href="#Intents">Data access via intents</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#ContractClasses">Contract Classes</a>
+ </li>
+ <li>
+ <a href="#MIMETypeReference">MIME Type Reference</a>
+ </li>
+</ol>
+
+ <!-- Key Classes -->
+<h2>Key classes</h2>
+ <ol>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.content.ContentResolver}
+ </li>
+ <li>
+ {@link android.database.Cursor}
+ </li>
+ <li>
+ {@link android.net.Uri}
+ </li>
+ </ol>
+
+ <!-- Related Samples -->
+<h2>Related Samples</h2>
+ <ol>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ Cursor (People)</a>
+ </li>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ Cursor (Phones)</a>
+ </li>
+ </ol>
+
+ <!-- See also -->
+<h2>See also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Creating a Content Provider</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Calendar Provider</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+ <!-- Intro paragraphs -->
+<p>
+ A content provider manages access to a central repository of data. The provider and
+ is part of an Android application, which often provides its own UI for working with
+ the data. However, content providers are primarily intended to be used by other
+ applications, which access the provider using a provider client object. Together, providers
+ and provider clients offer a consistent, standard interface to data that also handles
+ inter-process communication and secure data access.
+</p>
+<p>
+ This topic describes the basics of the following:
+</p>
+ <ul>
+ <li>How content providers work.</li>
+ <li>The API you use retrieve data from a content provider.</li>
+ <li>The API you use to insert, update, or delete data in a content provider.</li>
+ <li>Other API features that facilitate working with providers.</li>
+ </ul>
+
+ <!-- Basics -->
+<h2 id="Basics">Overview</h2>
+<p>
+ A content provider presents data to external applications as one or more tables that are
+ similar to the tables found in a relational database. A row represents an instance of some type
+ of data the provider collects, and each row in the column represents an individual piece of
+ data collected for an instance.
+</p>
+<p>
+ For example, one of the built-in providers in the Android platform is the user dictionary, which
+ stores the spellings of non-standard words that the user wants to keep. Table 1 illustrates what
+ the data might look like in this provider's table:
+</p>
+<p class="table-caption">
+ <strong>Table 1:</strong> Sample user dictionary table.
+</p>
+<table id="table1" style="width: 50%;">
+ <tr>
+ <th style="width:20%" align="center" scope="col">word</th>
+ <th style="width:20%" align="center" scope="col">app id</th>
+ <th style="width:20%" align="center" scope="col">frequency</th>
+ <th style="width:20%" align="center" scope="col">locale</th>
+ <th style="width:20%" align="center" scope="col">_ID</th>
+ </tr>
+ <tr>
+ <td align="center" scope="row">mapreduce</td>
+ <td align="center">user1</td>
+ <td align="center">100</td>
+ <td align="center">en_US</td>
+ <td align="center">1</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">precompiler</td>
+ <td align="center">user14</td>
+ <td align="center">200</td>
+ <td align="center">fr_FR</td>
+ <td align="center">2</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">applet</td>
+ <td align="center">user2</td>
+ <td align="center">225</td>
+ <td align="center">fr_CA</td>
+ <td align="center">3</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">const</td>
+ <td align="center">user1</td>
+ <td align="center">255</td>
+ <td align="center">pt_BR</td>
+ <td align="center">4</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">int</td>
+ <td align="center">user5</td>
+ <td align="center">100</td>
+ <td align="center">en_UK</td>
+ <td align="center">5</td>
+ </tr>
+</table>
+<p>
+ In table 1, each row represents an instance of a word that might not be
+ found in a standard dictionary. Each column represents some data for that word, such as the
+ locale in which it was first encountered. The column headers are column names that are stored in
+ the provider. To refer to a row's locale, you refer to its <code>locale</code> column. For
+ this provider, the <code>_ID</code> column serves as a "primary key" column that
+ the provider automatically maintains.
+</p>
+<p class="note">
+ <strong>Note:</strong> A provider isn't required to have a primary key, and it isn't required
+ to use <code>_ID</code> as the column name of a primary key if one is present. However,
+ if you want to bind data from a provider to a {@link android.widget.ListView}, one of the
+ column names has to be <code>_ID</code>. This requirement is explained in more detail in the
+ section <a href="#DisplayResults">Displaying query results</a>.
+</p>
+<h3 id="ClientProvider">Accessing a provider</h3>
+<p>
+ An application accesses the data from a content provider with
+ a {@link android.content.ContentResolver} client object. This object has methods that call
+ identically-named methods in the provider object, an instance of one of the concrete
+ subclasses of {@link android.content.ContentProvider}. The
+ {@link android.content.ContentResolver} methods provide the basic
+ "CRUD" (create, retrieve, update, and delete) functions of persistent storage.
+</p>
+<p>
+ The {@link android.content.ContentResolver} object in the client application's
+ process and the {@link android.content.ContentProvider} object in the application that owns
+ the provider automatically handle inter-process communication.
+ {@link android.content.ContentProvider} also acts as an abstraction layer between its
+ repository of data and the external appearance of data as tables.
+</p>
+<p class="note">
+ <strong>Note:</strong> To access a provider, your application usually has to request specific
+ permissions in its manifest file. This is described in more detail in the section
+ <a href="#Permissions">Content Provider Permissions</a>
+</p>
+<p>
+ For example, to get a list of the words and their locales from the User Dictionary Provider,
+ you call {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ ContentResolver.query()}.
+ The {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ query()} method calls the
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ ContentProvider.query()} method defined by the User Dictionary Provider. The following lines
+ of code show a
+ {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ ContentResolver.query()} call:
+<p>
+<pre>
+// Queries the user dictionary and returns results
+mCursor = getContentResolver().query(
+ UserDictionary.Words.CONTENT_URI, // The content URI of the words table
+ mProjection, // The columns to return for each row
+ mSelectionClause // Selection criteria
+ mSelectionArgs, // Selection criteria
+ mSortOrder); // The sort order for the returned rows
+</pre>
+<p>
+ Table 2 shows how the arguments to
+ {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ query(Uri,projection,selection,selectionArgs,sortOrder)} match an SQL SELECT statement:
+</p>
+<p class="table-caption">
+ <strong>Table 2:</strong> Query() compared to SQL query.
+</p>
+<table id="table2" style="width: 75%;">
+ <tr>
+ <th style="width:25%" align="center" scope="col">query() argument</th>
+ <th style="width:25%" align="center" scope="col">SELECT keyword/parameter</th>
+ <th style="width:50%" align="center" scope="col">Notes</th>
+ </tr>
+ <tr>
+ <td align="center"><code>Uri</code></td>
+ <td align="center"><code>FROM <em>table_name</em></code></td>
+ <td><code>Uri</code> maps to the table in the provider named <em>table_name</em>.</td>
+ </tr>
+ <tr>
+ <td align="center"><code>projection</code></td>
+ <td align="center"><code><em>col,col,col,...</em></code></td>
+ <td>
+ <code>projection</code> is an array of columns that should be included for each row
+ retrieved.
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><code>selection</code></td>
+ <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td>
+ <td><code>selection</code> specifies the criteria for selecting rows.</td>
+ </tr>
+ <tr>
+ <td align="center"><code>selectionArgs</code></td>
+ <td align="center">
+ (No exact equivalent. Selection arguments replace <code>?</code> placeholders in the
+ selection clause.)
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><code>sortOrder</code></td>
+ <td align="center"><code>ORDER BY <em>col,col,...</em></code></td>
+ <td>
+ <code>sortOrder</code> specifies the order in which rows appear in the returned
+ {@link android.database.Cursor}.
+ </td>
+ </tr>
+</table>
+<h3 id="ContentURIs">Content URIs</h3>
+<p>
+ A <strong>content URI</strong> is a URI that identifies data in a provider. Content URIs
+ include the symbolic name of the entire provider (its <strong>authority</strong>) and a
+ name that points to a table (a <strong>path</strong>). When you call
+ a client method to access a table in a provider, the content URI for the table is one of
+ the arguments.
+</p>
+<p>
+ In the preceding lines of code, the constant
+ {@link android.provider.UserDictionary.Words#CONTENT_URI} contains the content URI of
+ the user dictionary's "words" table. The {@link android.content.ContentResolver}
+ object parses out the URI's authority, and uses it to "resolve" the provider by
+ comparing the authority to a system table of known providers. The
+ {@link android.content.ContentResolver} can then dispatch the query arguments to the correct
+ provider.
+</p>
+<p>
+ The {@link android.content.ContentProvider} uses the path part of the content URI to choose the
+ table to access. A provider usually has a <strong>path</strong> for each table it exposes.
+</p>
+<p>
+ In the previous lines of code, the full URI for the "words" table is:
+</p>
+<pre>
+content://user_dictionary/words
+</pre>
+<p>
+ where the <code>user_dictionary</code> string is the provider's authority, and
+ <code>words</code> string is the table's path. The string
+ <code>content://</code> (the <strong>scheme</strong>) is always present,
+ and identifies this as a content URI.
+</p>
+<p>
+ Many providers allow you to access a single row in a table by appending an ID value
+ to the end of the URI. For example, to retrieve a row whose <code>_ID</code> is
+ <code>4</code> from user dictionary, you can use this content URI:
+</p>
+<pre>
+Uri singleUri = ContentUri.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
+</pre>
+<p>
+ You often use id values when you've retrieved a set of rows and then want to update or delete
+ one of them.
+</p>
+<p class="note">
+ <strong>Note:</strong> The {@link android.net.Uri} and {@link android.net.Uri.Builder} classes
+ contain convenience methods for constructing well-formed Uri objects from strings. The
+ {@link android.content.ContentUris} contains convenience methods for appending id values to
+ a URI. The previous snippet uses {@link android.content.ContentUris#withAppendedId(Uri, long)
+ withAppendedId()} to append an id to the UserDictionary content URI.
+</p>
+
+
+ <!-- Retrieving Data from the Provider -->
+<h2 id="SimpleQuery">Retrieving Data from the Provider</h2>
+<p>
+ This section describes how to retrieve data from a provider, using the User Dictionary Provider
+ as an example.
+</p>
+<p class="note">
+ For the sake of clarity, the code snippets in this section call
+ {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ ContentResolver.query()} on the "UI thread"". In actual code, however, you should
+ do queries asynchronously on a separate thread. One way to do this is to use the
+ {@link android.content.CursorLoader} class, which is described
+ in more detail in the <a href="{@docRoot}guide/topics/fundamentals/loaders.html">
+ Loaders</a> guide. Also, the lines of code are snippets only; they don't show a complete
+ application.
+</p>
+<p>
+ To retrieve data from a provider, follow these basic steps:
+</p>
+<ol>
+ <li>
+ Request the read access permission for the provider.
+ </li>
+ <li>
+ Define the code that sends a query to the provider.
+ </li>
+</ol>
+<h3 id="RequestPermissions">Requesting read access permission</h3>
+<p>
+ To retrieve data from a provider, your application needs "read access permission" for the
+ provider. You can't request this permission at run-time; instead, you have to specify that
+ you need this permission in your manifest, using the
+ <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> element and the exact permission name defined by the
+ provider. When you specify this element in your manifest, you are in effect "requesting" this
+ permission for your application. When users install your application, they implicitly grant
+ this request.
+</p>
+<p>
+ To find the exact name of the read access permission for the provider you're using, as well
+ as the names for other access permissions used by the provider, look in the provider's
+ documentation.
+</p>
+<p>
+ The role of permissions in accessing providers is described in more detail in the section
+ <a href="#Permissions">Content Provider Permissions</a>.
+</p>
+<p>
+ The User Dictionary Provider defines the permission
+ <code>android.permission.READ_USER_DICTIONARY</code> in its manifest file, so an
+ application that wants to read from the provider must request this permission.
+</p>
+<!-- Constructing the query -->
+<h3 id="Query">Constructing the query</h3>
+<p>
+ The next step in retrieving data a provider is to construct a query. This first snippet
+ defines some variables for accessing the User Dictionary Provider:
+</p>
+<pre class="prettyprint">
+
+// A "projection" defines the columns that will be returned for each row
+String[] mProjection =
+{
+ UserDictionary.Words._ID, // Contract class constant for the _ID column name
+ UserDictionary.Words.WORD, // Contract class constant for the word column name
+ UserDictionary.Words.LOCALE // Contract class constant for the locale column name
+};
+
+// Defines a string to contain the selection clause
+String mSelectionClause = null;
+
+// Initializes an array to contain selection arguments
+String[] mSelectionArgs = {""};
+
+</pre>
+<p>
+ The next snippet shows how to use
+ {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ ContentResolver.query()}, using the User Dictionary Provider as an example.
+ A provider client query is similar to an SQL query, and it contains a set of columns to return,
+ a set of selection criteria, and a sort order.
+</p>
+<p>
+ The set of columns that the query should return is called a <strong>projection</strong>
+ (the variable <code>mProjection</code>).
+</p>
+<p>
+ The expression that specifies the rows to retrieve is split into a selection clause and
+ selection arguments. The selection clause is a combination of logical and Boolean expressions,
+ column names, and values (the variable <code>mSelection</code>). If you specify the replaceable
+ parameter <code>?</code> instead of a value, the query method retrieves the value from the
+ selection arguments array (the variable <code>mSelectionArgs</code>).
+</p>
+<p>
+ In the next snippet, if the user doesn't enter a word, the selection clause is set to
+ <code>null</code>, and the query returns all the words in the provider. If the user enters
+ a word, the selection clause is set to <code>UserDictionary.Words.Word + " = ?"</code> and
+ the first element of selection arguments array is set to the word the user enters.
+</p>
+<pre class="prettyprint">
+/*
+ * This defines a one-element String array to contain the selection argument.
+ */
+String[] mSelectionArgs = {""};
+
+// Gets a word from the UI
+mSearchString = mSearchWord.getText().toString();
+
+// Remember to insert code here to check for invalid or malicious input.
+
+// If the word is the empty string, gets everything
+if (TextUtils.isEmpty(mSearchString)) {
+ // Setting the selection clause to null will return all words
+ mSelectionClause = null;
+ mSelectionArgs[0] = "";
+
+} else {
+ // Constructs a selection clause that matches the word that the user entered.
+ mSelectionClause = " = ?";
+
+ // Moves the user's input string to the selection arguments.
+ mSelectionArgs[0] = mSearchString;
+
+}
+
+// Does a query against the table and returns a Cursor object
+mCursor = getContentResolver().query(
+ UserDictionary.Words.CONTENT_URI, // The content URI of the words table
+ mProjection, // The columns to return for each row
+ mSelectionClause // Either null, or the word the user entered
+ mSelectionArgs, // Either empty, or the string the user entered
+ mSortOrder); // The sort order for the returned rows
+
+// Some providers return null if an error occurs, others throw an exception
+if (null == mCursor) {
+ /*
+ * Insert code here to handle the error. Be sure not to use the cursor! You may want to
+ * call android.util.Log.e() to log this error.
+ *
+ */
+// If the Cursor is empty, the provider found no matches
+} else if (mCursor.getCount() &lt; 1) {
+
+ /*
+ * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
+ * an error. You may want to offer the user the option to insert a new row, or re-type the
+ * search term.
+ */
+
+} else {
+ // Insert code here to do something with the results
+
+}
+</pre>
+<p>
+ This query is analogous to the SQL statement:
+</p>
+<pre>
+SELECT _ID, word, frequency, locale FROM words WHERE word = &lt;userinput&gt; ORDER BY word ASC;
+</pre>
+<p>
+ In this SQL statement, the actual column names are used instead of contract class constants.
+</p>
+<h4 id="Injection">Protecting against malicious input</h4>
+<p>
+ If the data managed by the content provider is in an SQL database, including external untrusted
+ data into raw SQL statements can lead to SQL injection.
+</p>
+<p>
+ Consider this selection clause:
+</p>
+<pre>
+// Constructs a selection clause by concatenating the user's input to the column name
+String mSelectionClause = "var = " + mUserInput;
+</pre>
+<p>
+ If you do this, you're allowing the user to concatenate malicious SQL onto your SQL statement.
+ For example, the user could enter "nothing; DROP TABLE *;" for <code>mUserInput</code>, which
+ would result in the selection clause <code>var = nothing; DROP TABLE *;</code>. Since the
+ selection clause is treated as an SQL statement, this might cause the provider to erase all of
+ the tables in the underlying SQLite database (unless the provider is set up to catch
+ <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection</a> attempts).
+</p>
+<p>
+ To avoid this problem, use a selection clause that uses <code>?</code> as a replaceable
+ parameter and a separate array of selection arguments. When you do this, the user input
+ is bound directly to the query rather than being interpreted as part of an SQL statement.
+ Because it's not treated as SQL, the user input can't inject malicious SQL. Instead of using
+ concatenation to include the user input, use this selection clause:
+</p>
+<pre>
+// Constructs a selection clause with a replaceable parameter
+String mSelectionClause = "var = ?";
+</pre>
+<p>
+ Set up the array of selection arguments like this:
+</p>
+<pre>
+// Defines an array to contain the selection arguments
+String[] selectionArgs = {""};
+</pre>
+<p>
+ Put a value in the selection arguments array like this:
+</p>
+<pre>
+// Sets the selection argument to the user's input
+selectionArgs[0] = mUserInput;
+</pre>
+<p>
+ A selection clause that uses <code>?</code> as a replaceable parameter and an array of
+ selection arguments array are preferred way to specify a selection, even the provider isn't
+ based on an SQL database.
+</p>
+<!-- Displaying the results -->
+<h3 id="DisplayResults">Displaying query results</h3>
+<p>
+ The {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
+ ContentResolver.query()} client method always returns a {@link android.database.Cursor}
+ containing the columns specified by the query's projection for the rows that match the query's
+ selection criteria. A {@link android.database.Cursor} object provides random read access to the
+ rows and columns it contains. Using {@link android.database.Cursor} methods,
+ you can iterate over the rows in the results, determine the data type of each column, get the
+ data out of a column, and examine other properties of the results. Some
+ {@link android.database.Cursor} implementations automatically update the object when the
+ provider's data changes, or trigger methods in an observer object when the
+ {@link android.database.Cursor} changes, or both.
+</p>
+<p class="note">
+ <strong>Note:</strong> A provider may restrict access to columns based on the nature of the
+ object making the query. For example, the Contacts Provider restricts access for some columns to
+ sync adapters, so it won't return them to an activity or service.
+</p>
+<p>
+ If no rows match the selection criteria, the provider
+ returns a {@link android.database.Cursor} object for which
+ {@link android.database.Cursor#getCount() Cursor.getCount()} is 0 (an empty cursor).
+</p>
+<p>
+ If an internal error occurs, the results of the query depend on the particular provider. It may
+ choose to return <code>null</code>, or it may throw an {@link java.lang.Exception}.
+</p>
+<p>
+ Since a {@link android.database.Cursor} is a "list" of rows, a good way to display the
+ contents of a {@link android.database.Cursor} is to link it to a {@link android.widget.ListView}
+ via a {@link android.widget.SimpleCursorAdapter}.
+</p>
+<p>
+ The following snippet continues the code from the previous snippet. It creates a
+ {@link android.widget.SimpleCursorAdapter} object containing the {@link android.database.Cursor}
+ retrieved by the query, and sets this object to be the adapter for a
+ {@link android.widget.ListView}:
+</p>
+<pre class="prettyprint">
+// Defines a list of columns to retrieve from the Cursor and load into an output row
+String[] mWordListColumns =
+{
+ UserDictionary.Words.WORD, // Contract class constant containing the word column name
+ UserDictionary.Words.LOCALE // Contract class constant containing the locale column name
+};
+
+// Defines a list of View IDs that will receive the Cursor columns for each row
+int[] mWordListItems = { R.id.dictWord, R.id.locale};
+
+// Creates a new SimpleCursorAdapter
+mCursorAdapter = new SimpleCursorAdapter(
+ getApplicationContext(), // The application's Context object
+ R.layout.wordlistrow, // A layout in XML for one row in the ListView
+ mCursor, // The result from the query
+ mWordListColumns, // A string array of column names in the cursor
+ mWordListItems, // An integer array of view IDs in the row layout
+ 0); // Flags (usually none are needed)
+
+// Sets the adapter for the ListView
+mWordList.setAdapter(mCursorAdapter);
+</pre>
+<p class="note">
+ <strong>Note:</strong> To back a {@link android.widget.ListView} with a
+ {@link android.database.Cursor}, the cursor must contain a column named <code>_ID</code>.
+ Because of this, the query shown previously retrieves the <code>_ID</code> column for the
+ "words" table, even though the {@link android.widget.ListView} doesn't display it.
+ This restriction also explains why most providers have a <code>_ID</code> column for each of
+ their tables.
+</p>
+
+ <!-- Getting data from query results -->
+<h3 id="GettingResults">Getting data from query results</h3>
+<p>
+ Rather than simply displaying query results, you can use them for other tasks. For
+ example, you can retrieve spellings from the user dictionary and then look them up in
+ other providers. To do this, you iterate over the rows in the {@link android.database.Cursor}:
+</p>
+<pre class="prettyprint">
+
+// Determine the column index of the column named "word"
+int index = mCursor.getColumnIndex(UserDictionary.Words.WORD);
+
+/*
+ * Only executes if the cursor is valid. The User Dictionary Provider returns null if
+ * an internal error occurs. Other providers may throw an Exception instead of returning null.
+ */
+
+if (mCursor != null) {
+ /*
+ * Moves to the next row in the cursor. Before the first movement in the cursor, the
+ * "row pointer" is -1, and if you try to retrieve data at that position you will get an
+ * exception.
+ */
+ while (mCursor.moveToNext()) {
+
+ // Gets the value from the column.
+ newWord = mCursor.getString(index);
+
+ // Insert code here to process the retrieved word.
+
+ ...
+
+ // end of while loop
+ }
+} else {
+
+ // Insert code here to report an error if the cursor is null or the provider threw an exception.
+}
+</pre>
+<p>
+ {@link android.database.Cursor} implementations contain several "get" methods for
+ retrieving different types of data from the object. For example, the previous snippet
+ uses {@link android.database.Cursor#getString(int) getString()}. They also have a
+ {@link android.database.Cursor#getType(int) getType()} method that returns a value indicating
+ the data type of the column.
+</p>
+
+
+ <!-- Requesting permissions -->
+<h2 id="Permissions">Content Provider Permissions</h2>
+<p>
+ A provider's application can specify permissions that other applications must have in order to
+ access the provider's data. These permissions ensure that the user knows what data
+ an application will try to access. Based on the provider's requirements, other applications
+ request the permissions they need in order to access the provider. End users see the requested
+ permissions when they install the application.
+</p>
+<p>
+ If a provider's application doesn't specify any permissions, then other applications have no
+ access to the provider's data. However, components in the provider's application always have
+ full read and write access, regardless of the specified permissions.
+</p>
+<p>
+ As noted previously, the User Dictionary Provider requires the
+ <code>android.permission.READ_USER_DICTIONARY</code> permission to retrieve data from it.
+ The provider has the separate <code>android.permission.WRITE_USER_DICTIONARY</code>
+ permission for inserting, updating, or deleting data.
+</p>
+<p>
+ To get the permissions needed to access a provider, an application requests them with a
+ <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> element in its manifest file.
+ When the Android Package Manager installs the application, a user must approve all of the
+ permissions the application requests. If the user approves all of them, Package Manager
+ continues the installation; if the user doesn't approve them, Package Manager
+ aborts the installation.
+</p>
+<p>
+ The following
+ <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> element requests read access to the User Dictionary Provider:
+</p>
+<pre>
+ &lt;uses-permission android:name="android.permission.READ_USER_DICTIONARY"&gt;
+</pre>
+<p>
+ The impact of permissions on provider access is explained in more detail in the
+ <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> guide.
+</p>
+
+
+<!-- Inserting, Updating, and Deleting Data -->
+<h2 id="Modifications">Inserting, Updating, and Deleting Data</h2>
+<p>
+ In the same way that you retrieve data from a provider, you also use the interaction between
+ a provider client and the provider's {@link android.content.ContentProvider} to modify data.
+ You call a method of {@link android.content.ContentResolver} with arguments that are passed to
+ the corresponding method of {@link android.content.ContentProvider}. The provider and provider
+ client automatically handle security and inter-process communication.
+</p>
+<h3 id="Inserting">Inserting data</h3>
+<p>
+ To insert data into a provider, you call the
+ {@link android.content.ContentResolver#insert(Uri,ContentValues) ContentResolver.insert()}
+ method. This method inserts a new row into the provider and returns a content URI for that row.
+ This snippet shows how to insert a new word into the User Dictionary Provider:
+</p>
+<pre class="prettyprint">
+// Defines a new Uri object that receives the result of the insertion
+Uri mNewUri;
+
+...
+
+// Defines an object to contain the new values to insert
+ContentValues mNewValues = new ContentValues();
+
+/*
+ * Sets the values of each column and inserts the word. The arguments to the "put"
+ * method are "column name" and "value"
+ */
+mNewValues.put(UserDictionary.Words.APP_ID, "example.user");
+mNewValues.put(UserDictionary.Words.LOCALE, "en_US");
+mNewValues.put(UserDictionary.Words.WORD, "insert");
+mNewValues.put(UserDictionary.Words.FREQUENCY, "100");
+
+mNewUri = getContentResolver().insert(
+ UserDictionary.Word.CONTENT_URI, // the user dictionary content URI
+ mNewValues // the values to insert
+);
+</pre>
+<p>
+ The data for the new row goes into a single {@link android.content.ContentValues} object, which
+ is similar in form to a one-row cursor. The columns in this object don't need to have the
+ same data type, and if you don't want to specify a value at all, you can set a column
+ to <code>null</code> using {@link android.content.ContentValues#putNull(String)
+ ContentValues.putNull()}.
+</p>
+<p>
+ The snippet doesn't add the <code>_ID</code> column, because this column is maintained
+ automatically. The provider assigns a unique value of <code>_ID</code> to every row that is
+ added. Providers usually use this value as the table's primary key.
+</p>
+<p>
+ The content URI returned in <code>newUri</code> identifies the newly-added row, with
+ the following format:
+</p>
+<pre>
+content://user_dictionary/words/&lt;id_value&gt;
+</pre>
+<p>
+ The <code>&lt;id_value&gt;</code> is the contents of <code>_ID</code> for the new row.
+ Most providers can detect this form of content URI automatically and then perform the requested
+ operation on that particular row.
+</p>
+<p>
+ To get the value of <code>_ID</code> from the returned {@link android.net.Uri}, call
+ {@link android.content.ContentUris#parseId(Uri) ContentUris.parseId()}.
+</p>
+<h3 id="Updating">Updating data</h3>
+<p>
+ To update a row, you use a {@link android.content.ContentValues} object with the updated
+ values just as you do with an insertion, and selection criteria just as you do with a query.
+ The client method you use is
+ {@link android.content.ContentResolver#update(Uri, ContentValues, String, String[])
+ ContentResolver.update()}. You only need to add values to the
+ {@link android.content.ContentValues} object for columns you're updating. If you want to clear
+ the contents of a column, set the value to <code>null</code>.
+</p>
+<p>
+ The following snippet changes all the rows whose locale has the language "en" to a
+ have a locale of <code>null</code>. The return value is the number of rows that were updated:
+</p>
+<pre>
+// Defines an object to contain the updated values
+ContentValues mUpdateValues = new ContentValues();
+
+// Defines selection criteria for the rows you want to update
+String mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?";
+String[] mSelectionArgs = {"en_%"};
+
+// Defines a variable to contain the number of updated rows
+int mRowsUpdated = 0;
+
+...
+
+/*
+ * Sets the updated value and updates the selected words.
+ */
+mUpdateValues.putNull(UserDictionary.Words.LOCALE);
+
+mRowsUpdated = getContentResolver().update(
+ UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
+ mUpdateValues // the columns to update
+ mSelectionClause // the column to select on
+ mSelectionArgs // the value to compare to
+);
+</pre>
+<p>
+ You should also sanitize user input when you call
+ {@link android.content.ContentResolver#update(Uri, ContentValues, String, String[])
+ ContentResolver.update()}. To learn more about this, read the section
+ <a href="#Injection">Protecting against malicious input</a>.
+</p>
+<h3 id="Deleting">Deleting data</h3>
+<p>
+ Deleting rows is similar to retrieving row data: you specify selection criteria for the rows
+ you want to delete and the client method returns the number of deleted rows.
+ The following snippet deletes rows whose appid matches "user". The method returns the
+ number of deleted rows.
+</p>
+<pre>
+
+// Defines selection criteria for the rows you want to delete
+String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
+String[] mSelectionArgs = {"user"};
+
+// Defines a variable to contain the number of rows deleted
+int mRowsDeleted = 0;
+
+...
+
+// Deletes the words that match the selection criteria
+mRowsDeleted = getContentResolver().delete(
+ UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
+ mSelectionClause // the column to select on
+ mSelectionArgs // the value to compare to
+);
+</pre>
+<p>
+ You should also sanitize user input when you call
+ {@link android.content.ContentResolver#delete(Uri, String, String[])
+ ContentResolver.delete()}. To learn more about this, read the section
+ <a href="#Injection">Protecting against malicious input</a>.
+</p>
+<!-- Provider Data Types -->
+<h2 id="DataTypes">Provider Data Types</h2>
+<p>
+ Content providers can offer many different data types. The User Dictionary Provider offers only
+ text, but providers can also offer the following formats:
+</p>
+ <ul>
+ <li>
+ integer
+ </li>
+ <li>
+ long integer (long)
+ </li>
+ <li>
+ floating point
+ </li>
+ <li>
+ long floating point (double)
+ </li>
+ </ul>
+<p>
+ Another data type that providers often use is Binary Large OBject (BLOB) implemented as a
+ 64KB byte array. You can see the available data types by looking at the
+ {@link android.database.Cursor} class "get" methods.
+</p>
+<p>
+ The data type for each column in a provider is usually listed in its documentation.
+ The data types for the User Dictionary Provider are listed in the reference documentation
+ for its contract class {@link android.provider.UserDictionary.Words} (contract classes are
+ described in the section <a href="#ContractClasses">Contract Classes</a>).
+ You can also determine the data type by calling {@link android.database.Cursor#getType(int)
+ Cursor.getType()}.
+</p>
+<p>
+ Providers also maintain MIME data type information for each content URI they define. You can
+ use the MIME type information to find out if your application can handle data that the
+ provider offers, or to choose a type of handling based on the MIME type. You usually need the
+ MIME type when you are working with a provider that contains complex
+ data structures or files. For example, the {@link android.provider.ContactsContract.Data}
+ table in the Contacts Provider uses MIME types to label the type of contact data stored in each
+ row. To get the MIME type corresponding to a content URI, call
+ {@link android.content.ContentResolver#getType(Uri) ContentResolver.getType()}.
+</p>
+<p>
+ The section <a href="#MIMETypeReference">MIME Type Reference</a> describes the
+ syntax of both standard and custom MIME types.
+</p>
+
+
+<!-- Alternative Forms of Provider Access -->
+<h2 id="AltForms">Alternative Forms of Provider Access</h2>
+<p>
+ Three alternative forms of provider access are important in application development:
+</p>
+<ul>
+ <li>
+ <a href="#Batch">Batch access</a>: You can create a batch of access calls with methods in
+ the {@link android.content.ContentProviderOperation} class, and then apply them with
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList)
+ ContentResolver.applyBatch()}.
+ </li>
+ <li>
+ Asynchronous queries: You should do queries in a separate thread. One way to do this is to
+ use a {@link android.content.CursorLoader} object. The examples in the
+ <a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> guide demonstrate
+ how to do this.
+ </li>
+ <li>
+ <a href="#Intents">Data access via intents</a>: Although you can't send an intent
+ directly to a provider, you can send an intent to the provider's application, which is
+ usually the best-equipped to modify the provider's data.
+ </li>
+</ul>
+<p>
+ Batch access and modification via intents are described in the following sections.
+</p>
+<h3 id="Batch">Batch access</h3>
+<p>
+ Batch access to a provider is useful for inserting a large number of rows, or for inserting
+ rows in multiple tables in the same method call, or in general for performing a set of
+ operations across process boundaries as a transaction (an atomic operation).
+</p>
+<p>
+ To access a provider in "batch mode",
+ you create an array of {@link android.content.ContentProviderOperation} objects and then
+ dispatch them to a content provider with
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList)
+ ContentResolver.applyBatch()}. You pass the content provider's <em>authority</em> to this
+ method, rather than a particular content URI, which allows each
+ {@link android.content.ContentProviderOperation} object in the array to work against a
+ different table. A call to {@link android.content.ContentResolver#applyBatch(String, ArrayList)
+ ContentResolver.applyBatch()} returns an array of results.
+</p>
+<p>
+ The description of the {@link android.provider.ContactsContract.RawContacts} contract class
+ includes a code snippet that demonstrates batch insertion. The
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">Contact Manager</a>
+ sample application contains an example of batch access in its <code>ContactAdder.java</code>
+ source file.
+</p>
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Displaying data using a helper app</h2>
+<p>
+ If your application <em>does</em> have access permissions, you still may want to use an
+ intent to display data in another application. For example, the Calendar application accepts an
+ {@link android.content.Intent#ACTION_VIEW} intent, which displays a particular date or event.
+ This allows you to display calendar information without having to create your own UI.
+ To learn more about this feature, see the
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a> guide.
+</p>
+<p>
+ The application to which you send the intent doesn't have to be the application
+ associated with the provider. For example, you can retrieve a contact from the
+ Contact Provider, then send an {@link android.content.Intent#ACTION_VIEW} intent
+ containing the content URI for the contact's image to an image viewer.
+</p>
+</div>
+</div>
+<h3 id="Intents">Data access via intents</h3>
+<p>
+ Intents can provide indirect access to a content provider. You allow the user to access
+ data in a provider even if your application doesn't have access permissions, either by
+ getting a result intent back from an application that has permissions, or by activating an
+ application that has permissions and letting the user do work in it.
+</p>
+<h4>Getting access with temporary permissions</h4>
+<p>
+ You can access data in a content provider, even if you don't have the proper access
+ permissions, by sending an intent to an application that does have the permissions and
+ receiving back a result intent containing "URI" permissions.
+ These are permissions for a specific content URI that last until the activity that receives
+ them is finished. The application that has permanent permissions grants temporary
+ permissions by setting a flag in the result intent:
+</p>
+<ul>
+ <li>
+ <strong>Read permission:</strong>
+ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}
+ </li>
+ <li>
+ <strong>Write permission:</strong>
+ {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}
+ </li>
+</ul>
+<p class="note">
+ <strong>Note:</strong> These flags don't give general read or write access to the provider
+ whose authority is contained in the content URI. The access is only for the URI itself.
+</p>
+<p>
+ A provider defines URI permissions for content URIs in its manifest, using the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermission</a></code>
+ attribute of the
+ {@code <a href="guide/topics/manifest/provider-element.html">&lt;provider&gt;</a>}
+ element, as well as the
+ {@code <a href="guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a>} child element of the
+ {@code <a href="guide/topics/manifest/provider-element.html">&lt;provider&gt;</a>}
+ element. The URI permissions mechanism is explained in more detail in the
+ <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> guide,
+ in the section "URI Permissions".
+</p>
+<p>
+ For example, you can retrieve data for a contact in the Contacts Provider, even if you don't
+ have the {@link android.Manifest.permission#READ_CONTACTS} permission. You might want to do
+ this in an application that sends e-greetings to a contact on his or her birthday. Instead of
+ requesting {@link android.Manifest.permission#READ_CONTACTS}, which gives you access to all of
+ the user's contacts and all of their information, you prefer to let the user control which
+ contacts are used by your application. To do this, you use the following process:
+</p>
+<ol>
+ <li>
+ Your application sends an intent containing the action
+ {@link android.content.Intent#ACTION_PICK} and the "contacts" MIME type
+ {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE}, using the
+ method {@link android.app.Activity#startActivityForResult(Intent, int)
+ startActivityForResult()}.
+ </li>
+ <li>
+ Because this intent matches the intent filter for the
+ People app's "selection" activity, the activity will come to the foreground.
+ </li>
+ <li>
+ In the selection activity, the user selects a
+ contact to update. When this happens, the selection activity calls
+ {@link android.app.Activity#setResult(int, Intent) setResult(resultcode, intent)}
+ to set up a intent to give back to your application. The intent contains the content URI
+ of the contact the user selected, and the "extras" flags
+ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}. These flags grant URI
+ permission to your app to read data for the contact pointed to by the
+ content URI. The selection activity then calls {@link android.app.Activity#finish()} to
+ return control to your application.
+ </li>
+ <li>
+ Your activity returns to the foreground, and the system calls your activity's
+ {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()}
+ method. This method receives the result intent created by the selection activity in
+ the People app.
+ </li>
+ <li>
+ With the content URI from the result intent, you can read the contact's data
+ from the Contacts Provider, even though you didn't request permanent read access permission
+ to the provider in your manifest. You can then get the contact's birthday information
+ or his or her email address and then send the e-greeting.
+ </li>
+</ol>
+<h4>Using another application</h4>
+<p>
+ A simple way to allow the user to modify data to which you don't have access permissions is to
+ activate an application that has permissions and let the user do the work there.
+</p>
+<p>
+ For example, the Calendar application accepts an
+ {@link android.content.Intent#ACTION_INSERT} intent, which allows you to activate the
+ application's insert UI. You can pass "extras" data in this intent, which the application
+ uses to pre-populate the UI. Because recurring events have a complex syntax, the preferred
+ way of inserting events into the Calendar Provider is to activate the Calendar app with an
+ {@link android.content.Intent#ACTION_INSERT} and then let the user insert the event there.
+</p>
+<!-- Contract Classes -->
+<h2 id="ContractClasses">Contract Classes</h2>
+<p>
+ A contract class defines constants that help applications work with the content URIs, column
+ names, intent actions, and other features of a content provider. Contract classes are not
+ included automatically with a provider; the provider's developer has to define them and then
+ make them available to other developers. Many of the providers included with the Android
+ platform have corresponding contract classes in the package {@link android.provider}.
+</p>
+<p>
+ For example, the User Dictionary Provider has a contract class
+ {@link android.provider.UserDictionary} containing content URI and column name constants. The
+ content URI for the "words" table is defined in the constant
+ {@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI}.
+ The {@link android.provider.UserDictionary.Words} class also contains column name constants,
+ which are used in the example snippets in this guide. For example, a query projection can be
+ defined as:
+</p>
+<pre>
+String[] mProjection =
+{
+ UserDictionary.Words._ID,
+ UserDictionary.Words.WORD,
+ UserDictionary.Words.LOCALE
+};
+</pre>
+<p>
+ Another contract class is {@link android.provider.ContactsContract} for the Contacts Provider.
+ The reference documentation for this class includes example code snippets. One of its
+ subclasses, {@link android.provider.ContactsContract.Intents.Insert}, is a contract
+ class that contains constants for intents and intent data.
+</p>
+
+
+<!-- MIME Type Reference -->
+<h2 id="MIMETypeReference">MIME Type Reference</h2>
+<p>
+ Content providers can return standard MIME media types, or custom MIME type strings, or both.
+</p>
+<p>
+ MIME types have the format
+</p>
+<pre>
+<em>type</em>/<em>subtype</em>
+</pre>
+<p>
+ For example, the well-known MIME type <code>text/html</code> has the <code>text</code> type and
+ the <code>html</code> subtype. If the provider returns this type for a URI, it means that a
+ query using that URI will return text containing HTML tags.
+</p>
+<p>
+ Custom MIME type strings, also called "vendor-specific" MIME types, have more
+ complex <em>type</em> and <em>subtype</em> values. The <em>type</em> value is always
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>
+</pre>
+<p>
+ for multiple rows, or
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>
+</pre>
+<p>
+ for a single row.
+</p>
+<p>
+ The <em>subtype</em> is provider-specific. The Android built-in providers usually have a simple
+ subtype. For example, the when the Contacts application creates a row for a telephone number,
+ it sets the following MIME type in the row:
+</p>
+<pre>
+vnd.android.cursor.item/phone_v2
+</pre>
+<p>
+ Notice that the subtype value is simply <code>phone_v2</code>.
+</p>
+<p>
+ Other provider developers may create their own pattern of subtypes based on the provider's
+ authority and table names. For example, consider a provider that contains train timetables.
+ The provider's authority is <code>com.example.trains</code>, and it contains the tables
+ Line1, Line2, and Line3. In response to the content URI
+</p>
+<p>
+<pre>
+content://com.example.trains/Line1
+</pre>
+<p>
+ for table Line1, the provider returns the MIME type
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>/vnd.example.line1
+</pre>
+<p>
+ In response to the content URI
+</p>
+<pre>
+content://com.example.trains/Line2/5
+</pre>
+<p>
+ for row 5 in table Line2, the provider returns the MIME type
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>/vnd.example.line2
+</pre>
+<p>
+ Most content providers define contract class constants for the MIME types they use. The
+ Contacts Provider contract class {@link android.provider.ContactsContract.RawContacts},
+ for example, defines the constant
+ {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} for the MIME type of
+ a single raw contact row.
+</p>
+<p>
+ Content URIs for single rows are described in the section
+ <a href="#ContentURIs">Content URIs</a>.
+</p>
diff --git a/docs/html/guide/topics/providers/content-provider-creating.jd b/docs/html/guide/topics/providers/content-provider-creating.jd
new file mode 100644
index 000000000000..4ebdb502138c
--- /dev/null
+++ b/docs/html/guide/topics/providers/content-provider-creating.jd
@@ -0,0 +1,1215 @@
+page.title=Creating a Content Provider
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+
+<h2>In this document</h2>
+<ol>
+ <li>
+ <a href="#DataStorage">Designing Data Storage</a>
+ </li>
+ <li>
+ <a href="#ContentURI">Designing Content URIs</a>
+ </li>
+ <li>
+ <a href="#ContentProvider">Implementing the ContentProvider Class</a>
+ <ol>
+ <li>
+ <a href="#RequiredAccess">Required Methods</a>
+ </li>
+ <li>
+ <a href="#Query">Implementing the query() method</a>
+ </li>
+ <li>
+ <a href="#Insert">Implementing the insert() method</a>
+ </li>
+ <li>
+ <a href="#Delete">Implementing the delete() method</a>
+ </li>
+ <li>
+ <a href="#Update">Implementing the update() method</a>
+ </li>
+ <li>
+ <a href="#OnCreate">Implementing the onCreate() method</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#MIMETypes">Implementing Content Provider MIME Types</a>
+ <ol>
+ <li>
+ <a href="#TableMIMETypes">MIME types for tables</a>
+ </li>
+ <li>
+ <a href="#FileMIMETypes">MIME types for files</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#ContractClass">Implementing a Contract Class</a>
+ </li>
+ <li>
+ <a href="#Permissions">Implementing Content Provider Permissions</a>
+ </li>
+ <li>
+ <a href="#ProviderElement">The &lt;provider&gt; Element</a>
+ </li>
+ <li>
+ <a href="#Intents">Intents and Data Access</a>
+ </li>
+</ol>
+<h2>Key classes</h2>
+ <ol>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.database.Cursor}
+ </li>
+ <li>
+ {@link android.net.Uri}
+ </li>
+ </ol>
+<h2>Related Samples</h2>
+ <ol>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/NotePad/index.html">
+ Note Pad sample application
+ </a>
+ </li>
+ </ol>
+<h2>See also</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Calendar Provider</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+
+<p>
+ A content provider manages access to a central repository of data. You implement a
+ provider as one or more classes in an Android application, along with elements in
+ the manifest file. One of your classes implements a subclass
+ {@link android.content.ContentProvider}, which is the interface between your provider and
+ other applications. Although content providers are meant to make data available to other
+ applications, you may of course have activities in your application that allow the user
+ to query and modify the data managed by your provider.
+</p>
+<p>
+ The rest of this topic is a basic list of steps for building a content provider and a list
+ of APIs to use.
+</p>
+
+
+<!-- Before You Start Building -->
+<h2 id="BeforeYouStart">Before You Start Building</h2>
+<p>
+ Before you start building a provider, do the following:
+</p>
+<ol>
+ <li>
+ <strong>Decide if you need a content provider</strong>. You need to build a content
+ provider if you want to provide one or more of the following features:
+ <ul>
+ <li>You want to offer complex data or files to other applications.</li>
+ <li>You want to allow users to copy complex data from your app into other apps.</li>
+ <li>You want to provide custom search suggestions using the search framework.</li>
+ </ul>
+ <p>
+ You <em>don't</em> need a provider to use an SQLite database if the use is entirely within
+ your own application.
+ </p>
+ </li>
+ <li>
+ If you haven't done so already, read the topic
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a> to learn more about providers.
+ </li>
+</ol>
+<p>
+ Next, follow these steps to build your provider:
+</p>
+<ol>
+ <li>
+ Design the raw storage for your data. A content provider offers data in two ways:
+ <dl>
+ <dt>
+ File data
+ </dt>
+ <dd>
+ Data that normally goes into files, such as
+ photos, audio, or videos. Store the files in your application's private
+ space. In response to a request for a file from another application, your
+ provider can offer a handle to the file.
+ </dd>
+ <dt>
+ &quot;Structured&quot; data
+ </dt>
+ <dd>
+ Data that normally goes into a database, array, or similar structure.
+ Store the data in a form that's compatible with tables of rows and columns. A row
+ represents an entity, such as a person or an item in inventory. A column represents
+ some data for the entity, such a person's name or an item's price. A common way to
+ store this type of data is in an SQLite database, but you can use any type of
+ persistent storage. To learn more about the storage types available in the
+ Android system, see the section <a href="#DataStorage">
+ Designing Data Storage</a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ Define a concrete implementation of the {@link android.content.ContentProvider} class and
+ its required methods. This class is the interface between your data and the rest of the
+ Android system. For more information about this class, see the section
+ <a href="#ContentProvider">Implementing the ContentProvider Class</a>.
+ </li>
+ <li>
+ Define the provider's authority string, its content URIs, and column names. If you want
+ the provider's application to handle intents, also define intent actions, extras data,
+ and flags. Also define the permissions that you will require for applications that want
+ to access your data. You should consider defining all of these values as constants in a
+ separate contract class; later, you can expose this class to other developers. For more
+ information about content URIs, see the
+ section <a href="#ContentURI">Designing Content URIs</a>.
+ For more information about intents, see the
+ section <a href="#Intents">Intents and Data Access</a>.
+ </li>
+ <li>
+ Add other optional pieces, such as sample data or an implementation
+ of {@link android.content.AbstractThreadedSyncAdapter} that can synchronize data between
+ the provider and cloud-based data.
+ </li>
+</ol>
+
+
+<!-- Designing Data Storage -->
+<h2 id="DataStorage">Designing Data Storage</h2>
+<p>
+ A content provider is the interface to data saved in a structured format. Before you create
+ the interface, you must decide how to store the data. You can store the data in any form you
+ like, and then design the interface to read and write the data as necessary.
+</p>
+<p>
+ These are some of the data storage technologies that are available in Android:
+</p>
+<ul>
+ <li>
+ The Android system includes an SQLite database API that Android's own providers use
+ to store table-oriented data. The
+ {@link android.database.sqlite.SQLiteOpenHelper} class helps you create databases, and the
+ {@link android.database.sqlite.SQLiteDatabase} class is the base class for accessing
+ databases.
+ <p>
+ Remember that you don't have to use a database to implement your repository. A provider
+ appears externally as a set of tables, similar to a relational database, but this is
+ not a requirement for the provider's internal implementation.
+ </p>
+ </li>
+ <li>
+ For storing file data, Android has a variety of file-oriented APIs.
+ To learn more about file storage, read the topic
+ <a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>. If you're
+ designing a provider that offers media-related data such as music or videos, you can
+ have a provider that combines table data and files.
+ </li>
+ <li>
+ For working with network-based data, use classes in {@link java.net} and
+ {@link android.net}. You can also synchronize network-based data to a local data
+ store such as a database, and then offer the data as tables or files.
+ The <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Sample Sync Adapter</a> sample application demonstrates this type of synchronization.
+ </li>
+</ul>
+<h3 id="DataDesign">
+ Data design considerations
+</h3>
+<p>
+ Here are some tips for designing your provider's data structure:
+</p>
+<ul>
+ <li>
+ Table data should always have a &quot;primary key&quot; column that the provider maintains
+ as a unique numeric value for each row. You can use this value to link the row to related
+ rows in other tables (using it as a &quot;foreign key&quot;). Although you can use any name
+ for this column, using {@link android.provider.BaseColumns#_ID BaseColumns._ID} is the best
+ choice, because linking the results of a provider query to a
+ {@link android.widget.ListView} requires one of the retrieved columns to have the name
+ <code>_ID</code>.
+ </li>
+ <li>
+ If you want to provide bitmap images or other very large pieces of file-oriented data, store
+ the data in a file and then provide it indirectly rather than storing it directly in a
+ table. If you do this, you need to tell users of your provider that they need to use a
+ {@link android.content.ContentResolver} file method to access the data.
+ </li>
+ <li>
+ Use the Binary Large OBject (BLOB) data type to store data that varies in size or has a
+ varying structure. For example, you can use a BLOB column to store a
+ <a href="http://code.google.com/p/protobuf">protocol buffer</a> or
+ <a href="http://www.json.org">JSON structure</a>.
+ <p>
+ You can also use a BLOB to implement a <em>schema-independent</em> table. In
+ this type of table, you define a primary key column, a MIME type column, and one or
+ more generic columns as BLOB. The meaning of the data in the BLOB columns is indicated
+ by the value in the MIME type column. This allows you to store different row types in
+ the same table. The Contacts Provider's &quot;data&quot; table
+ {@link android.provider.ContactsContract.Data} is an example of a schema-independent
+ table.
+ </p>
+ </li>
+</ul>
+<!-- Designing Content URIs -->
+<h2 id="ContentURI">Designing Content URIs</h2>
+<p>
+ A <strong>content URI</strong> is a URI that identifies data in a provider. Content URIs include
+ the symbolic name of the entire provider (its <strong>authority</strong>) and a
+ name that points to a table or file (a <strong>path</strong>). The optional id part points to
+ an individual row in a table. Every data access method of
+ {@link android.content.ContentProvider} has a content URI as an argument; this allows you to
+ determine the table, row, or file to access.
+</p>
+<p>
+ The basics of content URIs are described in the topic
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a>.
+</p>
+<h3>Designing an authority</h3>
+<p>
+ A provider usually has a single authority, which serves as its Android-internal name. To
+ avoid conflicts with other providers, you should use Internet domain ownership (in reverse)
+ as the basis of your provider authority. Because this recommendation is also true for Android
+ package names, you can define your provider authority as an extension of the name
+ of the package containing the provider. For example, if your Android package name is
+ <code>com.example.&lt;appname&gt;</code>, you should give your provider the
+ authority <code>com.example.&lt;appname&gt;.provider</code>.
+</p>
+<h3>Designing a path structure</h3>
+<p>
+ Developers usually create content URIs from the authority by appending paths that point to
+ individual tables. For example, if you have two tables <em>table1</em> and
+ <em>table2</em>, you combine the authority from the previous example to yield the
+ content URIs
+ <code>com.example.&lt;appname&gt;.provider/table1</code> and
+ <code>com.example.&lt;appname&gt;.provider/table2</code>. Paths aren't
+ limited to a single segment, and there doesn't have to be a table for each level of the path.
+</p>
+<h3>Handling content URI IDs</h3>
+<p>
+ By convention, providers offer access to a single row in a table by accepting a content URI
+ with an ID value for the row at the end of the URI. Also by convention, providers match the
+ ID value to the table's <code>_ID</code> column, and perform the requested access against the
+ row that matches.
+</p>
+<p>
+ This convention facilitates a common design pattern for apps accessing a provider. The app
+ does a query against the provider and displays the resulting {@link android.database.Cursor}
+ in a {@link android.widget.ListView} using a {@link android.widget.CursorAdapter}.
+ The definition of {@link android.widget.CursorAdapter} requires one of the columns in the
+ {@link android.database.Cursor} to be <code>_ID</code>
+</p>
+<p>
+ The user then picks one of the displayed rows from the UI in order to look at or modify the
+ data. The app gets the corresponding row from the {@link android.database.Cursor} backing the
+ {@link android.widget.ListView}, gets the <code>_ID</code> value for this row, appends it to
+ the content URI, and sends the access request to the provider. The provider can then do the
+ query or modification against the exact row the user picked.
+</p>
+<h3>Content URI patterns</h3>
+<p>
+ To help you choose which action to take for an incoming content URI, the provider API includes
+ the convenience class {@link android.content.UriMatcher}, which maps content URI "patterns" to
+ integer values. You can use the integer values in a <code>switch</code> statement that
+ chooses the desired action for the content URI or URIs that match a particular pattern.
+</p>
+<p>
+ A content URI pattern matches content URIs using wildcard characters:
+</p>
+ <ul>
+ <li>
+ <strong><code>*</code>:</strong> Matches a string of any valid characters of any length.
+ </li>
+ <li>
+ <strong><code>#</code>:</strong> Matches a string of numeric characters of any length.
+ </li>
+ </ul>
+<p>
+ As an example of designing and coding content URI handling, consider a provider with the
+ authority <code>com.example.app.provider</code> that recognizes the following content URIs
+ pointing to tables:
+</p>
+<ul>
+ <li>
+ <code>content://com.example.app.provider/table1</code>: A table called <code>table1</code>.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table2/dataset1</code>: A table called
+ <code>dataset1</code>.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table2/dataset2</code>: A table called
+ <code>dataset2</code>.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table3</code>: A table called <code>table3</code>.
+ </li>
+</ul>
+<p>
+ The provider also recognizes these content URIs if they have a row ID appended to them, as
+ for example <code>content://com.example.app.provider/table3/1</code> for the row identified by
+ <code>1</code> in <code>table3</code>.
+</p>
+<p>
+ The following content URI patterns would be possible:
+</p>
+<dl>
+ <dt>
+ <code>content://com.example.app.provider/*</code>
+ </dt>
+ <dd>
+ Matches any content URI in the provider.
+ </dd>
+ <dt>
+ <code>content://com.example.app.provider/table2/*</code>:
+ </dt>
+ <dd>
+ Matches a content URI for the tables <code>dataset1</code>
+ and <code>dataset2</code>, but doesn't match content URIs for <code>table1</code> or
+ <code>table3</code>.
+ </dd>
+ <dt>
+ <code>content://com.example.app.provider/table3/#</code>: Matches a content URI
+ for single rows in <code>table3</code>, such as
+ <code>content://com.example.app.provider/table3/6</code> for the row identified by
+ <code>6</code>.
+ </dt>
+</dl>
+<p>
+ The following code snippet shows how the methods in {@link android.content.UriMatcher} work.
+ This code handles URIs for an entire table differently from URIs for a
+ single row, by using the content URI pattern
+ <code>content://&lt;authority&gt;/&lt;path&gt;</code> for tables, and
+ <code>content://&lt;authority&gt;/&lt;path&gt;/&lt;id&gt;</code> for single rows.
+</p>
+<p>
+ The method {@link android.content.UriMatcher#addURI(String, String, int) addURI()} maps an
+ authority and path to an integer value. The method android.content.UriMatcher#match(Uri)
+ match()} returns the integer value for a URI. A <code>switch</code> statement
+ chooses between querying the entire table, and querying for a single record:
+</p>
+<pre class="prettyprint">
+public class ExampleProvider extends ContentProvider {
+...
+ // Creates a UriMatcher object.
+ private static final UriMatcher sUriMatcher;
+...
+ /*
+ * The calls to addURI() go here, for all of the content URI patterns that the provider
+ * should recognize. For this snippet, only the calls for table 3 are shown.
+ */
+...
+ /*
+ * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used
+ * in the path
+ */
+ sUriMatcher.addURI("com.example.app.provider", "table3", 1);
+
+ /*
+ * Sets the code for a single row to 2. In this case, the "#" wildcard is
+ * used. "content://com.example.app.provider/table3/3" matches, but
+ * "content://com.example.app.provider/table3 doesn't.
+ */
+ sUriMatcher.addURI("com.example.app.provider", "table3/#", 2);
+...
+ // Implements ContentProvider.query()
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder) {
+...
+ /*
+ * Choose the table to query and a sort order based on the code returned for the incoming
+ * URI. Here, too, only the statements for table 3 are shown.
+ */
+ switch (sUriMatcher.match(uri)) {
+
+
+ // If the incoming URI was for all of table3
+ case 1:
+
+ if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC";
+ break;
+
+ // If the incoming URI was for a single row
+ case 2:
+
+ /*
+ * Because this URI was for a single row, the _ID value part is
+ * present. Get the last path segment from the URI; this is the _ID value.
+ * Then, append the value to the WHERE clause for the query
+ */
+ selection = selection + "_ID = " uri.getLastPathSegment();
+ break;
+
+ default:
+ ...
+ // If the URI is not recognized, you should do some error handling here.
+ }
+ // call the code to actually do the query
+ }
+</pre>
+<p>
+ Another class, {@link android.content.ContentUris}, provides convenience methods for working
+ with the <code>id</code> part of content URIs. The classes {@link android.net.Uri} and
+ {@link android.net.Uri.Builder} include convenience methods for parsing existing
+ {@link android.net.Uri} objects and building new ones.
+</p>
+
+<!-- Implementing the ContentProvider class -->
+<h2 id="ContentProvider">Implementing the ContentProvider Class</h2>
+<p>
+ The {@link android.content.ContentProvider} instance manages access
+ to a structured set of data by handling requests from other applications. All forms
+ of access eventually call {@link android.content.ContentResolver}, which then calls a concrete
+ method of {@link android.content.ContentProvider} to get access.
+</p>
+<h3 id="RequiredAccess">Required methods</h3>
+<p>
+ The abstract class {@link android.content.ContentProvider} defines six abstract methods that
+ you must implement as part of your own concrete subclass. All of these methods except
+ {@link android.content.ContentProvider#onCreate() onCreate()} are called by a client application
+ that is attempting to access your content provider:
+</p>
+<dl>
+ <dt>
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ query()}
+ </dt>
+ <dd>
+ Retrieve data from your provider. Use the arguments to select the table to
+ query, the rows and columns to return, and the sort order of the result.
+ Return the data as a {@link android.database.Cursor} object.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}
+ </dt>
+ <dd>
+ Insert a new row into your provider. Use the arguments to select the
+ destination table and to get the column values to use. Return a content URI for the
+ newly-inserted row.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[])
+ update()}
+ </dt>
+ <dd>
+ Update existing rows in your provider. Use the arguments to select the table and rows
+ to update and to get the updated column values. Return the number of rows updated.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()}
+ </dt>
+ <dd>
+ Delete rows from your provider. Use the arguments to select the table and the rows to
+ delete. Return the number of rows deleted.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ Return the MIME type corresponding to a content URI. This method is described in more
+ detail in the section <a href="#MIMETypes">Implementing Content Provider MIME Types</a>.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#onCreate() onCreate()}
+ </dt>
+ <dd>
+ Initialize your provider. The Android system calls this method immediately after it
+ creates your provider. Notice that your provider is not created until a
+ {@link android.content.ContentResolver} object tries to access it.
+ </dd>
+</dl>
+<p>
+ Notice that these methods have the same signature as the identically-named
+ {@link android.content.ContentResolver} methods.
+</p>
+<p>
+ Your implementation of these methods should account for the following:
+</p>
+<ul>
+ <li>
+ All of these methods except {@link android.content.ContentProvider#onCreate() onCreate()}
+ can be called by multiple threads at once, so they must be thread-safe. To learn
+ more about multiple threads, see the topic
+ <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">
+ Processes and Threads</a>.
+ </li>
+ <li>
+ Avoid doing lengthy operations in {@link android.content.ContentProvider#onCreate()
+ onCreate()}. Defer initialization tasks until they are actually needed.
+ The section <a href="#OnCreate">Implementing the onCreate() method</a>
+ discusses this in more detail.
+ </li>
+ <li>
+ Although you must implement these methods, your code does not have to do anything except
+ return the expected data type. For example, you may want to prevent other applications
+ from inserting data into some tables. To do this, you can ignore the call to
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} and return
+ 0.
+ </li>
+</ul>
+<h3 id="Query">Implementing the query() method</h3>
+<p>
+ The
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ ContentProvider.query()} method must return a {@link android.database.Cursor} object, or if it
+ fails, throw an {@link java.lang.Exception}. If you are using an SQLite database as your data
+ storage, you can simply return the {@link android.database.Cursor} returned by one of the
+ <code>query()</code> methods of the {@link android.database.sqlite.SQLiteDatabase} class.
+ If the query does not match any rows, you should return a {@link android.database.Cursor}
+ instance whose {@link android.database.Cursor#getCount()} method returns 0.
+ You should return <code>null</code> only if an internal error occurred during the query process.
+</p>
+<p>
+ If you aren't using an SQLite database as your data storage, use one of the concrete subclasses
+ of {@link android.database.Cursor}. For example, the {@link android.database.MatrixCursor} class
+ implements a cursor in which each row is an array of {@link java.lang.Object}. With this class,
+ use {@link android.database.MatrixCursor#addRow(Object[]) addRow()} to add a new row.
+</p>
+<p>
+ Remember that the Android system must be able to communicate the {@link java.lang.Exception}
+ across process boundaries. Android can do this for the following exceptions that may be useful
+ in handling query errors:
+</p>
+<ul>
+ <li>
+ {@link java.lang.IllegalArgumentException} (You may choose to throw this if your provider
+ receives an invalid content URI)
+ </li>
+ <li>
+ {@link java.lang.NullPointerException}
+ </li>
+</ul>
+<h3 id="Insert">Implementing the insert() method</h3>
+<p>
+ The {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} method adds a
+ new row to the appropriate table, using the values in the {@link android.content.ContentValues}
+ argument. If a column name is not in the {@link android.content.ContentValues} argument, you
+ may want to provide a default value for it either in your provider code or in your database
+ schema.
+</p>
+<p>
+ This method should return the content URI for the new row. To construct this, append the new
+ row's <code>_ID</code> (or other primary key) value to the table's content URI, using
+ {@link android.content.ContentUris#withAppendedId(Uri, long) withAppendedId()}.
+</p>
+<h3 id="Delete">Implementing the delete() method</h3>
+<p>
+ The {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} method
+ does not have to physically delete rows from your data storage. If you are using a sync adapter
+ with your provider, you should consider marking a deleted row
+ with a &quot;delete&quot; flag rather than removing the row entirely. The sync adapter can
+ check for deleted rows and remove them from the server before deleting them from the provider.
+</p>
+<h3 id="Update">Implementing the update() method</h3>
+<p>
+ The {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[])
+ update()} method takes the same {@link android.content.ContentValues} argument used by
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}, and the
+ same <code>selection</code> and <code>selectionArgs</code> arguments used by
+ {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} and
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ ContentProvider.query()}. This may allow you to re-use code between these methods.
+</p>
+<h3 id="OnCreate">Implementing the onCreate() method</h3>
+<p>
+ The Android system calls {@link android.content.ContentProvider#onCreate()
+ onCreate()} when it starts up the provider. You should perform only fast-running initialization
+ tasks in this method, and defer database creation and data loading until the provider actually
+ receives a request for the data. If you do lengthy tasks in
+ {@link android.content.ContentProvider#onCreate() onCreate()}, you will slow down your
+ provider's startup. In turn, this will slow down the response from the provider to other
+ applications.
+</p>
+<p>
+ For example, if you are using an SQLite database you can create
+ a new {@link android.database.sqlite.SQLiteOpenHelper} object in
+ {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()},
+ and then create the SQL tables the first time you open the database. To facilitate this, the
+ first time you call {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase
+ getWritableDatabase()}, it automatically calls the
+ {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+ SQLiteOpenHelper.onCreate()} method.
+</p>
+<p>
+ The following two snippets demonstrate the interaction between
+ {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} and
+ {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+ SQLiteOpenHelper.onCreate()}. The first snippet is the implementation of
+ {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()}:
+</p>
+<pre class="prettyprint">
+public class ExampleProvider extends ContentProvider
+
+ /*
+ * Defines a handle to the database helper object. The MainDatabaseHelper class is defined
+ * in a following snippet.
+ */
+ private MainDatabaseHelper mOpenHelper;
+
+ // Defines the database name
+ private static final String DBNAME = "mydb";
+
+ // Holds the database object
+ private SQLiteDatabase db;
+
+ public boolean onCreate() {
+
+ /*
+ * Creates a new helper object. This method always returns quickly.
+ * Notice that the database itself isn't created or opened
+ * until SQLiteOpenHelper.getWritableDatabase is called
+ */
+ mOpenHelper = new SQLiteOpenHelper(
+ getContext(), // the application context
+ DBNAME, // the name of the database)
+ null, // uses the default SQLite cursor
+ 1 // the version number
+ );
+
+ return true;
+ }
+
+ ...
+
+ // Implements the provider's insert method
+ public Cursor insert(Uri uri, ContentValues values) {
+ // Insert code here to determine which table to open, handle error-checking, and so forth
+
+ ...
+
+ /*
+ * Gets a writeable database. This will trigger its creation if it doesn't already exist.
+ *
+ */
+ db = mOpenHelper.getWritableDatabase();
+ }
+}
+</pre>
+<p>
+ The next snippet is the implementation of
+ {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+ SQLiteOpenHelper.onCreate()}, including a helper class:
+</p>
+<pre class="prettyprint">
+...
+// A string that defines the SQL statement for creating a table
+private static final String SQL_CREATE_MAIN = "CREATE TABLE " +
+ "main " + // Table's name
+ "(" + // The columns in the table
+ " _ID INTEGER PRIMARY KEY, " +
+ " WORD TEXT"
+ " FREQUENCY INTEGER " +
+ " LOCALE TEXT )";
+...
+/**
+ * Helper class that actually creates and manages the provider's underlying data repository.
+ */
+protected static final class MainDatabaseHelper extends SQLiteOpenHelper {
+
+ /*
+ * Instantiates an open helper for the provider's SQLite data repository
+ * Do not do database creation and upgrade here.
+ */
+ MainDatabaseHelper(Context context) {
+ super(context, DBNAME, null, 1);
+ }
+
+ /*
+ * Creates the data repository. This is called when the provider attempts to open the
+ * repository and SQLite reports that it doesn't exist.
+ */
+ public void onCreate(SQLiteDatabase db) {
+
+ // Creates the main table
+ db.execSQL(SQL_CREATE_MAIN);
+ }
+}
+</pre>
+
+
+<!-- Implementing ContentProvider MIME Types -->
+<h2 id="MIMETypes">Implementing ContentProvider MIME Types</h2>
+<p>
+ The {@link android.content.ContentProvider} class has two methods for returning MIME types:
+</p>
+<dl>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ One of the required methods that you must implement for any provider.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}
+ </dt>
+ <dd>
+ A method that you're expected to implement if your provider offers files.
+ </dd>
+</dl>
+<h3 id="TableMIMETypes">MIME types for tables</h3>
+<p>
+ The {@link android.content.ContentProvider#getType(Uri) getType()} method returns a
+ {@link java.lang.String} in MIME format that describes the type of data returned by the content
+ URI argument. The {@link android.net.Uri} argument can be a pattern rather than a specific URI;
+ in this case, you should return the type of data associated with content URIs that match the
+ pattern.
+</p>
+<p>
+ For common types of data such as as text, HTML, or JPEG,
+ {@link android.content.ContentProvider#getType(Uri) getType()} should return the standard
+ MIME type for that data. A full list of these standard types is available on the
+ <a href="http://www.iana.org/assignments/media-types/index.htm">IANA MIME Media Types</a>
+ website.
+</p>
+<p>
+ For content URIs that point to a row or rows of table data,
+ {@link android.content.ContentProvider#getType(Uri) getType()} should return
+ a MIME type in Android's vendor-specific MIME format:
+</p>
+<ul>
+ <li>
+ Type part: <code>vnd</code>
+ </li>
+ <li>
+ Subtype part:
+ <ul>
+ <li>
+ If the URI pattern is for a single row: <code>android.cursor.<strong>item</strong>/</code>
+ </li>
+ <li>
+ If the URI pattern is for more than one row: <code>android.cursor.<strong>dir</strong>/</code>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Provider-specific part: <code>vnd.&lt;name&gt;</code>.<code>&lt;type&gt;</code>
+ <p>
+ You supply the <code>&lt;name&gt;</code> and <code>&lt;type&gt;</code>.
+ The <code>&lt;name&gt;</code> value should be globally unique,
+ and the <code>&lt;type&gt;</code> value should be unique to the corresponding URI
+ pattern. A good choice for <code>&lt;name&gt;</code> is your company's name or
+ some part of your application's Android package name. A good choice for the
+ <code>&lt;type&gt;</code> is a string that identifies the table associated with the
+ URI.
+ </p>
+
+ </li>
+</ul>
+<p>
+ For example, if a provider's authority is
+ <code>com.example.app.provider</code>, and it exposes a table named
+ <code>table1</code>, the MIME type for multiple rows in <code>table1</code> is:
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>/vnd.com.example.provider.table1
+</pre>
+<p>
+ For a single row of <code>table1</code>, the MIME type is:
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>/vnd.com.example.provider.table1
+</pre>
+<h3 id="FileMIMETypes">MIME types for files</h3>
+<p>
+ If your provider offers files, implement
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}.
+ The method returns a {@link java.lang.String} array of MIME types for the files your provider
+ can return for a given content URI. You should filter the MIME types you offer by the MIME type
+ filter argument, so that you return only those MIME types that the client wants to handle.
+</p>
+<p>
+ For example, consider a provider that offers photo images as files in <code>.jpg</code>,
+ <code>.png</code>, and <code>.gif</code> format.
+ If an application calls {@link android.content.ContentResolver#getStreamTypes(Uri, String)
+ ContentResolver.getStreamTypes()} with the filter string <code>image/*</code> (something that
+ is an &quot;image&quot;),
+ then the {@link android.content.ContentProvider#getStreamTypes(Uri, String)
+ ContentProvider.getStreamTypes()} method should return the array:
+</p>
+<pre>
+{ &quot;image/jpeg&quot;, &quot;image/png&quot;, &quot;image/gif&quot;}
+</pre>
+<p>
+ If the app is only interested in <code>.jpg</code> files, then it can call
+ {@link android.content.ContentResolver#getStreamTypes(Uri, String)
+ ContentResolver.getStreamTypes()} with the filter string <code>*\/jpeg</code>, and
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String)
+ ContentProvider.getStreamTypes()} should return:
+<pre>
+{&quot;image/jpeg&quot;}
+</pre>
+<p>
+ If your provider doesn't offer any of the MIME types requested in the filter string,
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}
+ should return <code>null</code>.
+</p>
+
+
+<!-- Implementing a Contract Class -->
+<h2 id="ContractClass">Implementing a Contract Class</h2>
+<p>
+ A contract class is a <code>public final</code> class that contains constant definitions for the
+ URIs, column names, MIME types, and other meta-data that pertain to the provider. The class
+ establishes a contract between the provider and other applications by ensuring that the provider
+ can be correctly accessed even if there are changes to the actual values of URIs, column names,
+ and so forth.
+</p>
+<p>
+ A contract class also helps developers because it usually has mnemonic names for its constants,
+ so developers are less likely to use incorrect values for column names or URIs. Since it's a
+ class, it can contain Javadoc documentation. Integrated development environments such as
+ Eclipse can auto-complete constant names from the contract class and display Javadoc for the
+ constants.
+</p>
+<p>
+ Developers can't access the contract class's class file from your application, but they can
+ statically compile it into their application from a <code>.jar</code> file you provide.
+</p>
+<p>
+ The {@link android.provider.ContactsContract} class and its nested classes are examples of
+ contract classes.
+</p>
+<h2 id="Permissions">Implementing Content Provider Permissions</h2>
+<p>
+ Permissions and access for all aspects of the Android system are described in detail in the
+ topic <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>.
+ The topic <a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a> also
+ described the security and permissions in effect for various types of storage.
+ In brief, the important points are:
+</p>
+<ul>
+ <li>
+ By default, data files stored on the device's internal storage are private to your
+ application and provider.
+ </li>
+ <li>
+ {@link android.database.sqlite.SQLiteDatabase} databases you create are private to your
+ application and provider.
+ </li>
+ <li>
+ By default, data files that you save to external storage are <em>public</em> and
+ <em>world-readable</em>. You can't use a content provider to restrict access to files in
+ external storage, because other applications can use other API calls to read and write them.
+ </li>
+ <li>
+ The method calls for opening or creating files or SQLite databases on your device's internal
+ storage can potentially give both read and write access to all other applications. If you
+ use an internal file or database as your provider's repository, and you give it
+ "world-readable" or "world-writeable" access, the permissions you set for your provider in
+ its manifest won't protect your data. The default access for files and databases in
+ internal storage is "private", and for your provider's repository you shouldn't change this.
+ </li>
+</ul>
+<p>
+ If you want to use content provider permissions to control access to your data, then you should
+ store your data in internal files, SQLite databases, or the &quot;cloud&quot; (for example,
+ on a remote server), and you should keep files and databases private to your application.
+</p>
+<h3>Implementing permissions</h3>
+<p>
+ All applications can read from or write to your provider, even if the underlying data is
+ private, because by default your provider does not have permissions set. To change this,
+ set permissions for your provider in your manifest file, using attributes or child
+ elements of the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element. You can set permissions that apply to the entire provider,
+ or to certain tables, or even to certain records, or all three.
+</p>
+<p>
+ You define permissions for your provider with one or more
+ <code><a href="{@docRoot}guide/topics/manifest/permission-element.html">
+ &lt;permission&gt;</a></code> elements in your manifest file. To make the
+ permission unique to your provider, use Java-style scoping for the
+ <code><a href="{@docRoot}guide/topics/manifest/permission-element.html#nm">
+ android:name</a></code> attribute. For example, name the read permission
+ <code>com.example.app.provider.permission.READ_PROVIDER</code>.
+
+</p>
+<p>
+ The following list describes the scope of provider permissions, starting with the
+ permissions that apply to the entire provider and then becoming more fine-grained.
+ More fine-grained permissions take precedence over ones with larger scope:
+</p>
+<dl>
+ <dt>
+ Single read-write provider-level permission
+ </dt>
+ <dd>
+ One permission that controls both read and write access to the entire provider, specified
+ with the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code> attribute of the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element.
+ </dd>
+ <dt>
+ Separate read and write provider-level permission
+ </dt>
+ <dd>
+ A read permission and a write permission for the entire provider. You specify them
+ with the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">
+ android:readPermission</a></code> and
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">
+ android:writePermission</a></code> attributes of the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element. They take precedence over the permission required by
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code>.
+ </dd>
+ <dt>
+ Path-level permission
+ </dt>
+ <dd>
+ Read, write, or read/write permission for a content URI in your provider. You specify
+ each URI you want to control with a
+ <code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html">
+ &lt;path-permission&gt;</a></code> child element of the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element. For each content URI you specify, you can specify a
+ read/write permission, a read permission, or a write permission, or all three. The read and
+ write permissions take precedence over the read/write permission. Also, path-level
+ permission takes precedence over provider-level permissions.
+ </dd>
+ <dt>
+ Temporary permission
+ </dt>
+ <dd>
+ A permission level that grants temporary access to an application, even if the application
+ doesn't have the permissions that are normally required. The temporary
+ access feature reduces the number of permissions an application has to request in
+ its manifest. When you turn on temporary permissions, the only applications that need
+ &quot;permanent&quot; permissions for your provider are ones that continually access all
+ your data.
+ <p>
+ Consider the permissions you need to implement an email provider and app, when you
+ want to allow an outside image viewer application to display photo attachments from your
+ provider. To give the image viewer the necessary access without requiring permissions,
+ set up temporary permissions for content URIs for photos. Design your email app so
+ that when the user wants to display a photo, the app sends an intent containing the
+ photo's content URI and permission flags to the image viewer. The image viewer can
+ then query your email provider to retrieve the photo, even though the viewer doesn't
+ have the normal read permission for your provider.
+ </p>
+ <p>
+ To turn on temporary permissions, either set the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermissions</a></code> attribute of the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element, or add one or more
+ <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a></code> child elements to your
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element. If you use temporary permissions, you have to call
+ {@link android.content.Context#revokeUriPermission(Uri, int)
+ Context.revokeUriPermission()} whenever you remove support for a content URI from your
+ provider, and the content URI is associated with a temporary permission.
+ </p>
+ <p>
+ The attribute's value determines how much of your provider is made accessible.
+ If the attribute is set to <code>true</code>, then the system will grant temporary
+ permission to your entire provider, overriding any other permissions that are required
+ by your provider-level or path-level permissions.
+ </p>
+ <p>
+ If this flag is set to <code>false</code>, then you must add
+ <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a></code> child elements to your
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element. Each child element specifies the content URI or
+ URIs for which temporary access is granted.
+ </p>
+ <p>
+ To delegate temporary access to an application, an intent must contain
+ the {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} or the
+ {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION} flags, or both. These
+ are set with the {@link android.content.Intent#setFlags(int) setFlags()} method.
+ </p>
+ <p>
+ If the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermissions</a></code> attribute is not present, it's assumed to be
+ <code>false</code>.
+ </p>
+ </dd>
+</dl>
+
+
+
+<!-- The Provider Element -->
+<h2 id="ProviderElement">The &lt;provider&gt; Element</h2>
+<p>
+ Like {@link android.app.Activity} and {@link android.app.Service} components,
+ a subclass of {@link android.content.ContentProvider}
+ must be defined in the manifest file for its application, using the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element. The Android system gets the following information from
+ the element:
+<dl>
+ <dt>
+ Authority
+ (<a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">{@code
+ android:authorities}</a>)
+ </dt>
+ <dd>
+ Symbolic names that identify the entire provider within the system. This
+ attribute is described in more detail in the section
+ <a href="#ContentURI">Designing Content URIs</a>.
+ </dd>
+ <dt>
+ Provider class name
+ (<code>
+<a href="{@docRoot}guide/topics/manifest/provider-element.html#nm">android:name</a>
+ </code>)
+ </dt>
+ <dd>
+ The class that implements {@link android.content.ContentProvider}. This class is
+ described in more detail in the section
+ <a href="#ContentProvider">Implementing the ContentProvider Class</a>.
+ </dd>
+ <dt>
+ Permissions
+ </dt>
+ <dd>
+ Attributes that specify the permissions that other applications must have in order to access
+ the provider's data:
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermssions</a></code>: Temporary permission flag.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code>: Single provider-wide read/write permission.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">
+ android:readPermission</a></code>: Provider-wide read permission.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">
+ android:writePermission</a></code>: Provider-wide write permission.
+ </li>
+ </ul>
+ <p>
+ Permissions and their corresponding attributes are described in more
+ detail in the section
+ <a href="#Permissions">Implementing Content Provider Permissions</a>.
+ </p>
+ </dd>
+ <dt>
+ Startup and control attributes
+ </dt>
+ <dd>
+ These attributes determine how and when the Android system starts the provider, the
+ process characteristics of the provider, and other run-time settings:
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#enabled">
+ android:enabled</a></code>: Flag allowing the system to start the provider.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
+ android:exported</a></code>: Flag allowing other applications to use this provider.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#init">
+ android:initOrder</a></code>: The order in which this provider should be started,
+ relative to other providers in the same process.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#multi">
+ android:multiProcess</a></code>: Flag allowing the system to start the provider
+ in the same process as the calling client.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#proc">
+ android:process</a></code>: The name of the process in which the provider should
+ run.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#sync">
+ android:syncable</a></code>: Flag indicating that the provider's data is to be
+ sync'ed with data on a server.
+ </li>
+ </ul>
+ <p>
+ The attributes are fully documented in the dev guide topic for the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>
+ element.
+ </p>
+ </dd>
+ <dt>
+ Informational attributes
+ </dt>
+ <dd>
+ An optional icon and label for the provider:
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#icon">
+ android:icon</a></code>: A drawable resource containing an icon for the provider.
+ The icon appears next to the provider's label in the list of apps in
+ <em>Settings</em> &gt; <em>Apps</em> &gt; <em>All</em>.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#label">
+ android:label</a></code>: An informational label describing the provider or its
+ data, or both. The label appears in the list of apps in
+ <em>Settings</em> &gt; <em>Apps</em> &gt; <em>All</em>.
+ </li>
+ </ul>
+ <p>
+ The attributes are fully documented in the dev guide topic for the
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> element.
+ </p>
+ </dd>
+</dl>
+
+<!-- Intent Access -->
+<h2 id="Intents">Intents and Data Access</h2>
+<p>
+ Applications can access a content provider indirectly with an {@link android.content.Intent}.
+ The application does not call any of the methods of {@link android.content.ContentResolver} or
+ {@link android.content.ContentProvider}. Instead, it sends an intent that starts an activity,
+ which is often part of the provider's own application. The destination activity is in charge of
+ retrieving and displaying the data in its UI. Depending on the action in the intent, the
+ destination activity may also prompt the user to make modifications to the provider's data.
+ An intent may also contain &quot;extras&quot; data that the destination activity displays
+ in the UI; the user then has the option of changing this data before using it to modify the
+ data in the provider.
+</p>
+<p>
+
+</p>
+<p>
+ You may want to use intent access to help ensure data integrity. Your provider may depend
+ on having data inserted, updated, and deleted according to strictly defined business logic. If
+ this is the case, allowing other applications to directly modify your data may lead to
+ invalid data. If you want developers to use intent access, be sure to document it thoroughly.
+ Explain to them why intent access using your own application's UI is better than trying to
+ modify the data with their code.
+</p>
+<p>
+ Handling an incoming intent that wishes to modify your provider's data is no different from
+ handling other intents. You can learn more about using intents by reading the topic
+ <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>.
+</p>
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index 95331ce38519..1707f038b3ce 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -1,922 +1,96 @@
page.title=Content Providers
@jd:body
-
<div id="qv-wrapper">
<div id="qv">
-<h2>In this document</h2>
-<ol>
-<li><a href="#basics">Content provider basics</a></li>
-<li><a href="#querying">Querying a content provider</a></li>
-<li><a href="#modifying">Modifying data in a provider</a></li>
-<li><a href="#creating">Creating a content provider</a></li>
-<li><a href="#urisum">Content URI summary</a></li>
-</ol>
-<h2>Key classes</h2>
+<!-- In this document -->
+<h2>Topics</h2>
<ol>
-<li>{@link android.content.ContentProvider}</li>
-<li>{@link android.content.ContentResolver}</li>
-<li>{@link android.database.Cursor}</li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Creating a Content Provider</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a>
+ </li>
</ol>
-<h2>See also</h2>
-<ol>
- <li><a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a></li>
-</ol>
+ <!-- Related Samples -->
+<h2>Related Samples</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">
+ Contact Manager</a> application
+ </li>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ &quot;Cursor (People)&quot;
+ </a>
+ </li>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ &quot;Cursor (Phones)&quot;</a>
+ </li>
+ </ol>
</div>
</div>
-
-<p>
-Content providers store and retrieve data and make it accessible to all
-applications. They're the only way to share data across applications; there's
-no common storage area that all Android packages can access.
-</p>
-
-<p>
-Android ships with a number of content providers for common data types
-(audio, video, images, personal contact information, and so on). You can
-see some of them listed in the {@link android.provider android.provider}
-package. You can query these providers for the data they contain (although,
-for some, you must acquire the proper permission to read the data).
-</p>
-
-<p class="note"><strong>Note:</strong> Android 4.0 introduces the Calendar
-Provider. For more information, see <a
-href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar
-Provider</a>.</p>
-<p>
-If you want to make your own data public, you have two options: You can
-create your own content provider (a {@link android.content.ContentProvider}
-subclass) or you can add the data to an existing provider &mdash; if there's
-one that controls the same type of data and you have permission to write to it.
-</p>
-
-<p>
-This document is an introduction to using content providers. After a
-brief discussion of the fundamentals, it explores how to query a content
-provider, how to modify data controlled by a provider, and how to create
-a content provider of your own.
-</p>
-
-
-<h2><a name="basics"></a>Content Provider Basics</h2>
-
-<p>
-How a content provider actually stores its data under the covers is
-up to its designer. But all content providers implement a common interface
-for querying the provider and returning results &mdash; as well as for
-adding, altering, and deleting data.
-</p>
-
-<p>
-It's an interface that clients use indirectly, most generally through
-{@link android.content.ContentResolver} objects. You get a ContentResolver
-by calling <code>{@link android.content.Context#getContentResolver
-getContentResolver()}</code> from within the implementation of an Activity
-or other application component:
-</p>
-
-<pre>ContentResolver cr = getContentResolver();</pre>
-
-<p>
-You can then use the ContentResolver's methods to interact with whatever
-content providers you're interested in.
-</p>
-
-<p>
-When a query is initiated, the Android system identifies the content provider
-that's the target of the query and makes sure that it is up and running.
-The system instantiates all ContentProvider objects; you never need to do it
-on your own. In fact, you never deal directly with ContentProvider objects
-at all. Typically, there's just a single instance of each type of
-ContentProvider. But it can communicate with multiple ContentResolver objects
-in different applications and processes. The interaction between processes is
-handled by the ContentResolver and ContentProvider classes.
-</p>
-
-
-<h3>The data model</h3>
-
-<p>
-Content providers expose their data as a simple table on a database model,
-where each row is a record and each column is data of a particular type
-and meaning. For example, information about people and their phone numbers
-might be exposed as follows:
-</p>
-
-<table>
- <tr>
- <th scope="col">_ID</th>
- <th scope="col">NUMBER</th>
- <th scope="col">NUMBER_KEY</th>
- <th scope="col">LABEL</th>
- <th scope="col">NAME</th>
- <th scope="col">TYPE</th>
- </tr>
- <tr>
- <td>13</td>
- <td>(425) 555 6677</td>
- <td>425 555 6677</td>
- <td>Kirkland office</td>
- <td>Bully Pulpit</td>
- <td>{@code TYPE_WORK}</td>
- </tr>
- <tr>
- <td>44</td>
- <td>(212) 555-1234</td>
- <td>212 555 1234</td>
- <td>NY apartment</td>
- <td>Alan Vain</td>
- <td>{@code TYPE_HOME}</td>
- </tr>
- <tr>
- <td>45</td>
- <td>(212) 555-6657</td>
- <td>212 555 6657</td>
- <td>Downtown office</td>
- <td>Alan Vain</td>
- <td>{@code TYPE_MOBILE}</td>
- </tr>
- <tr>
- <td>53</td>
- <td>201.555.4433</td>
- <td>201 555 4433</td>
- <td>Love Nest</td>
- <td>Rex Cars</td>
- <td>{@code TYPE_HOME}</td>
- </tr>
-</table>
-
-<p>
-Every record includes a numeric {@code _ID} field that uniquely identifies
-the record within the table. IDs can be used to match records in related
-tables &mdash; for example, to find a person's phone number in one table
-and pictures of that person in another.
-</p>
-
-<p>
-A query returns a {@link android.database.Cursor} object that can move from
-record to record and column to column to read the contents of each field.
-It has specialized methods for reading each type of data. So, to read a field,
-you must know what type of data the field contains. (There's more on query
-results and Cursor objects later.)
-</p>
-
-
-<h3><a name="uri"></a>URIs</h3>
-
-<p>
-Each content provider exposes a public URI (wrapped as a {@link android.net.Uri}
-object) that uniquely identifies its data set. A content provider that controls
-multiple data sets (multiple tables) exposes a separate URI for each one. All
-URIs for providers begin with the string "{@code content://}". The {@code content:}
-scheme identifies the data as being controlled by a content provider.
-</p>
-
-<p>
-If you're defining a content provider, it's a good idea to also define a
-constant for its URI, to simplify client code and make future updates cleaner.
-Android defines {@code CONTENT_URI} constants for all the providers that come
-with the platform. For example, the URI for the table that matches
-phone numbers to people and the URI for the table that holds pictures of
-people (both controlled by the Contacts content provider) are:
-</p>
-
-<p>
-<p style="margin-left: 2em">{@code android.provider.Contacts.Phones.CONTENT_URI}
-<br/>{@code android.provider.Contacts.Photos.CONTENT_URI}
-</p>
-
-<p>
-The URI constant is used in all interactions with the content provider.
-Every {@link android.content.ContentResolver} method takes the URI
-as its first argument. It's what identifies which provider the ContentResolver
-should talk to and which table of the provider is being targeted.
-</p>
-
-
-<h2><a name="querying"></a>Querying a Content Provider</h2>
-
-<p>
-You need three pieces of information to query a content provider:
-</p>
-
-<ul>
-<li>The URI that identifies the provider</li>
-<li>The names of the data fields you want to receive</li>
-<li>The data types for those fields</li>
-</ul>
-
-<p>
-If you're querying a particular record, you also need the ID for that record.
-</p>
-
-
-<h3>Making the query</h3>
-
-<p>
-To query a content provider, you can use either the
-<code>{@link android.content.ContentResolver#query ContentResolver.query()}</code>
-method or the <code>{@link android.app.Activity#managedQuery
-Activity.managedQuery()}</code> method.
-Both methods take the same set of arguments, and both return a
-Cursor object. However, {@code managedQuery()}
-causes the activity to manage the life cycle of the Cursor. A managed Cursor
-handles all of the niceties, such as unloading itself when the activity pauses,
-and requerying itself when the activity restarts. You can ask an Activity to
-begin managing an unmanaged Cursor object for you by calling
-<code>{@link android.app.Activity#startManagingCursor
-Activity.startManagingCursor()}</code>.
-</p>
-
-<p>
-The first argument to either <code>{@link android.content.ContentResolver#query query()}</code>
-or <code>{@link android.app.Activity#managedQuery managedQuery()}</code> is the provider URI
-&mdash; the {@code CONTENT_URI} constant that identifies a particular
-ContentProvider and data set (see <a href="#uri">URIs</a> earlier).
-</p>
-
-<p>
-To restrict a query to just one record, you can append the {@code _ID} value for
-that record to the URI &mdash; that is, place a string matching the ID as the
-last segment of the path part of the URI. For example, if the ID is 23,
-the URI would be:
-</p>
-
-<p style="margin-left: 2em">{@code content://. . . ./23}</p>
-
-<p>
-There are some helper methods, particularly
-<code>{@link android.content.ContentUris#withAppendedId
-ContentUris.withAppendedId()}</code> and <code>{@link
-android.net.Uri#withAppendedPath Uri.withAppendedPath()}</code>,
-that make it easy to append an ID to a URI. Both are static methods that return
-a Uri object with the ID added. So, for example, if you were looking for record
-23 in the database of people contacts, you might construct a query as follows:
-</p>
-
-<pre>
-import android.provider.Contacts.People;
-import android.content.ContentUris;
-import android.net.Uri;
-import android.database.Cursor;
-
-// Use the ContentUris method to produce the base URI for the contact with _ID == 23.
-Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23);
-
-// Alternatively, use the Uri method to produce the base URI.
-// It takes a string rather than an integer.
-Uri myPerson = Uri.withAppendedPath(People.CONTENT_URI, "23");
-
-// Then query for this specific record:
-Cursor cur = managedQuery(myPerson, null, null, null, null);
-</pre>
-
-<p>
-The other arguments to the <code>{@link android.content.ContentResolver#query query()}</code>
-and <code>{@link android.app.Activity#managedQuery managedQuery()}</code> methods delimit
-the query in more detail. They are:
-</p>
-
-<ul>
-<li>The names of the data columns that should be returned. A {@code null}
-value returns all columns. Otherwise, only columns that are listed by name
-are returned. All the content providers that come with the platform define
-constants for their columns. For example, the
-{@link android.provider.Contacts.Phones android.provider.Contacts.Phones} class
-defines constants for the names of the columns in the phone table illustrated
-earlier &mdash; {@code _ID}, {@code NUMBER}, {@code NUMBER_KEY}, {@code NAME},
-and so on.</li>
-
-<li><p>A filter detailing which rows to return, formatted as an SQL {@code WHERE}
-clause (excluding the {@code WHERE} itself). A {@code null} value returns
-all rows (unless the URI limits the query to a single record).</p></li>
-
-<li><p>Selection arguments.</p></li>
-
-<li><p>A sorting order for the rows that are returned, formatted as an SQL
-{@code ORDER BY} clause (excluding the {@code ORDER BY} itself). A {@code null}
-value returns the records in the default order for the table, which may be
-unordered.</p></li>
-</ul>
-
-<p>
-Let's look at an example query to retrieve a list of contact names and their
-primary phone numbers:
-</p>
-
-<pre>
-import android.provider.Contacts.People;
-import android.database.Cursor;
-
-// Form an array specifying which columns to return.
-String[] projection = new String[] {
- People._ID,
- People._COUNT,
- People.NAME,
- People.NUMBER
- };
-
-// Get the base URI for the People table in the Contacts content provider.
-Uri contacts = People.CONTENT_URI;
-
-// Make the query.
-Cursor managedCursor = managedQuery(contacts,
- projection, // Which columns to return
- null, // Which rows to return (all rows)
- null, // Selection arguments (none)
- // Put the results in ascending order by name
- People.NAME + " ASC");
-</pre>
-
-<p>
-This query retrieves data from the People table of the Contacts content
-provider. It gets the name, primary phone number, and unique record ID for
-each contact. It also reports the number of records that are returned as
-the {@code _COUNT} field of each record.
-</p>
-
-<p>
-The constants for the names of the columns are defined in various interfaces
-&mdash; {@code _ID} and {@code _COUNT} in
-{@link android.provider.BaseColumns BaseColumns}, {@code NAME} in {@link android.provider.Contacts.PeopleColumns PeopleColumns}, and {@code NUMBER}
-in {@link android.provider.Contacts.PhonesColumns PhoneColumns}. The
-{@link android.provider.Contacts.People Contacts.People} class implements
-each of these interfaces, which is why the code example above could refer
-to them using just the class name.
-</p>
-
-
-<h3>What a query returns</h3>
-
-<p>
-A query returns a set of zero or more database records. The names of the
-columns, their default order, and their data types are specific to each
-content provider.
-But every provider has an {@code _ID} column, which holds a unique numeric
-ID for each record. Every provider can also report the number
-of records returned as the {@code _COUNT} column; its value
-is the same for all rows.
-</p>
-
-<p>
-Here is an example result set for the query in the previous section:
-</p>
-
-<table border="1">
- <tbody>
- <tr>
- <th scope="col">_ID</th>
- <th scope="col">_COUNT</th>
- <th scope="col">NAME</th>
- <th scope="col">NUMBER</th>
- </tr>
- <tr>
- <td>44</td>
- <td>3</td>
- <td>Alan Vain</td>
- <td>212 555 1234</td>
- </tr>
- <tr>
- <td>13</td>
- <td>3</td>
- <td>Bully Pulpit</td>
- <td>425 555 6677</td>
- </tr>
- <tr>
- <td>53</td>
- <td>3</td>
- <td>Rex Cars</td>
- <td>201 555 4433</td>
- </tr>
- </tbody>
-</table>
-
-<p>
-The retrieved data is exposed by a {@link android.database.Cursor Cursor}
-object that can be used to iterate backward or forward through the result
-set. You can use this object only to read the data. To add, modify, or
-delete data, you must use a ContentResolver object.
-</p>
-
-
-<h3>Reading retrieved data</h3>
-
-<p>
-The Cursor object returned by a query provides access to a recordset of
-results. If you have queried for a specific record by ID, this set will
-contain only one value. Otherwise, it can contain multiple values.
-(If there are no matches, it can also be empty.) You
-can read data from specific fields in the record, but you must know the
-data type of the field, because the Cursor object has a separate method
-for reading each type of data &mdash; such as <code>{@link
-android.database.Cursor#getString getString()}</code>, <code>{@link
-android.database.Cursor#getInt getInt()}</code>, and <code>{@link
-android.database.Cursor#getFloat getFloat()}</code>.
-(However, for most types, if you call the method for reading strings,
-the Cursor object will give you the String representation of the data.)
-The Cursor lets you request the column name from the index of the column,
-or the index number from the column name.
-</p>
-
-<p>
-The following snippet demonstrates reading names and phone numbers from
-the query illustrated earlier:
-</p>
-
-<pre>
-import android.provider.Contacts.People;
-
-private void getColumnData(Cursor cur){
- if (cur.moveToFirst()) {
-
- String name;
- String phoneNumber;
- int nameColumn = cur.getColumnIndex(People.NAME);
- int phoneColumn = cur.getColumnIndex(People.NUMBER);
- String imagePath;
-
- do {
- // Get the field values
- name = cur.getString(nameColumn);
- phoneNumber = cur.getString(phoneColumn);
-
- // Do something with the values.
- ...
-
- } while (cur.moveToNext());
-
- }
-}
-</pre>
-
-<p>
-If a query can return binary data, such as an image or sound, the data
-may be directly entered in the table or the table entry for that data may be
-a string specifying a {@code content:} URI that you can use to get the data.
-In general, smaller amounts of data (say, from 20 to 50K or less) are most often
-directly entered in the table and can be read by calling
-<code>{@link android.database.Cursor#getBlob Cursor.getBlob()}</code>.
-It returns a byte array.
-</p>
-
-<p>
-If the table entry is a {@code content:} URI, you should never try to open
-and read the file directly (for one thing, permissions problems can make this
-fail). Instead, you should call
-<code>{@link android.content.ContentResolver#openInputStream
-ContentResolver.openInputStream()}</code> to get an
-{@link java.io.InputStream} object that you can use to read the data.
-</p>
-
-
-<h2><a name="modifying"></a>Modifying Data</h2>
-
-<p>
-Data kept by a content provider can be modified by:
-</p>
-
-<ul>
-<p><li>Adding new records</li>
-<li>Adding new values to existing records</li>
-<li>Batch updating existing records</li>
-<li>Deleting records</li>
-</ul>
-
-<p>
-All data modification is accomplished using {@link android.content.ContentResolver}
-methods. Some content providers require a more restrictive permission for writing
-data than they do for reading it. If you don't have permission to write to a
-content provider, the ContentResolver methods will fail.
-</p>
-
-
-<h3>Adding records</h3>
-
-<p>
-To add a new record to a content provider, first set up a map of key-value pairs
-in a {@link android.content.ContentValues} object, where each key matches
-the name of a column in the content provider and the value is the desired
-value for the new record in that column. Then call <code>{@link
-android.content.ContentResolver#insert ContentResolver.insert()}</code> and pass
-it the URI of the provider and the ContentValues map. This method returns
-the full URI of the new record &mdash; that is, the provider's URI with
-the appended ID for the new record. You can then use this URI to query and
-get a Cursor over the new record, and to further modify the record.
-Here's an example:
-</p>
-
-<pre>
-import android.provider.Contacts.People;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-
-ContentValues values = new ContentValues();
-
-// Add Abraham Lincoln to contacts and make him a favorite.
-values.put(People.NAME, "Abraham Lincoln");
-// 1 = the new contact is added to favorites
-// 0 = the new contact is not added to favorites
-values.put(People.STARRED, 1);
-
-Uri uri = getContentResolver().insert(People.CONTENT_URI, values);
-</pre>
-
-
-<h3>Adding new values</h3>
-
-<p>
-Once a record exists, you can add new information to it or modify
-existing information. For example, the next step in the example above would
-be to add contact information &mdash; like a phone number or an IM or e-mail
-address &mdash; to the new entry.
-</p>
-
-<p>
-The best way to add to a record in the Contacts database is to append
-the name of the table where the new data goes to the URI for the
-record, then use the amended URI to add the new data values. Each
-Contacts table exposes a name for this purpose as a {@code
-CONTENT_DIRECTORY} constant. The following code continues the previous
-example by adding a phone number and e-mail address for the record
-just created:
-</p>
-
-<pre>
-Uri phoneUri = null;
-Uri emailUri = null;
-
-// Add a phone number for Abraham Lincoln. Begin with the URI for
-// the new record just returned by insert(); it ends with the _ID
-// of the new record, so we don't have to add the ID ourselves.
-// Then append the designation for the phone table to this URI,
-// and use the resulting URI to insert the phone number.
-phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
-
-values.clear();
-values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE);
-values.put(People.Phones.NUMBER, "1233214567");
-getContentResolver().insert(phoneUri, values);
-
-// Now add an email address in the same way.
-emailUri = Uri.withAppendedPath(uri, People.ContactMethods.CONTENT_DIRECTORY);
-
-values.clear();
-// ContactMethods.KIND is used to distinguish different kinds of
-// contact methods, such as email, IM, etc.
-values.put(People.ContactMethods.KIND, Contacts.KIND_EMAIL);
-values.put(People.ContactMethods.DATA, "test@example.com");
-values.put(People.ContactMethods.TYPE, People.ContactMethods.TYPE_HOME);
-getContentResolver().insert(emailUri, values);
-</pre>
-
-<p>
-You can place small amounts of binary data into a table by calling
-the version of <code>{@link android.content.ContentValues#put
-ContentValues.put()}</code> that takes a byte array.
-That would work for a small icon-like image or a short audio clip, for example.
-However, if you have a large amount of binary data to add, such as a photograph
-or a complete song, put a {@code content:} URI for the data in the table and call
-<code>{@link android.content.ContentResolver#openOutputStream
-ContentResolver.openOutputStream()}</code>
-with the file's URI. (That causes the content provider to store the data
-in a file and record the file path in a hidden field of the record.)
-</p>
-
-<p>
-In this regard, the {@link android.provider.MediaStore} content
-provider, the main provider that dispenses image, audio, and video
-data, employs a special convention: The same URI that is used with
-{@code query()} or {@code managedQuery()} to get meta-information
-about the binary data (such as, the caption of a photograph or the
-date it was taken) is used with {@code openInputStream()}
-to get the data itself. Similarly, the same URI that is used with
-{@code insert()} to put meta-information into a MediaStore record
-is used with {@code openOutputStream()} to place the binary data there.
-The following code snippet illustrates this convention:
-</p>
-
-<pre>
-import android.provider.MediaStore.Images.Media;
-import android.content.ContentValues;
-import java.io.OutputStream;
-
-// Save the name and description of an image in a ContentValues map.
-ContentValues values = new ContentValues(3);
-values.put(Media.DISPLAY_NAME, "road_trip_1");
-values.put(Media.DESCRIPTION, "Day 1, trip to Los Angeles");
-values.put(Media.MIME_TYPE, "image/jpeg");
-
-// Add a new record without the bitmap, but with the values just set.
-// insert() returns the URI of the new record.
-Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
-
-// Now get a handle to the file for that record, and save the data into it.
-// Here, sourceBitmap is a Bitmap object representing the file to save to the database.
-try {
- OutputStream outStream = getContentResolver().openOutputStream(uri);
- sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);
- outStream.close();
-} catch (Exception e) {
- Log.e(TAG, "exception while writing image", e);
-}
-</pre>
-
-
-<h3>Batch updating records</h3>
-
-<p>
-To batch update a group of records (for example, to change "NY" to "New York"
-in all fields), call the <code>{@link
-android.content.ContentResolver#update ContentResolver.update()}</code>
-method with the columns and values to change.
-</p>
-
-
-<h3><a name="deletingrecord"></a>Deleting a record</h3>
-
-<p>
-To delete a single record, call {<code>{@link
-android.content.ContentResolver#delete ContentResolver.delete()}</code>
-with the URI of a specific row.
-</p>
-
<p>
-To delete multiple rows, call <code>{@link
-android.content.ContentResolver#delete ContentResolver.delete()}</code>
-with the URI of the type of record to delete (for example, {@code android.provider.Contacts.People.CONTENT_URI}) and an SQL {@code WHERE}
-clause defining which rows to delete. (<i><b>Caution</b>:
-Be sure to include a valid {@code WHERE} clause if you're deleting a general
-type, or you risk deleting more records than you intended!</i>).
-</p>
-
-
-<h2><a name="creating"></a>Creating a Content Provider</h2>
-
-<p>
-To create a content provider, you must:
-</p>
-
-<ul>
-<li>Set up a system for storing the data. Most content providers
-store their data using Android's file storage methods or SQLite databases,
-but you can store your data any way you want. Android provides the
-{@link android.database.sqlite.SQLiteOpenHelper SQLiteOpenHelper}
-class to help you create a database and {@link
-android.database.sqlite.SQLiteDatabase SQLiteDatabase} to manage it.</li>
-
-<li><p>Extend the {@link android.content.ContentProvider} class to provide
-access to the data.</p></li>
-
-<li><p>Declare the content provider in the manifest file for your
-application (AndroidManifest.xml).</p></li>
-</ul>
-
-<p>
-The following sections have notes on the last two of these tasks.
-</p>
-
-
-<h3>Extending the ContentProvider class</h3>
-
-<p>
-You define a {@link android.content.ContentProvider} subclass to
-expose your data to others using the conventions expected by
-ContentResolver and Cursor objects. Principally, this means
-implementing six abstract methods declared in the ContentProvider class:
-</p>
-
-<p style="margin-left: 2em">{@code query()}
-<br/>{@code insert()}
-<br/>{@code update()}
-<br/>{@code delete()}
-<br/>{@code getType()}
-<br/>{@code onCreate()}</p>
-
-<p>
-The {@code query()} method must return a {@link android.database.Cursor} object
-that can iterate over the requested data. Cursor itself is an interface, but
-Android provides some ready-made Cursor objects that you can use. For example,
-{@link android.database.sqlite.SQLiteCursor} can iterate over data stored in
-an SQLite database. You get the Cursor object by calling any of the {@link
-android.database.sqlite.SQLiteDatabase SQLiteDatabase} class's {@code query()}
-methods. There are other Cursor implementations &mdash; such as {@link
-android.database.MatrixCursor} &mdash; for data not stored in a database.
-</p>
-
-<p>
-Because these ContentProvider methods can be called from
-various ContentResolver objects in different processes and threads,
-they must be implemented in a thread-safe manner.
-</p>
-
-<p>
-As a courtesy, you might also want to call <code>{@link android.content.ContentResolver#notifyChange(android.net.Uri,android.database.ContentObserver)
-ContentResolver.notifyChange()}</code> to notify listeners when there are
-modifications to the data.
-</p>
-
-<p>
-Beyond defining the subclass itself, there are other steps you should take
-to simplify the work of clients and make the class more accessible:
-</p>
-
-<ul>
-<li>Define a {@code public static final} {@link android.net.Uri}
-named {@code CONTENT_URI}. This is the string that represents the full
-{@code content:} URI that your content provider handles. You must define a
-unique string for this value. The best solution is to use the fully-qualified
-class name of the content provider (made lowercase). So, for example, the
-URI for a TransportationProvider class could be defined as follows:
-
-<pre>public static final Uri CONTENT_URI =
- Uri.parse("content://com.example.codelab.transportationprovider");</pre>
-
-<p>
-If the provider has subtables, also define {@code CONTENT_URI} constants for
-each of the subtables. These URIs should all have the same authority (since
-that identifies the content provider), and be distinguished only by their paths.
-For example:
-</p>
-
-<p style="margin-left: 2em">{@code content://com.example.codelab.transportationprovider/train}
-<br/>{@code content://com.example.codelab.transportationprovider/air/domestic}
-<br/>{@code content://com.example.codelab.transportationprovider/air/international}</p>
-
-<p>
-For an overview of {@code content:} URIs, see the <a href="#urisum">Content URI
-Summary</a> at the end of this document.
-</p></li>
-
-<li><p>Define the column names that the content provider will return to clients.
-If you are using an underlying database, these column names are typically
-identical to the SQL database column names they represent. Also define
-{@code public static} String constants that clients can use to specify
-the columns in queries and other instructions.
-</p>
-
-<p>
-Be sure to include an integer column named "{@code _id}"
-(with the constant {@code _ID}) for
-the IDs of the records. You should have this field whether or not you have
-another field (such as a URL) that is also unique among all records. If
-you're using the SQLite database, the {@code _ID} field should be the
-following type:
-</p>
-
-<p style="margin-left: 2em">{@code INTEGER PRIMARY KEY AUTOINCREMENT}</p>
-
-<p>
-The {@code AUTOINCREMENT} descriptor is optional. But without it, SQLite
-increments an ID counter field to the next number above the largest
-existing number in the column. If you delete the last row, the next row added
-will have the same ID as the deleted row. {@code AUTOINCREMENT} avoids this
-by having SQLite increment to the next largest value whether deleted or not.
-</p>
-</li>
-
-<li><p>Carefully document the data type of each column. Clients need this
-information to read the data.</p></li>
-
-<li><p>If you are handling a new data type, you must define a new MIME type
-to return in your implementation of <code>{@link
-android.content.ContentProvider#getType ContentProvider.getType()}</code>.
-The type depends in part on whether or not the {@code content:} URI submitted
-to {@code getType()} limits the request to a specific record. There's one
-form of the MIME type for a single record and another for multiple records.
-Use the {@link android.net.Uri Uri} methods to help determine what is being
-requested. Here is the general format for each type:</p></li>
-
-<ul>
-<li><p>For a single record:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.item/vnd.<em>yourcompanyname.contenttype</em>}</p>
-
-<p>For example, a request for train record 122, like this URI,</p>
-<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains/122}</p>
-
-<p>might return this MIME type:</p>
-<p style="margin-left: 2em">{@code vnd.android.cursor.item/vnd.example.rail}</p>
-</li>
-
-<li><p>For multiple records:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.dir/vnd.<em>yourcompanyname.contenttype</em>}</p>
-
-<p>For example, a request for all train records, like the following URI,</p>
-<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains}</p>
-
-<p>might return this MIME type:</p>
-<p style="margin-left: 2em">{@code vnd.android.cursor.dir/vnd.example.rail}</p>
-</li>
-</ul>
-
-<li><p>If you are exposing byte data that's too big to put in the table itself
-&mdash; such as a large bitmap file &mdash; the field that exposes the
-data to clients should actually contain a {@code content:} URI string.
-This is the field that gives clients access to the data file. The record
-should also have another field, named "{@code _data}" that lists the exact file
-path on the device for that file. This field is not intended to be read by
-the client, but by the ContentResolver. The client will call <code>{@link
-android.content.ContentResolver#openInputStream ContentResolver.openInputStream()}</code>
-on the user-facing field holding the URI for the item. The ContentResolver
-will request the "{@code _data}" field for that record, and because
-it has higher permissions than a client, it should be able to access
-that file directly and return a read wrapper for the file to the client.</p></li>
-
-</ul>
-
-<p>
-For an example of a private content provider implementation, see the
-NodePadProvider class in the Notepad sample application that ships with the SDK.
-</p>
-
-
-<h3>Declaring the content provider</h3>
-
-<p>
-To let the Android system know about the content provider you've developed,
-declare it with a {@code &lt;provider&gt;} element in the application's
-AndroidManifest.xml file. Content providers that are not declared in the
-manifest are not visible to the Android system
-</p>
-
-<p>
-The {@code name} attribute is the fully qualified name of the ContentProvider
-subclass. The {@code authorities} attribute is the authority part of the
-{@code content:} URI that identifies the provider.
-For example if the ContentProvider subclass is AutoInfoProvider, the
-{@code &lt;provider&gt;} element might look like this:
-</p>
-
-<pre>
-&lt;provider android:name="com.example.autos.AutoInfoProvider"
- android:authorities="com.example.autos.autoinfoprovider"
- . . . /&gt
-&lt;/provider&gt;
-</pre>
-
-<p>
-Note that the {@code authorities} attribute omits the path part of a
-{@code content:} URI. For example, if AutoInfoProvider controlled subtables
-for different types of autos or different manufacturers,
-</p>
-
-<p style="margin-left: 2em">{@code content://com.example.autos.autoinfoprovider/honda}
-<br/>{@code content://com.example.autos.autoinfoprovider/gm/compact}
-<br/>{@code content://com.example.autos.autoinfoprovider/gm/suv}</p>
-
-<p>
-those paths would not be declared in the manifest. The authority is what
-identifies the provider, not the path; your provider can interpret the path
-part of the URI in any way you choose.
-</p>
-
-<p>
-Other {@code &lt;provider&gt;} attributes can set permissions to read and
-write data, provide for an icon and text that can be displayed to users,
-enable and disable the provider, and so on. Set the {@code multiprocess}
-attribute to "{@code true}" if data does not need to be synchronized between
-multiple running versions of the content provider. This permits an instance
-of the provider to be created in each client process, eliminating the need
-to perform IPC.
-</p>
-
-
-<h2><a name="urisum"></a>Content URI Summary</h2>
-
-<p>
-Here is a recap of the important parts of a content URI:
-</p>
-
-<p>
-<img src="{@docRoot}images/content_uri.png" alt="Elements of a content URI"
-height="80" width="528">
-</p>
-
-<ol type="A">
-<li>Standard prefix indicating that the data is controlled by a
-content provider. It's never modified.</li>
-
-<li><p>The authority part of the URI; it identifies the content provider.
-For third-party applications, this should be a fully-qualified class name
-(reduced to lowercase) to ensure uniqueness. The authority is declared in
-the {@code &lt;provider&gt;} element's {@code authorities} attribute:</p>
-
-<pre>&lt;provider android:name=".TransportationProvider"
- android:authorities="com.example.transportationprovider"
- . . . &gt;</pre></li>
-
-<li><p>The path that the content provider uses to determine what kind of data is
-being requested. This can be zero or more segments long. If the content provider
-exposes only one type of data (only trains, for example), it can be absent.
-If the provider exposes several types, including subtypes, it can be several
-segments long &mdash; for example, "{@code land/bus}", "{@code land/train}",
-"{@code sea/ship}", and "{@code sea/submarine}" to give four possibilities.</p></li>
-
-<li><p>The ID of the specific record being requested, if any. This is the
-{@code _ID} value of the requested record. If the request is not limited to
-a single record, this segment and the trailing slash are omitted:</p>
-
-<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains}</p>
-</li>
-</ol>
-
-
+ Content providers manage access to a structured set of data. They encapsulate the
+ data, and provide mechanisms for defining data security. Content providers are the standard
+ interface that connects data in one process with code running in another process.
+</p>
+<p>
+ When you want to access data in a content provider, you use the
+ {@link android.content.ContentResolver} object in your
+ application's {@link android.content.Context} to communicate with the provider as a client.
+ The {@link android.content.ContentResolver} object communicates with the provider object, an
+ instance of a class that implements {@link android.content.ContentProvider}. The provider
+ object receives data requests from clients, performs the requested action, and
+ returns the results.
+</p>
+<p>
+ You don't need to develop your own provider if you don't intend to share your data with
+ other applications. However, you do need your own provider to provide custom search
+ suggestions in your own application. You also need your own provider if you want to copy and
+ paste complex data or files from your application to other applications.
+</p>
+<p>
+ Android itself includes content providers that manage data such as audio, video, images, and
+ personal contact information. You can see some of them listed in the reference
+ documentation for the
+ <code><a href="{@docRoot}reference/android/provider/package-summary.html">android.provider</a>
+ </code> package. With some restrictions, these providers are accessible to any Android
+ application.
+</p><p>
+ The following topics describe content providers in more detail:
+</p>
+<dl>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a></strong>
+ </dt>
+ <dd>
+ How to access data in a content provider when the data is organized in tables.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Creating a Content Provider</a></strong>
+ </dt>
+ <dd>
+ How to create your own content provider.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Calendar Provider</a></strong>
+ </dt>
+ <dd>
+ How to access the Calendar Provider that is part of the Android platform.
+ </dd>
+</dl>
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index b83bde75dd2a..e59fa0f1aaca 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -113,9 +113,10 @@ accessible to the user in a predictable way.
href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">options menu</a> directly in the action bar,
as "action items." Action items can also provide an "action view," which provides an embedded
widget for even more immediate action behaviors. Menu items that are not promoted
-to an action item are available in the overflow menu, revealed by either the device MENU button
+to an action item are available in the overflow menu, revealed by either the device <em>Menu</em>
+button
(when available) or by an "overflow menu" button in the action bar (when the device does not
-include a MENU button).</p>
+include a <em>Menu</em> button).</p>
</li>
</ul>
@@ -125,6 +126,10 @@ href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery
landscape handset), showing the logo on the left, navigation tabs, and an action item on the
right (plus the overflow menu button).</p>
+<p class="note"><strong>Note:</strong> If you're looking for information about the contextual
+action bar for displaying contextual action items, see the <a
+href="{@docRoot}guide/topics/ui/menus.html#context-menu">Menu</a> guide.</p>
+
<div class="design-announce">
<p><strong>Action Bar Design</strong></p>
@@ -225,9 +230,10 @@ later&mdash;calling {@link android.app.Activity#getActionBar()} will return null
href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">options menu</a>. To do this, you can
declare that the menu item should appear in the action bar as an "action item." An action item can
include an icon and/or a text title. If a menu item does not appear as an action item, then the
-system places it in the overflow menu. The overflow menu is revealed either by the device MENU
+system places it in the overflow menu. The overflow menu is revealed either by the device
+<em>Menu</em>
button (if provided by the device) or an additional button in the action bar (if the device does not
-provide the MENU button).</p>
+provide the <em>Menu</em> button).</p>
<div class="figure" style="width:359px">
<img src="{@docRoot}images/ui/actionbar-item-withtext.png" height="57" alt="" />
@@ -1421,7 +1427,7 @@ href="#ActionView">action views</a>. (Added in API level 14.)</dd>
&lt;/style>
&lt;!-- style for the action bar tab text -->
- &lt;style name="CustomTabTextStyle">
+ &lt;style name="CustomTabTextStyle" parent="@android:style/TextAppearance.Holo">
&lt;item name="android:textColor">#2456c2&lt;/item>
&lt;/style>
&lt;/resources>
@@ -1437,8 +1443,7 @@ action bar styles you want to change without re-implementing the styles you want
manifest file like this:</p>
<pre>
-&lt;application android:theme="&#64;style/CustomActivityTheme"
- ... />
+&lt;application android:theme="&#64;style/CustomActivityTheme" ... />
</pre>
<p>For more information about using style and theme resources in your application, read <a
@@ -1457,7 +1462,7 @@ android:backgroundStacked}. If you override these action bar styles, be sure tha
parent action bar style such as {@link android.R.style#Widget_Holo_ActionBar
Widget.Holo.ActionBar}.</p>
-<p>For example, if you want to change the action bar's background, you could use the following
+<p>For example, if you want to change the action bar's background, you can use the following
styles:</p>
<pre>
@@ -1465,14 +1470,15 @@ styles:</p>
&lt;resources>
&lt;!-- the theme applied to the application or activity -->
&lt;style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
-   &lt;item name="android:actionBarTabTextStyle">@style/customTabTextStyle&lt;/item>
+ &lt;item name="android:actionBarStyle">@style/MyActionBar&lt;/item>
&lt;!-- other activity and action bar styles here -->
&lt;/style>
- &lt;!-- style for the action bar, simply to change the background -->
- &lt;style parent="@android:style/Widget.Holo.ActionBar">
+ &lt;!-- style for the action bar backgrounds -->
+ &lt;style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
&lt;item name="android:background">@drawable/ab_background&lt;/item>
- &lt;item name="android:backgroundSplit">@drawable/ab_background&lt;/item>
+ &lt;item name="android:backgroundStacked">@drawable/ab_background&lt;/item>
+ &lt;item name="android:backgroundSplit">@drawable/ab_split_background&lt;/item>
&lt;/style>
&lt;/resources>
</pre>
diff --git a/docs/html/guide/topics/ui/how-android-draws.jd b/docs/html/guide/topics/ui/how-android-draws.jd
index 3a57afacaa27..6a8cd869e535 100644
--- a/docs/html/guide/topics/ui/how-android-draws.jd
+++ b/docs/html/guide/topics/ui/how-android-draws.jd
@@ -62,7 +62,7 @@ and each View is responsible for drawing itself.
<p>
The measure pass uses two classes to communicate dimensions. The
- {@link android.view.View.MeasureSpec} class is used by Views to tell their parents how they
+ {@link android.view.ViewGroup.LayoutParams} class is used by Views to tell their parents how they
want to be measured and positioned. The base LayoutParams class just
describes how big the View wants to be for both width and height. For each
dimension, it can specify one of:</p>
diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd
index 7b5b3dc2f3c1..a2313b368b82 100644
--- a/docs/html/guide/topics/ui/menus.jd
+++ b/docs/html/guide/topics/ui/menus.jd
@@ -6,77 +6,129 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
- <ol>
- <li><a href="#xml">Creating a Menu Resource</a></li>
- <li><a href="#Inflating">Inflating a Menu Resource</a>
- <li><a href="#options-menu">Creating an Options Menu</a>
- <ol>
- <li><a href="#ChangingTheMenu">Changing menu items at runtime</a></li>
- </ol>
- </li>
- <li><a href="#context-menu">Creating a Context Menu</a></li>
- <li><a href="#submenu">Creating a Submenu</a></li>
- <li><a href="#features">Other Menu Features</a>
- <ol>
- <li><a href="#groups">Menu groups</a></li>
- <li><a href="#checkable">Checkable menu items</a></li>
- <li><a href="#shortcuts">Shortcut keys</a></li>
- <li><a href="#intents">Dynamically adding menu intents</a></li>
- </ol>
- </li>
- </ol>
+<ol>
+ <li><a href="#xml">Defining a Menu in XML</a></li>
+ <li><a href="#options-menu">Creating an Options Menu</a>
+ <ol>
+ <li><a href="#RespondingOptionsMenu">Handling click events</a></li>
+ <li><a href="#ChangingTheMenu">Changing menu items at runtime</a></li>
+ </ol>
+ </li>
+ <li><a href="#context-menu">Creating Contextual Menus</a>
+ <ol>
+ <li><a href="#FloatingContextMenu">Creating a floating context menu</a></li>
+ <li><a href="#CAB">Using the contextual action bar</a></li>
+ </ol>
+ </li>
+ <li><a href="#PopupMenu">Creating a Popup Menu</a>
+ <ol>
+ <li><a href="#PopupEvents">Handling click events</a></li>
+ </ol>
+ </li>
+ <li><a href="#groups">Creating Menu Groups</a>
+ <ol>
+ <li><a href="#checkable">Using checkable menu items</a></li>
+ </ol>
+ </li>
+ <li><a href="#intents">Adding Menu Items Based on an Intent</a>
+ <ol>
+ <li><a href="#AllowingToAdd">Allowing your activity to be added to other menus</a></li>
+ </ol>
+ </li>
+</ol>
<h2>Key classes</h2>
<ol>
<li>{@link android.view.Menu}</li>
<li>{@link android.view.MenuItem}</li>
<li>{@link android.view.ContextMenu}</li>
- <li>{@link android.view.SubMenu}</li>
+ <li>{@link android.view.ActionMode}</li>
</ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
<li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a></li>
+ <li><a
+href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">Say
+Goodbye to the Menu Button</a></li>
</ol>
</div>
</div>
-<p>Menus are an important part of an activity's user interface, which provide users a familiar
-way to perform actions. Android offers a simple framework for you to add standard
-menus to your application.</p>
+<p>Menus are a common user interface component in many types of applications. To provide a familiar
+and consistent user experience, you should use the {@link android.view.Menu} APIs to present user
+actions and other options in your activities.</p>
+
+<p>Beginning with Android 3.0 (API level 11), Android-powered devices are no longer required to
+provide a dedicated <em>Menu</em> button. With this change, Android apps should migrate away from a
+dependence on the traditional 6-item menu panel and instead provide an action bar to present common
+user actions.</p>
+
+<p>Although the design and user experience for some menu items have changed, the semantics to define
+a set of actions and options is still based on the {@link android.view.Menu} APIs. This
+guide shows how to create the three fundamental types of menus or action presentations on all
+versions of Android:</p>
-<p>There are three types of application menus:</p>
<dl>
- <dt><strong>Options Menu</strong></dt>
- <dd>The primary collection of menu items for an activity, which appears when the user touches
-the MENU button. When your application is running on Android 3.0 or later, you can provide
-quick access to select menu items by placing them directly in the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>, as "action items."</dd>
- <dt><strong>Context Menu</strong></dt>
- <dd>A floating list of menu items that appears when the user touches and holds a view
-that's registered to provide a context menu.
+ <dt><strong>Options menu and action bar</strong></dt>
+ <dd>The <a href="#options-menu">options menu</a> is the primary collection of menu items for an
+activity. It's where you should place actions that have a global impact on the app, such as
+"Search," "Compose email," and "Settings."
+ <p>If you're developing for Android 2.3 or lower, users can
+reveal the options menu panel by pressing the <em>Menu</em> button.</p>
+ <p>On Android 3.0 and higher, items from the options menu are presented by the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a> as a combination of on-screen action
+items and overflow options. Beginning with Android 3.0, the <em>Menu</em> button is deprecated (some
+devices
+don't have one), so you should migrate toward using the action bar to provide access to actions and
+other options.</p>
+ <p>See the section about <a href="#options-menu">Creating an Options Menu</a>.</p>
+ </dd>
+
+ <dt><strong>Context menu and contextual action mode</strong></dt>
+
+ <dd>A context menu is a <a href="#FloatingContextMenu">floating menu</a> that appears when the
+user performs a long-click on an element. It provides actions that affect the selected content or
+context frame.
+ <p>When developing for Android 3.0 and higher, you should instead use the <a
+href="#CAB">contextual action mode</a> to enable actions on selected content. This mode displays
+action items that affect the selected content in a bar at the top of the screen and allows the user
+to select multiple items.</p>
+ <p>See the section about <a href="#context-menu">Creating Contextual Menus</a>.</p>
+</dd>
+
+ <dt><strong>Popup menu</strong></dt>
+ <dd>A popup menu displays a list of items in a vertical list that's anchored to the view that
+invoked the menu. It's good for providing an overflow of actions that relate to specific content or
+to provide options for a second part of a command. Actions in a popup menu should
+<strong>not</strong> directly affect the corresponding content&mdash;that's what contextual actions
+are for. Rather, the popup menu is for extended actions that relate to regions of content in your
+activity.
+ <p>See the section about <a href="#PopupMenu">Creating a Popup Menu</a>.</p>
</dd>
- <dt><strong>Submenu</strong></dt>
- <dd>A floating list of menu items that appears when the user touches a menu item that contains
-a nested menu.</dd>
</dl>
-<p>This document shows you how to create each type of menu, using XML to define the content of
-the menu and callback methods in your activity to respond when the user selects an item.</p>
+<h2 id="xml">Defining a Menu in XML</h2>
-<h2 id="xml">Creating a Menu Resource</h2>
+<p>For all menu types, Android provides a standard XML format to define menu items.
+Instead of building a menu in your activity's code, you should define a menu and all its items in an
+XML <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. You can then
+inflate the menu resource (load it as a {@link android.view.Menu} object) in your activity or
+fragment.</p>
-<p>Instead of instantiating a {@link android.view.Menu} in your application code, you should
-define a menu and all its items in an XML <a
-href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, then inflate the menu
-resource (load it as a programmable object) in your application code. Using a menu resource to
-define your menu is a good practice because it separates the content for the menu from your
-application code. It's also easier to visualize the structure and content of a menu in XML.</p>
+<p>Using a menu resource is a good practice for a few reasons:</p>
+<ul>
+ <li>It's easier to visualize the menu structure in XML.</li>
+ <li>It separates the content for the menu from your application's behavioral code.</li>
+ <li>It allows you to create alternative menu configurations for different platform versions,
+screen sizes, and other configurations by leveraging the <a
+href="{@docRoot}guide/topics/resources/index.html">app resources</a> framework.</li>
+</ul>
-<p>To create a menu resource, create an XML file inside your project's <code>res/menu/</code>
+<p>To define the menu, create an XML file inside your project's <code>res/menu/</code>
directory and build the menu with the following elements:</p>
<dl>
<dt><code>&lt;menu></code></dt>
@@ -90,8 +142,8 @@ element may contain a nested <code>&lt;menu></code> element in order to create a
<dt><code>&lt;group></code></dt>
<dd>An optional, invisible container for {@code &lt;item&gt;} elements. It allows you to
-categorize menu items so they share properties such as active state and visibility. See the
-section about <a href="#groups">Menu groups</a>.</dd>
+categorize menu items so they share properties such as active state and visibility. For more
+information, see the section about <a href="#groups">Creating Menu Groups</a>.</dd>
</dl>
@@ -101,14 +153,17 @@ section about <a href="#groups">Menu groups</a>.</dd>
&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
&lt;item android:id="@+id/new_game"
android:icon="@drawable/ic_new_game"
- android:title="@string/new_game" /&gt;
+ android:title="@string/new_game"
+ android:showAsAction="ifRoom"/&gt;
&lt;item android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help" /&gt;
&lt;/menu&gt;
</pre>
-<p>This example defines a menu with two items. Each item includes the attributes:</p>
+<p>The <code>&lt;item></code> element supports several attributes you can use to define an item's
+appearance and behavior. The items in the above menu include the following attributes:</p>
+
<dl>
<dt>{@code android:id}</dt>
<dd>A resource ID that's unique to the item, which allows the application can recognize the item
@@ -117,158 +172,175 @@ when the user selects it.</dd>
<dd>A reference to a drawable to use as the item's icon.</dd>
<dt>{@code android:title}</dt>
<dd>A reference to a string to use as the item's title.</dd>
+ <dt>{@code android:showAsAction}</dt>
+ <dd>Specifies when and how this item should appear as an action item in the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>.</dd>
</dl>
-<p>There are many more attributes you can include in an {@code &lt;item&gt;}, including some that
- specify how the item may appear in the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>. For more information about the XML
-syntax and attributes for a menu resource, see the <a
-href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a> reference.</p>
+<p>These are the most important attributes you should use, but there are many more available.
+For information about all the supported attributes, see the <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a> document.</p>
-
-
-<h2 id="Inflating">Inflating a Menu Resource</h2>
-
-<p>From your application code, you can inflate a menu resource (convert the XML resource into a
-programmable object) using
-{@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}. For
-example, the following code inflates the <code>game_menu.xml</code> file defined above, during the
-{@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} callback method, to
-use the menu as the activity's Options Menu:</p>
+<p>You can add a submenu to an item in any menu (except a submenu) by adding a {@code &lt;menu&gt;}
+element as the child of an {@code &lt;item&gt;}. Submenus are useful when your application has a lot
+of functions that can be organized into topics, like items in a PC application's menu bar (File,
+Edit, View, etc.). For example:</p>
<pre>
-&#64;Override
-public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.game_menu, menu);
- return true;
-}
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/file"
+ android:title="@string/file" &gt;
+ &lt;!-- "file" submenu --&gt;
+ &lt;menu&gt;
+ &lt;item android:id="@+id/create_new"
+ android:title="@string/create_new" /&gt;
+ &lt;item android:id="@+id/open"
+ android:title="@string/open" /&gt;
+ &lt;/menu&gt;
+ &lt;/item&gt;
+&lt;/menu&gt;
</pre>
-<p>The {@link android.app.Activity#getMenuInflater()} method returns a {@link
-android.view.MenuInflater} for the activity. With this object, you can call {@link
-android.view.MenuInflater#inflate(int,Menu) inflate()}, which inflates a menu resource into a
-{@link android.view.Menu} object. In this example, the menu resource defined by
-<code>game_menu.xml</code>
-is inflated into the {@link android.view.Menu} that was passed into {@link
-android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}. (This callback method for
-the Options Menu is discussed more in the next section.)</p>
+<p>To use the menu in your activity, you need to inflate the menu resource (convert the XML
+resource into a programmable object) using {@link android.view.MenuInflater#inflate(int,Menu)
+MenuInflater.inflate()}. In the following sections, you'll see how to inflate a menu for each
+menu type.</p>
<h2 id="options-menu">Creating an Options Menu</h2>
-<div class="figure" style="width:200px">
+<div class="figure" style="width:200px;margin:0">
<img src="{@docRoot}images/options_menu.png" height="333" alt="" />
- <p class="img-caption"><strong>Figure 1.</strong> Screenshot of the Options Menu in the
-Browser.</p>
+ <p class="img-caption"><strong>Figure 1.</strong> Options menu in the
+Browser, on Android 2.3.</p>
</div>
-<p>The Options Menu is where you should include basic activity actions and necessary navigation
-items (for example, a button to open the application settings). Items in the Options Menu are
-accessible in two distinct ways: the MENU button or in the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> (on devices running Android 3.0
-or higher).</p>
-
-<p>When running on a device with Android 2.3 and lower, the Options Menu appears at the bottom of
-the screen, as shown in figure 1. When opened, the first visible portion of the Options Menu is
-the icon menu. It holds the first six menu items. If you add more than six items to the
-Options Menu, Android places the sixth item and those after it into the overflow menu, which the
-user can open by touching the "More" menu item.</p>
-
-<p>On Android 3.0 and higher, items from the Options Menu is placed in the Action Bar, which appears
-at the top of the activity in place of the traditional title bar. By default all items from the
-Options Menu are placed in the overflow menu, which the user can open by touching the menu icon
-on the right side of the Action Bar. However, you can place select menu items directly in the
-Action Bar as "action items," for instant access, as shown in figure 2.</p>
-
-<p>When the Android system creates the Options Menu for the first time, it calls your
-activity's {@link android.app.Activity#onCreateOptionsMenu(Menu)
-onCreateOptionsMenu()} method. Override this method in your activity
-and populate the {@link android.view.Menu} that is passed into the method,
-{@link android.view.Menu} by inflating a menu resource as described above in <a
-href="#Inflating">Inflating a Menu Resource</a>. For example:</p>
+<p>The options menu is where you should include actions and other options that are relevant to the
+current activity context, such as "Search," "Compose email," and "Settings."</p>
+
+<p>Where the items in your options menu appear on the screen depends on the version for which you've
+developed your application:</p>
+
+<ul>
+ <li>If you've developed your application for <strong>Android 2.3.x (API level 10) or
+lower</strong>, the contents of your options menu appear at the bottom of the screen when the user
+presses the <em>Menu</em> button, as shown in figure 1. When opened, the first visible portion is
+the icon
+menu, which holds up to six menu items. If your menu includes more than six items, Android places
+the sixth item and the rest into the overflow menu, which the user can open by selecting
+<em>More</em>.</li>
+
+ <li>If you've developed your application for <strong>Android 3.0 (API level 11) and
+higher</strong>, items from the options menu are available in the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>. By default, the system
+places all items in the action overflow, which the user can reveal with the action overflow icon on
+the right side of the action bar (or by pressing the device <em>Menu</em> button, if available). To
+enable
+quick access to important actions, you can promote a few items to appear in the action bar by adding
+{@code android:showAsAction="ifRoom"} to the corresponding {@code &lt;item&gt;} elements (see figure
+2). <p>For more information about action items and other action bar behaviors, see the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> guide. </p>
+<p class="note"><strong>Note:</strong> Even if you're <em>not</em> developing for Android 3.0 or
+higher, you can build your own action bar layout for a similar effect. For an example of how you can
+support older versions of Android with an action bar, see the <a
+href="{@docRoot}resources/samples/ActionBarCompat/index.html">Action Bar Compatibility</a>
+sample.</p>
+</li>
+</ul>
+
+<img src="{@docRoot}images/ui/actionbar.png" alt="" />
+<p class="img-caption"><strong>Figure 2.</strong> Action bar from the <a
+href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> app, showing
+navigation tabs and a camera action item (plus the action overflow button).</p>
+
+<p>You can declare items for the options menu from either your {@link android.app.Activity}
+subclass or a {@link android.app.Fragment} subclass. If both your activity and fragment(s)
+declare items for the options menu, they are combined in the UI. The activity's items appear
+first, followed by those of each fragment in the order in which each fragment is added to the
+activity. If necessary, you can re-order the menu items with the {@code android:orderInCategory}
+attribute in each {@code &lt;item&gt;} you need to move.</p>
+
+<p>To specify the options menu for an activity, override {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} (fragments provide their
+own {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()} callback). In this
+method, you can inflate your menu resource (<a href="#xml">defined in XML</a>) into the {@link
+android.view.Menu} provided in the callback. For example:</p>
<pre>
&#64;Override
public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
+ MenuInflater inflater = {@link android.app.Activity#getMenuInflater()};
inflater.inflate(R.menu.game_menu, menu);
return true;
}
</pre>
-<div class="figure" style="width:450px">
-<img src="{@docRoot}images/ui/actionbar.png" alt="" />
-<p class="img-caption"><strong>Figure 2.</strong> Action bar from the <a
-href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> app, including
-navigation tabs and a camera action item (plus the overflow menu button).</p>
-</div>
+<p>You can also add menu items using {@link android.view.Menu#add(int,int,int,int)
+add()} and retrieve items with {@link android.view.Menu#findItem findItem()} to revise their
+properties with {@link android.view.MenuItem} APIs.</p>
-<p>You can also populate the menu in code, using {@link android.view.Menu#add(int,int,int,int)
-add()} to add items to the {@link android.view.Menu}.</p>
+<p>If you've developed your application for Android 2.3.x and lower, the system calls {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} to create the options menu
+when the user opens the menu for the first time. If you've developed for Android 3.0 and higher, the
+system calls {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} when
+starting the activity, in order to show items to the action bar.</p>
-<p class="note"><strong>Note:</strong> On Android 2.3 and lower, the system calls {@link
-android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} to create the Options Menu
-when the user opens it for the first time, but on Android 3.0 and greater, the system creates it as
-soon as the activity is created, in order to populate the Action Bar.</p>
-<h3 id="RespondingOptionsMenu">Responding to user action</h3>
+<h3 id="RespondingOptionsMenu">Handling click events</h3>
-<p>When the user selects a menu item from the Options Menu (including action items in the
-Action Bar), the system calls your activity's
-{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}
-method. This method passes the
-{@link android.view.MenuItem} that the user selected. You can identify the menu item by calling
-{@link android.view.MenuItem#getItemId()}, which returns the unique ID for the menu
-item (defined by the {@code android:id} attribute in the menu resource or with an integer
-given to the {@link android.view.Menu#add(int,int,int,int) add()} method). You can match this ID
-against known menu items and perform the appropriate action. For example:</p>
+<p>When the user selects an item from the options menu (including action items in the action bar),
+the system calls your activity's {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()} method. This method passes the {@link android.view.MenuItem} selected. You
+can identify the item by calling {@link android.view.MenuItem#getItemId()}, which returns the unique
+ID for the menu item (defined by the {@code android:id} attribute in the menu resource or with an
+integer given to the {@link android.view.Menu#add(int,int,int,int) add()} method). You can match
+this ID against known menu items to perform the appropriate action. For example:</p>
<pre>
&#64;Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
- case R.id.new_game:
- newGame();
- return true;
- case R.id.help:
- showHelp();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ case R.id.new_game:
+ newGame();
+ return true;
+ case R.id.help:
+ showHelp();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
}
</pre>
-<p>In this example, {@link android.view.MenuItem#getItemId()} queries the ID for the selected menu
-item and the switch statement compares the ID against the resource IDs that were assigned to menu
-items in the XML resource. When a switch case successfully handles the menu item, it
-returns {@code true} to indicate that the item selection was handled. Otherwise, the default
-statement passes the menu item to the super class, in
-case it can handle the item selected. (If you've directly extended the {@link android.app.Activity}
-class, then the super class returns {@code false}, but it's a good practice to
-pass unhandled menu items to the super class instead of directly returning {@code false}.)</p>
-
-<p>Additionally, Android 3.0 adds the ability for you to define the on-click behavior for a menu
-item in the <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> XML,
-using the {@code android:onClick} attribute. So you don't need to implement {@link
-android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}. Using the {@code
-android:onClick} attribute, you can specify a method to call when the user selects the menu item.
-Your activity must then implement the method specified in the {@code android:onClick} attribute so
-that it accepts a single {@link android.view.MenuItem} parameter&mdash;when the system calls this
-method, it passes the menu item selected.</p>
+<p>When you successfully handle a menu item, return {@code true}. If you don't handle the menu
+item, you should call the superclass implementation of {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} (the default
+implementation returns false).</p>
+
+<p>If your activity includes fragments, the system first calls {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} for the activity then
+for each fragment (in the order each fragment was added) until one returns
+{@code true} or all fragments have been called.</p>
+
+<p class="note"><strong>Tip:</strong> Android 3.0 adds the ability for you to define the on-click
+behavior for a menu item in XML, using the {@code android:onClick} attribute. The value for the
+attribute must be the name of a method defined by the activity using the menu. The method
+must be public and accept a single {@link android.view.MenuItem} parameter&mdash;when the system
+calls this method, it passes the menu item selected. For more information and an example, see the <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a> document.</p>
<p class="note"><strong>Tip:</strong> If your application contains multiple activities and
-some of them provide the same Options Menu, consider creating
+some of them provide the same options menu, consider creating
an activity that implements nothing except the {@link android.app.Activity#onCreateOptionsMenu(Menu)
onCreateOptionsMenu()} and {@link android.app.Activity#onOptionsItemSelected(MenuItem)
onOptionsItemSelected()} methods. Then extend this class for each activity that should share the
-same Options Menu. This way, you have to manage only one set of code for handling menu
-actions and each descendant class inherits the menu behaviors.<br/><br/>
-If you want to add menu items to one of your descendant activities,
+same options menu. This way, you can manage one set of code for handling menu
+actions and each descendant class inherits the menu behaviors.
+If you want to add menu items to one of the descendant activities,
override {@link android.app.Activity#onCreateOptionsMenu(Menu)
onCreateOptionsMenu()} in that activity. Call {@code super.onCreateOptionsMenu(menu)} so the
original menu items are created, then add new menu items with {@link
@@ -278,180 +350,477 @@ behavior for individual menu items.</p>
<h3 id="ChangingTheMenu">Changing menu items at runtime</h3>
-<p>Once the activity is created, the {@link android.app.Activity#onCreateOptionsMenu(Menu)
-onCreateOptionsMenu()} method is
-called only once, as described above. The system keeps and re-uses the {@link
-android.view.Menu} you define in this method until your activity is destroyed. If you want to change
-the Options Menu any time after it's first created, you must override the
-{@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} method. This passes
-you the {@link android.view.Menu} object as it currently exists. This is useful if you'd like to
-remove, add, disable, or enable menu items depending on the current state of your application.</p>
-
-<p>On Android 2.3 and lower, the system calls {@link android.app.Activity#onPrepareOptionsMenu(Menu)
-onPrepareOptionsMenu()} each time the user opens the Options Menu.</p>
+<p>After the system calls {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()}, it retains an instance of the {@link android.view.Menu} you populate and
+will not call {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}
+again unless the menu is invalidated for some reason. However, you should use {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} only to create the initial
+menu state and not to make changes during the activity lifecycle.</p>
+
+<p>If you want to modify the options menu based on
+events that occur during the activity lifecycle, you can do so in
+the {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} method. This
+method passes you the {@link android.view.Menu} object as it currently exists so you can modify it,
+such as add, remove, or disable items. (Fragments also provide an {@link
+android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()} callback.)</p>
+
+<p>On Android 2.3.x and lower, the system calls {@link
+android.app.Activity#onPrepareOptionsMenu(Menu)
+onPrepareOptionsMenu()} each time the user opens the options menu (presses the <em>Menu</em>
+button).</p>
-<p>On Android 3.0 and higher, you must call {@link android.app.Activity#invalidateOptionsMenu
-invalidateOptionsMenu()} when you want to update the menu, because the menu is always open. The
-system will then call {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}
-so you can update the menu items.</p>
+<p>On Android 3.0 and higher, the options menu is considered to always be open when menu items are
+presented in the action bar. When an event occurs and you want to perform a menu update, you must
+call {@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()} to request that the
+system call {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}.</p>
<p class="note"><strong>Note:</strong>
-You should never change items in the Options Menu based on the {@link android.view.View} currently
+You should never change items in the options menu based on the {@link android.view.View} currently
in focus. When in touch mode (when the user is not using a trackball or d-pad), views
cannot take focus, so you should never use focus as the basis for modifying
-items in the Options Menu. If you want to provide menu items that are context-sensitive to a {@link
+items in the options menu. If you want to provide menu items that are context-sensitive to a {@link
android.view.View}, use a <a href="#context-menu">Context Menu</a>.</p>
-<p>If you're developing for Android 3.0 or higher, be sure to also read the <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</p>
+<h2 id="context-menu">Creating Contextual Menus</h2>
-<h2 id="context-menu">Creating a Context Menu</h2>
+<div class="figure" style="width:420px;margin-top:-1em">
+ <img src="{@docRoot}images/ui/menu-context.png" alt="" />
+ <p class="img-caption"><strong>Figure 3.</strong> Screenshots of a floating context menu (left)
+and the contextual action bar (right).</p>
+</div>
-<p>A context menu is conceptually similar to the menu displayed when the user performs a
-"right-click" on a PC. You should use a context menu to provide the user access to
-actions that pertain to a specific item in the user interface. On Android, a context menu is
-displayed when the user performs a "long press" (press and hold) on an item.</p>
+<p>A contextual menu offers actions that affect a specific item or context frame in the UI. You
+can provide a context menu for any view, but they are most often used for items in a {@link
+android.widget.ListView}, {@link android.widget.GridView}, or other view collections in which
+the user can perform direct actions on each item.</p>
-<p>You can create a context menu for any View, though context menus are most often used for items in
-a {@link android.widget.ListView}. When the user performs a long-press on an item in a ListView and
-the list is registered to provide a context menu, the list item signals to the user that a context
-menu is available by animating its background color&mdash;it transitions from
-orange to white before opening the context menu. (The Contacts application demonstrates this
-feature.)</p>
+<p>There are two ways to provide contextual actions:</p>
+<ul>
+ <li>In a <a href="#FloatingContextMenu">floating context menu</a>. A menu appears as a
+floating list of menu items (similar to a dialog) when the user performs a long-click (press and
+hold) on a view that declares support for a context menu. Users can perform a contextual
+action on one item at a time.</li>
+
+ <li>In the <a href="#CAB">contextual action mode</a>. This mode is a system implementation of
+{@link android.view.ActionMode} that displays a <em>contextual action bar</em> at the top of the
+screen with action items that affect the selected item(s). When this mode is active, users
+can perform an action on multiple items at once (if your app allows it).</li>
+</ul>
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<h3>Register a ListView</h3>
-<p>If your activity uses a {@link android.widget.ListView} and
-you want all list items to provide a context menu, register all items for a context
-menu by passing the {@link android.widget.ListView} to {@link
-android.app.Activity#registerForContextMenu(View) registerForContextMenu()}. For
-example, if you're using a {@link android.app.ListActivity}, register all list items like this:</p>
-<p><code>registerForContextMenu({@link android.app.ListActivity#getListView()});</code></p>
-</div>
-</div>
+<p class="note"><strong>Note:</strong> The contextual action mode is available on Android 3.0 (API
+level 11) and higher and is the preferred technique for displaying contextual actions when
+available. If your app supports versions lower than 3.0 then you should fall back to a floating
+context menu on those devices.</p>
-<p>In order for a View to provide a context menu, you must "register" the view for a context
-menu. Call {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} and
-pass it the {@link android.view.View} you want to give a context menu. When this View then
-receives a long-press, it displays a context menu.</p>
-<p>To define the context menu's appearance and behavior, override your activity's context menu
-callback methods, {@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
-onCreateContextMenu()} and
-{@link android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}.</p>
+<h3 id="FloatingContextMenu">Creating a floating context menu</h3>
-<p>For example, here's an {@link
-android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
-onCreateContextMenu()} that uses the {@code context_menu.xml} menu resource:</p>
+<p>To provide a floating context menu:</p>
+<ol>
+ <li>Register the {@link android.view.View} to which the context menu should be associated by
+calling {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} and pass
+it the {@link android.view.View}.
+ <p>If your activity uses a {@link android.widget.ListView} or {@link android.widget.GridView} and
+you want each item to provide the same context menu, register all items for a context menu by
+passing the {@link android.widget.ListView} or {@link android.widget.GridView} to {@link
+android.app.Activity#registerForContextMenu(View) registerForContextMenu()}.</p>
+</li>
+
+ <li>Implement the {@link
+android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()} method
+in your {@link android.app.Activity} or {@link android.app.Fragment}.
+ <p>When the registered view receives a long-click event, the system calls your {@link
+android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()}
+method. This is where you define the menu items, usually by inflating a menu resource. For
+example:</p>
<pre>
&#64;Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.context_menu, menu);
+ super.onCreateContextMenu(menu, v, menuInfo);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
}
</pre>
-<p>{@link android.view.MenuInflater} is used to inflate the context menu from a <a
-href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. (You can also use
-{@link android.view.Menu#add(int,int,int,int) add()} to add menu items.) The callback method
+<p>{@link android.view.MenuInflater} allows you to inflate the context menu from a <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. The callback method
parameters include the {@link android.view.View}
that the user selected and a {@link android.view.ContextMenu.ContextMenuInfo} object that provides
-additional information about the item selected. You might use these parameters to determine
-which context menu should be created, but in this example, all context menus for the activity are
-the same.</p>
+additional information about the item selected. If your activity has several views that each provide
+a different context menu, you might use these parameters to determine which context menu to
+inflate.</p>
+</li>
-<p>Then when the user selects an item from the context menu, the system calls {@link
-android.app.Activity#onContextItemSelected(MenuItem) onContextItemSelected()}. Here is an example
-of how you can handle selected items:</p>
+<li>Implement {@link android.app.Activity#onContextItemSelected(MenuItem)
+onContextItemSelected()}.
+ <p>When the user selects a menu item, the system calls this method so you can perform the
+appropriate action. For example:</p>
<pre>
&#64;Override
public boolean onContextItemSelected(MenuItem item) {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
- switch (item.getItemId()) {
- case R.id.edit:
- editNote(info.id);
- return true;
- case R.id.delete:
- deleteNote(info.id);
- return true;
- default:
- return super.onContextItemSelected(item);
- }
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ switch (item.getItemId()) {
+ case R.id.edit:
+ editNote(info.id);
+ return true;
+ case R.id.delete:
+ deleteNote(info.id);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
}
</pre>
-<p>The structure of this code is similar to the example for <a href="#options-menu">Creating an
-Options Menu</a>, in which {@link android.view.MenuItem#getItemId()} queries the ID for the selected
-menu item and a switch statement matches the item to the IDs that are defined in the menu resource.
-And like the options menu example, the default statement calls the super class in case it
-can handle menu items not handled here, if necessary.</p>
+<p>The {@link android.view.MenuItem#getItemId()} method queries the ID for
+the selected menu item, which you should assign to each menu item in XML using the {@code
+android:id} attribute, as shown in the section about <a href="#xml">Defining a Menu in
+XML</a>.</p>
+
+<p>When you successfully handle a menu item, return {@code true}. If you don't handle the menu item,
+you should pass the menu item to the superclass implementation. If your activity includes fragments,
+the activity receives this callback first. By calling the superclass when unhandled, the system
+passes the event to the respective callback method in each fragment, one at a time (in the order
+each fragment was added) until {@code true} or {@code false} is returned. (The default
+implementation for {@link android.app.Activity} and {@code android.app.Fragment} return {@code
+false}, so you should always call the superclass when unhandled.)</p>
+</li>
+</ol>
+
+
+<h3 id="CAB">Using the contextual action mode</h3>
-<p>In this example, the selected item is an item from a {@link android.widget.ListView}. To
-perform an action on the selected item, the application needs to know the list
-ID for the selected item (it's position in the ListView). To get the ID, the application calls
-{@link android.view.MenuItem#getMenuInfo()}, which returns a {@link
-android.widget.AdapterView.AdapterContextMenuInfo} object that includes the list ID for the
-selected item in the {@link android.widget.AdapterView.AdapterContextMenuInfo#id id} field. The
-local methods <code>editNote()</code> and <code>deleteNote()</code> methods accept this list ID to
-perform an action on the data specified by the list ID.</p>
+<p>The contextual action mode is a system implementation of {@link android.view.ActionMode} that
+focuses user interaction toward performing contextual actions. When a
+user enables this mode by selecting an item, a <em>contextual action bar</em> appears at the top of
+the screen to present actions the user can perform on the currently selected item(s). While this
+mode is enabled, the user can select multiple items (if you allow it), deselect items, and continue
+to navigate within the activity (as much as you're willing to allow). The action mode is disabled
+and the contextual action bar disappears when the user deselects all items, presses the BACK button,
+or selects the <em>Done</em> action on the left side of the bar.</p>
-<p class="note"><strong>Note:</strong> Items in a context menu do not support icons or shortcut
-keys.</p>
+<p class="note"><strong>Note:</strong> The contextual action bar is not necessarily
+associated with the <a href="{@docRoot}guide/topics/ui/actionbar.html">action bar</a>. They operate
+independently, even though the contextual action bar visually overtakes the action bar
+position.</p>
+<p>If you're developing for Android 3.0 (API level 11) or higher, you
+should usually use the contextual action mode to present contextual actions, instead of the <a
+href="#FloatingContextMenu">floating context menu</a>.</p>
+<p>For views that provide contextual actions, you should usually invoke the contextual action mode
+upon one of two events (or both):</p>
+<ul>
+ <li>The user performs a long-click on the view.</li>
+ <li>The user selects a checkbox or similar UI component within the view.</li>
+</ul>
+
+<p>How your application invokes the contextual action mode and defines the behavior for each
+action depends on your design. There are basically two designs:</p>
+<ul>
+ <li>For contextual actions on individual, arbitrary views.</li>
+ <li>For batch contextual actions on groups of items in a {@link
+android.widget.ListView} or {@link android.widget.GridView} (allowing the user to select multiple
+items and perform an action on them all).</li>
+</ul>
-<h2 id="submenu">Creating Submenus</h2>
+<p>The following sections describe the setup required for each scenario.</p>
-<p>A submenu is a menu that the user can open by selecting an item in another menu. You can add a
-submenu to any menu (except a submenu). Submenus are useful when your application has a lot of
-functions that can be organized into topics, like items in a PC application's menu bar (File, Edit,
-View, etc.).</p>
-<p>When creating your <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu
-resource</a>, you can create a submenu by adding a {@code &lt;menu&gt;} element as the child of an
-{@code &lt;item&gt;}. For example:</p>
+<h4 id="CABforViews">Enabling the contextual action mode for individual views</h4>
+<p>If you want to invoke the contextual action mode only when the user selects specific
+views, you should:</p>
+<ol>
+ <li>Implement the {@link android.view.ActionMode.Callback} interface. In its callback methods, you
+can specify the actions for the contextual action bar, respond to click events on action items, and
+handle other lifecycle events for the action mode.</li>
+ <li>Call {@link android.app.Activity#startActionMode startActionMode()} when you want to show the
+bar (such as when the user long-clicks the view).</li>
+</ol>
+
+<p>For example:</p>
+
+<ol>
+ <li>Implement the {@link android.view.ActionMode.Callback ActionMode.Callback} interface:
<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- &lt;item android:id="@+id/file"
- android:icon="@drawable/file"
- android:title="@string/file" &gt;
- &lt;!-- "file" submenu --&gt;
- &lt;menu&gt;
- &lt;item android:id="@+id/create_new"
- android:title="@string/create_new" /&gt;
- &lt;item android:id="@+id/open"
- android:title="@string/open" /&gt;
- &lt;/menu&gt;
- &lt;/item&gt;
-&lt;/menu&gt;
+private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
+
+ // Called when the action mode is created; startActionMode() was called
+ &#64;Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ // Inflate a menu resource providing context menu items
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
+ return true;
+ }
+
+ // Called each time the action mode is shown. Always called after onCreateActionMode, but
+ // may be called multiple times if the mode is invalidated.
+ &#64;Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false; // Return false if nothing is done
+ }
+
+ // Called when the user selects a contextual menu item
+ &#64;Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_share:
+ shareCurrentItem();
+ mode.finish(); // Action picked, so close the CAB
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // Called when the user exits the action mode
+ &#64;Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mActionMode = null;
+ }
+};
+</pre>
+
+<p>Notice that these event callbacks are almost exactly the same as the callbacks for the <a
+href="#options-menu">options menu</a>, except each of these also pass the {@link
+android.view.ActionMode} object associated with the event. You can use {@link
+android.view.ActionMode} APIs to make various changes to the CAB, such as revise the title and
+subtitle with {@link android.view.ActionMode#setTitle setTitle()} and {@link
+android.view.ActionMode#setSubtitle setSubtitle()} (useful to indicate how many items are
+selected).</p>
+
+<p>Also notice that the above sample sets the {@code mActionMode} variable null when the
+action mode is destroyed. In the next step, you'll see how it's initialized and how saving
+the member variable in your activity or fragment can be useful.</p>
+</li>
+
+ <li>Call {@link android.app.Activity#startActionMode startActionMode()} to enable the contextual
+action mode when appropriate, such as in response to a long-click on a {@link
+android.view.View}:</p>
+
+<pre>
+someView.setOnLongClickListener(new View.OnLongClickListener() {
+ // Called when the user long-clicks on someView
+ public boolean onLongClick(View view) {
+ if (mActionMode != null) {
+ return false;
+ }
+
+ // Start the CAB using the ActionMode.Callback defined above
+ mActionMode = getActivity().startActionMode(mActionModeCallback);
+ view.setSelected(true);
+ return true;
+ }
+});
+</pre>
+
+<p>When you call {@link android.app.Activity#startActionMode startActionMode()}, the system returns
+the {@link android.view.ActionMode} created. By saving this in a member variable, you can
+make changes to the contextual action bar in response to other events. In the above sample, the
+{@link android.view.ActionMode} is used to ensure that the {@link android.view.ActionMode} instance
+is not recreated if it's already active, by checking whether the member is null before starting the
+action mode.</p>
+</li>
+</ol>
+
+
+
+<h4 id="CABforListView">Enabling batch contextual actions in a ListView or GridView</h4>
+
+<p>If you have a collection of items in a {@link android.widget.ListView} or {@link
+android.widget.GridView} (or another extension of {@link android.widget.AbsListView}) and want to
+allow users to perform batch actions, you should:</p>
+
+<ul>
+ <li>Implement the {@link android.widget.AbsListView.MultiChoiceModeListener} interface and set it
+for the view group with {@link android.widget.AbsListView#setMultiChoiceModeListener
+setMultiChoiceModeListener()}. In the listener's callback methods, you can specify the actions
+for the contextual action bar, respond to click events on action items, and handle other callbacks
+inherited from the {@link android.view.ActionMode.Callback} interface.</li>
+
+ <li>Call {@link android.widget.AbsListView#setChoiceMode setChoiceMode()} with the {@link
+android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL} argument.</li>
+</ul>
+
+<p>For example:</p>
+
+<pre>
+ListView listView = getListView();
+listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
+
+ &#64;Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position,
+ long id, boolean checked) {
+ // Here you can do something when items are selected/de-selected,
+ // such as update the title in the CAB
+ }
+
+ &#64;Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ // Respond to clicks on the actions in the CAB
+ switch (item.getItemId()) {
+ case R.id.menu_delete:
+ deleteSelectedItems();
+ mode.finish(); // Action picked, so close the CAB
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ &#64;Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ // Inflate the menu for the CAB
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.context, menu);
+ return true;
+ }
+
+ &#64;Override
+ public void onDestroyActionMode(ActionMode mode) {
+ // Here you can make any necessary updates to the activity when
+ // the CAB is removed. By default, selected items are deselected/unchecked.
+ }
+
+ &#64;Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ // Here you can perform updates to the CAB due to
+ // an {@link android.view.ActionMode#invalidate} request
+ return false;
+ }
+});
+</pre>
+
+<p>That's it. Now when the user selects an item with a long-click, the system calls the {@link
+android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode onCreateActionMode()}
+method and displays the contextual action bar with the specified actions. While the contextual
+action bar is visible, users can select additional items.</p>
+
+<p>In some cases in which the contextual actions provide common action items, you might
+want to add a checkbox or a similar UI element that allows users to select items, because they
+might not discover the long-click behavior. When a user selects the checkbox, you
+can invoke the contextual action mode by setting the respective list item to the checked
+state with {@link android.widget.AbsListView#setItemChecked setItemChecked()}.</p>
+
+
+
+
+<h2 id="PopupMenu">Creating a Popup Menu</h2>
+
+<div class="figure" style="width:220px">
+<img src="{@docRoot}images/ui/popupmenu.png" alt="" />
+<p><strong>Figure 4.</strong> A popup menu in the Gmail app, anchored to the overflow
+button at the top-right.</p>
+</div>
+
+<p>A {@link android.widget.PopupMenu} is a modal menu anchored to a {@link android.view.View}.
+It appears below the anchor view if there is room, or above the view otherwise. It's useful for:</p>
+<ul>
+ <li>Providing an overflow-style menu for actions that <em>relate to</em> specific content (such as
+Gmail's email headers, shown in figure 4).
+ <p class="note"><strong>Note:</strong> This is not the same as a context menu, which is
+generally for actions that <em>affect</em> selected content. For actions that affect selected
+content, use the <a href="#CAB">contextual action mode</a> or <a
+href="#FloatingContextMenu">floating context menu</a>.</p></li>
+ <li>Providing a second part of a command sentence (such as a button marked "Add"
+that produces a popup menu with different "Add" options).</li>
+ <li>Providing a drop-down similar to {@link android.widget.Spinner} that does not retain
+a persistent selection.</li>
+</ul>
+
+
+<p class="note"><strong>Note:</strong> {@link android.widget.PopupMenu} is available with API
+level 11 and higher.</p>
+
+<p>If you <a href="#xml">define your menu in XML</a>, here's how you can show the popup menu:</p>
+<ol>
+ <li>Instantate a {@link android.widget.PopupMenu} with its constructor, which takes the
+current application {@link android.content.Context} and the {@link android.view.View} to which the
+menu should be anchored.</li>
+ <li>Use {@link android.view.MenuInflater} to inflate your menu resource into the {@link
+android.view.Menu} object returned by {@link
+android.widget.PopupMenu#getMenu() PopupMenu.getMenu()}. On API level 14 and above, you can use
+{@link android.widget.PopupMenu#inflate PopupMenu.inflate()} instead.</li>
+ <li>Call {@link android.widget.PopupMenu#show() PopupMenu.show()}.</li>
+</ol>
+
+<p>For example, here's a button with the {@link android.R.attr#onClick android:onClick} attribute
+that shows a popup menu:</p>
+
+<pre>
+&lt;ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_overflow_holo_dark"
+ android:contentDescription="@string/descr_overflow_button"
+ android:onClick="showPopup" />
+</pre>
+
+<p>The activity can then show the popup menu like this:</p>
+
+<pre>
+public void showPopup(View v) {
+ PopupMenu popup = new PopupMenu(this, v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.actions, popup.getMenu());
+ popup.show();
+}
</pre>
-<p>When the user selects an item from a submenu, the parent menu's respective on-item-selected
-callback method receives the event. For instance, if the above menu is applied as an Options Menu,
-then the {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method
-is called when a submenu item is selected.</p>
+<p>In API level 14 and higher, you can combine the two lines that inflate the menu with {@link
+android.widget.PopupMenu#inflate PopupMenu.inflate()}.</p>
+
+<p>The menu is dismissed when the user selects an item or touches outside the menu
+area. You can listen for the dismiss event using {@link
+android.widget.PopupMenu.OnDismissListener}.</p>
+
+<h3 id="PopupEvents">Handling click events</h3>
-<p>You can also use {@link android.view.Menu#addSubMenu(int,int,int,int) addSubMenu()} to
-dynamically add a {@link android.view.SubMenu} to an existing {@link android.view.Menu}. This
-returns the new {@link android.view.SubMenu} object, to which you can add
-submenu items, using {@link android.view.Menu#add(int,int,int,int) add()}</p>
+<p>To perform an
+action when the user selects a menu item, you must implement the {@link
+android.widget.PopupMenu.OnMenuItemClickListener} interface and register it with your {@link
+android.widget.PopupMenu} by calling {@link android.widget.PopupMenu#setOnMenuItemClickListener
+setOnMenuItemclickListener()}. When the user selects an item, the system calls the {@link
+android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick onMenuItemClick()} callback in
+your interface.</p>
+<p>For example:</p>
+<pre>
+public void showMenu(View v) {
+ PopupMenu popup = new PopupMenu(this, v);
-<h2 id="features">Other Menu Features</h2>
+ // This activity implements OnMenuItemClickListener
+ popup.setOnMenuItemClickListener(this);
+ popup.inflate(R.menu.actions);
+ popup.show();
+}
+
+&#64;Override
+public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.archive:
+ archive(item);
+ return true;
+ case R.id.delete:
+ delete(item);
+ return true;
+ default:
+ return false;
+ }
+}
+</pre>
-<p>Here are some other features that you can apply to most menu items.</p>
-<h3 id="groups">Menu groups</h3>
+<h2 id="groups">Creating Menu Groups</h2>
<p>A menu group is a collection of menu items that share certain traits. With a group, you
can:</p>
@@ -473,38 +842,41 @@ android.view.Menu#add(int,int,int,int) add()} method.</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- &lt;item android:id="@+id/item1"
- android:icon="@drawable/item1"
- android:title="@string/item1" /&gt;
+ &lt;item android:id="@+id/menu_save"
+ android:icon="@drawable/menu_save"
+ android:title="@string/menu_save" /&gt;
&lt;!-- menu group --&gt;
- &lt;group android:id="@+id/group1"&gt;
- &lt;item android:id="@+id/groupItem1"
- android:title="@string/groupItem1" /&gt;
- &lt;item android:id="@+id/groupItem2"
- android:title="@string/groupItem2" /&gt;
+ &lt;group android:id="@+id/group_delete"&gt;
+ &lt;item android:id="@+id/menu_archive"
+ android:title="@string/menu_archive" /&gt;
+ &lt;item android:id="@+id/menu_delete"
+ android:title="@string/menu_delete" /&gt;
&lt;/group&gt;
&lt;/menu&gt;
</pre>
-<p>The items that are in the group appear the same as the first item that is not in a
-group&mdash;all three items in the menu are siblings. However, you can modify the traits of the two
-items in the group by referencing the group ID and using the methods listed above.</p>
+<p>The items that are in the group appear at the same level as the first item&mdash;all three items
+in the menu are siblings. However, you can modify the traits of the two
+items in the group by referencing the group ID and using the methods listed above. The system
+will also never separate grouped items. For example, if you declare {@code
+android:showAsAction="ifRoom"} for each item, they will either both appear in the action
+bar or both appear in the action overflow.</p>
-<h3 id="checkable">Checkable menu items</h3>
+<h3 id="checkable">Using checkable menu items</h3>
<div class="figure" style="width:200px">
<img src="{@docRoot}images/radio_buttons.png" height="333" alt="" />
- <p class="img-caption"><strong>Figure 3.</strong> Screenshot of a submenu with checkable
+ <p class="img-caption"><strong>Figure 5.</strong> Screenshot of a submenu with checkable
items.</p>
</div>
<p>A menu can be useful as an interface for turning options on and off, using a checkbox for
stand-alone options, or radio buttons for groups of
-mutually exclusive options. Figure 2 shows a submenu with items that are checkable with radio
+mutually exclusive options. Figure 5 shows a submenu with items that are checkable with radio
buttons.</p>
-<p class="note"><strong>Note:</strong> Menu items in the Icon Menu (from the Options Menu) cannot
+<p class="note"><strong>Note:</strong> Menu items in the Icon Menu (from the options menu) cannot
display a checkbox or radio button. If you choose to make items in the Icon Menu checkable,
you must manually indicate the checked state by swapping the icon and/or text
each time the state changes.</p>
@@ -550,15 +922,15 @@ user selected it) with {@link android.view.MenuItem#isChecked()} and then set th
<pre>
&#64;Override
public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.vibrate:
- case R.id.dont_vibrate:
- if (item.isChecked()) item.setChecked(false);
- else item.setChecked(true);
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ switch (item.getItemId()) {
+ case R.id.vibrate:
+ case R.id.dont_vibrate:
+ if (item.isChecked()) item.setChecked(false);
+ else item.setChecked(true);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
}
</pre>
@@ -575,30 +947,8 @@ you should store the data using <a
href="{@docRoot}guide/topics/data/data-storage.html#pref">Shared Preferences</a>.</p>
-<h3 id="shortcuts">Shortcut keys</h3>
-
-<p>To facilitate quick access to items in the Options Menu when the user's device has a hardware
-keyboard, you can add quick-access shortcut keys using letters and/or numbers, with the
-{@code android:alphabeticShortcut} and {@code android:numericShortcut} attributes in the {@code
-&lt;item&gt;} element. You can also use the methods {@link
-android.view.MenuItem#setAlphabeticShortcut(char)} and {@link
-android.view.MenuItem#setNumericShortcut(char)}. Shortcut keys are <em>not</em>
-case sensitive.</p>
-
-<p>For example, if you apply the "s" character as an alphabetic shortcut to a "save" menu item, then
-when the menu is open (or while the user holds the MENU button) and the user presses the "s" key,
-the "save" menu item is selected.</p>
-
-<p>This shortcut key is displayed as a tip in the menu item, below the menu item name
-(except for items in the Icon Menu, which are displayed only if the user holds the MENU
-button).</p>
-
-<p class="note"><strong>Note:</strong> Shortcut keys for menu items only work on devices with a
-hardware keyboard. Shortcuts cannot be added to items in a Context Menu.</p>
-
-
-<h3 id="intents">Dynamically adding menu intents</h3>
+<h2 id="intents">Adding Menu Items Based on an Intent</h2>
<p>Sometimes you'll want a menu item to launch an activity using an {@link android.content.Intent}
(whether it's an activity in your application or another application). When you know the intent you
@@ -671,7 +1021,7 @@ addIntentOptions()}, it overrides any and all menu items by the menu group speci
argument.</p>
-<h4>Allowing your activity to be added to other menus</h4>
+<h3 id="AllowingToAdd">Allowing your activity to be added to other menus</h3>
<p>You can also offer the services of your activity to other applications, so your
application can be included in the menu of others (reverse the roles described above).</p>
@@ -681,7 +1031,7 @@ filter as usual, but be sure to include the {@link android.content.Intent#CATEGO
and/or {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} values for the intent filter
category. For example:</p>
<pre>
-&lt;intent-filter label="Resize Image">
+&lt;intent-filter label="&#64;string/resize_image">
...
&lt;category android:name="android.intent.category.ALTERNATIVE" />
&lt;category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index 33b0fecc9ed5..bef9671100bf 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -245,31 +245,27 @@ an application to be part of that application's UI flow, so simply launching the
activity like this can cause it to be mixed with your normal application back stack
in undesired ways. To make it behave correctly, in the manifest declaration
for the activity the attributes
-<code>android:launchMode="singleInstance"</code> and
+<code>android:launchMode="singleTask"</code>,
+<code>android:taskAffinity=""</code> and
<code>android:excludeFromRecents="true"</code>
must be set. The full activity declaration for this sample is:</p>
{@sample development/samples/ApiDemos/AndroidManifest.xml interstitial_affinity}
-<p>Because of the use of <code>singleInstance</code>, you must be careful about launching
-any other activities from this one. These activities will be launched
-in their own task, and care must be taken to make sure this interacts
-well with the current state of your application's task. This is essentially
+<p>You must be careful when launching other activities from this initial activity,
+because this is not a top-level part of the application, does not appear in
+recents, and needs to be relaunched at any point from the notification with new data
+to show. This best approach is to make sure any activity launched from it is
+launched in its own task. When doing this care must be taken to make sure this
+new task interacts well with the current state of your exiting application's
+task. This is essentially
the same as switching to the main application as described for the Email style
notification shown before. Given the <code>makeMessageIntentStack()</code>
-method previously shown, handling a click here would look something like this:</p>
+method previously shown, handling a click then would look something like this:</p>
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageInterstitial.java
app_launch}
-<p>If you don't want to use the <code>singleInstance</code> launch mode for
-this activity, an alternative approach is to use <code>android:taskAffinity=""</code>.
-This tells Android that the activity should not be treated as part of the
-main application flow, so it will not get mixed together with that. All of the
-other issues discussed here do still apply, though this would allow you to start
-additional activities that are part of this notification task instead of switching
-to and replacing the main application task.</p>
-
<h2 id="ManageYourNotifications">Managing your Notifications</h2>
<p>The {@link android.app.NotificationManager} is a system service that manages all
diff --git a/docs/html/images/ui/menu-context.png b/docs/html/images/ui/menu-context.png
new file mode 100644
index 000000000000..f6975fbf2df4
--- /dev/null
+++ b/docs/html/images/ui/menu-context.png
Binary files differ
diff --git a/docs/html/images/ui/popupmenu.png b/docs/html/images/ui/popupmenu.png
new file mode 100644
index 000000000000..5c9982170461
--- /dev/null
+++ b/docs/html/images/ui/popupmenu.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 9197b5d202a3..fdf860a880d8 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -1,4 +1,5 @@
home=true
+metaDescription=The official site for Android developers. Provides the Android SDK and documentation for app developers and designers.
@jd:body
@@ -142,6 +143,20 @@ href="{@docRoot}resources/dashboard/platform-versions.html">Learn more &raquo;</
+ "href='{@docRoot}sdk/api_diff/15/changes.html'>diff report</a>. If you're new to Android, "
+ "get started with the <a href='/sdk/index.html'>SDK starter package</a>.</p>"
},
+
+ 'plus': {
+ 'layout':"imgLeft",
+ 'icon':"google-plus-small.png",
+ 'name':"Google+ Page",
+ 'img':"google-plus.png",
+ 'title':"Android Developers on Google+",
+ 'desc': "<p>We now have a Google+ page for <a "
++ "href='https://plus.google.com/108967384991768947849'>+Android Developers</a>. "
++ "We'll use it to host Hangouts for developers, talk about the latest releases, "
++ "development and design tips, and much more.</p>"
++ "<div style='margin:.7em 0 0 -1.2em'><g:plus href='https://plus.google.com/108967384991768947849' "
++ "size=\"smallbadge\" width=\"275\"></g:plus></div>"
+ },
'tv': {
'layout':"imgLeft",
@@ -186,5 +201,16 @@ href="{@docRoot}resources/dashboard/platform-versions.html">Learn more &raquo;</
</script>
<script type="text/javascript" src="{@docRoot}assets/carousel.js"></script>
<script type="text/javascript">
- initCarousel("sdk");
+ initCarousel("plus");
</script>
+
+<script type="text/javascript" src="https://plus.google.com/108967384991768947849"
+rel="publisher"></script>
+<script type="text/javascript">
+window.___gcfg = {lang: 'en'};
+(function()
+{var po = document.createElement("script");
+po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
+var s = document.getElementsByTagName("script")[0];
+s.parentNode.insertBefore(po, s);
+})();</script>
diff --git a/docs/html/resources/community-more.jd b/docs/html/resources/community-more.jd
index df729265cc05..3089d45aa9b5 100644
--- a/docs/html/resources/community-more.jd
+++ b/docs/html/resources/community-more.jd
@@ -1,5 +1,5 @@
community=true
-page.title=IRC and Twitter
+page.title=IRC, G+, Twitter
@jd:body
<p>In addition to the <a href="community-groups.html">Android developer forums</a>, you can participate in the Android developer community through IRC and you can follow us on Twitter. </p>
@@ -45,8 +45,27 @@ does not require any installation, to join discussions on the Android IRC channe
</li>
</ul>
+
+<h3 id="gplus">Google+</h3>
+<p>We use a Google+ page to host Hangouts for developers, talk about the latest
+releases, development and design tips, and much more.</p>
+
+<div style='margin-top:1em'><g:plus href='https://plus.google.com/108967384991768947849'
+size='badge'></g:plus></div>
+
+
<h3 id="twitter">Twitter</h3>
<p>You can follow us on Twitter at this account:</p>
<p style="margin-left:2em;"><a href="http://twitter.com/androiddev">http://twitter.com/androiddev</a></p>
+<script type="text/javascript" src="https://plus.google.com/108967384991768947849"
+rel="publisher"></script>
+<script type="text/javascript">
+window.___gcfg = {lang: 'en'};
+(function()
+{var po = document.createElement("script");
+po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
+var s = document.getElementsByTagName("script")[0];
+s.parentNode.insertBefore(po, s);
+})();</script> \ No newline at end of file
diff --git a/docs/html/resources/dashboard/opengl.jd b/docs/html/resources/dashboard/opengl.jd
index 357c1ea4b797..d55ab2b54935 100644
--- a/docs/html/resources/dashboard/opengl.jd
+++ b/docs/html/resources/dashboard/opengl.jd
@@ -57,7 +57,7 @@ ending on the data collection date noted below.</p>
<div class="dashboard-panel">
<img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.5,90.5" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1%20only|GL%202.0%20%26%201.1&chd=t%3A10.7,89.3" />
<table>
<tr>
@@ -65,15 +65,15 @@ src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=
<th scope="col">Distribution</th>
</tr>
<tr>
-<td>1.1</th>
-<td>9.5%</td>
+<td>1.1 only</th>
+<td>10.7%</td>
</tr>
<tr>
-<td>2.0</th>
-<td>90.5%</td>
+<td>2.0 &amp; 1.1</th>
+<td>89.3%</td>
</tr>
</table>
-<p><em>Data collected during a 7-day period ending on January 3, 2012</em></p>
+<p><em>Data collected during a 7-day period ending on February 1, 2012</em></p>
</div>
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 2618a0424b49..4ea52aff393d 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,7 +52,7 @@ Android Market within a 14-day period ending on the data collection date noted b
<div class="dashboard-panel">
<img alt="" height="250" width="470"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.6,1.1,8.5,30.4,0.6,54.9,0.1,1.5,1.7,0.3,0.3&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2|Android%204.0|Android%204.0.3&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.6,1.0,7.6,27.8,0.5,58.1,0.1,1.4,1.9,0.3,0.7&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2|Android%204.0|Android%204.0.3&chco=c4df9b,6fad0c" />
<table>
<tr>
@@ -62,24 +62,24 @@ src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.6,1.1,8.5,30.
<th>Distribution</th>
</tr>
<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td> <td>3</td><td>0.6%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td> <td>4</td><td>1.1%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td> <td>7</td><td>8.5%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td> <td>8</td><td>30.4%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td> <td>4</td><td>1.0%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td> <td>7</td><td>7.6%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td> <td>8</td><td>27.8%</td></tr>
<tr><td><a href="{@docRoot}sdk/android-2.3.html">Android 2.3 -<br/>
- Android 2.3.2</a></td><td rowspan="2">Gingerbread</td> <td>9</td><td>0.6%</td></tr>
+ Android 2.3.2</a></td><td rowspan="2">Gingerbread</td> <td>9</td><td>0.5%</td></tr>
<tr><td><a href="{@docRoot}sdk/android-2.3.3.html">Android 2.3.3 -<br/>
- Android 2.3.7</a></td><!-- Gingerbread --> <td>10</td><td>54.9%</td></tr>
+ Android 2.3.7</a></td><!-- Gingerbread --> <td>10</td><td>58.1%</td></tr>
<tr><td><a href="{@docRoot}sdk/android-3.0.html">Android 3.0</a></td>
<td rowspan="3">Honeycomb</td> <td>11</td><td>0.1%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>1.5%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>1.7%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>1.4%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>1.9%</td></tr>
<tr><td><a href="{@docRoot}sdk/android-4.0.html">Android 4.0 -<br/>
Android 4.0.2</a></td>
<td rowspan="2">Ice Cream Sandwich</td><td>14</td><td>0.3%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-4.0.3.html">Android 4.0.3</a></td><!-- ICS --><td>15</td><td>0.3%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-4.0.3.html">Android 4.0.3</a></td><!-- ICS --><td>15</td><td>0.7%</td></tr>
</table>
-<p><em>Data collected during a 14-day period ending on January 3, 2012</em></p>
+<p><em>Data collected during a 14-day period ending on February 1, 2012</em></p>
<!--
<p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
-->
@@ -108,9 +108,9 @@ Android Market within a 14-day period ending on the date indicated on the x-axis
<div class="dashboard-panel">
<img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C10/15%7C11/01%7C11/15%7C12/01%7C12/15%7C01/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.2,99.0,98.8,98.7,98.5,98.5,98.2,98.1,98.0,99.9,99.9,99.7,99.2|97.7,97.6,97.5,97.5,97.5,97.5,97.1,97.1,97.0,99.1,99.1,99.0,98.6|95.5,95.5,95.5,95.6,95.7,95.8,95.6,95.9,95.7,97.7,97.8,97.8,97.5|77.6,79.0,80.2,81.1,82.4,83.3,83.8,84.9,85.1,87.5,88.2,88.6,89.0|17.8,20.6,24.3,27.5,31.2,34.7,38.3,41.3,44.0,48.9,52.9,55.7,58.5|16.8,20.0,23.7,26.9,30.6,34.1,37.8,40.8,43.5,48.4,52.4,55.2,57.9|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,2.3,2.6,3.2|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.2,1.3,1.7&chm=b,c3df9b,0,1,0|b,b8dc82,1,2,0|tAndroid 2.1,608920,2,0,15,,t::-5|b,addb67,2,3,0|tAndroid 2.2,517617,3,0,15,,t::-5|b,a3db4b,3,4,0|b,98dc2e,4,5,0|tAndroid 2.3.3,334d0a,5,0,15,,t::-5|b,8cd41b,5,6,0|b,7ec113,6,7,0|B,6fad0c,7,8,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3|Android 3.1|Android 3.2&chco=add274,a2d15a,97d13e,8bcb28,7dba1e,6ea715,5f920e,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C10/15%7C11/01%7C11/15%7C12/01%7C12/15%7C01/01%7C01/15%7C02/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:98.2,98.1,97.9,97.9,97.7,97.6,97.5,99.4,99.4,99.2,98.6,98.4,98.5|96.9,96.9,96.9,96.9,96.6,96.6,96.5,98.6,98.6,98.5,98.0,97.8,97.9|94.9,95.0,95.1,95.2,95.1,95.4,95.2,97.2,97.3,97.3,96.9,96.8,96.9|79.6,80.5,81.8,82.7,83.3,84.4,84.6,87.0,87.7,88.1,88.4,88.8,89.2|23.7,26.9,30.6,34.1,37.8,40.8,43.5,48.4,52.4,55.2,57.9,59.7,61.3|0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,2.3,2.6,3.2,3.2,3.3|0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.2,1.3,1.7,1.8,1.9&chm=b,c3df9b,0,1,0|b,b6dc7d,1,2,0|tAndroid%202.1,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|tAndroid%202.2,496c13,3,0,15,,t::-5|b,9ddb3d,3,4,0|tAndroid%202.3.3,38540b,4,0,15,,t::-5|b,91da1e,4,5,0|b,80c414,5,6,0|B,6fad0c,6,7,0&chg=7,25&chdl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08" />
-<p><em>Last historical dataset collected during a 14-day period ending on January 3, 2012</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on February 1, 2012</em></p>
</div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index 79d59d91aa7b..ae5cdc735915 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -60,7 +60,7 @@ ending on the data collection date noted below.</p>
<div class="dashboard-panel">
<img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A3.1,0.1,3.1,71.0,1.0,17.5,2.9,1.3" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Normal%20/%20xhdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A4.8,0.2,2.9,67.1,0.7,18.4,1.8,2.5,1.6" />
<table>
<tr>
@@ -71,31 +71,31 @@ src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=
<th scope="col">xhdpi</th>
</tr>
<tr><th scope="row">small</th>
-<td>1.3%</td> <!-- small/ldpi -->
+<td>1.6%</td> <!-- small/ldpi -->
<td></td> <!-- small/mdpi -->
-<td>2.9%</td> <!-- small/hdpi -->
+<td>2.5%</td> <!-- small/hdpi -->
<td></td> <!-- small/xhdpi -->
</tr>
<tr><th scope="row">normal</th>
-<td>1.0%</td> <!-- normal/ldpi -->
-<td>17.5%</td> <!-- normal/mdpi -->
-<td>71%</td> <!-- normal/hdpi -->
-<td></td> <!-- normal/xhdpi -->
+<td>0.7%</td> <!-- normal/ldpi -->
+<td>18.4%</td> <!-- normal/mdpi -->
+<td>67.1%</td> <!-- normal/hdpi -->
+<td>1.8%</td> <!-- normal/xhdpi -->
</tr>
<tr><th scope="row">large</th>
-<td>0.1%</td> <!-- large/ldpi -->
-<td>3.1%</td> <!-- large/mdpi -->
+<td>0.2%</td> <!-- large/ldpi -->
+<td>2.9%</td> <!-- large/mdpi -->
<td></td> <!-- large/hdpi -->
<td></td> <!-- large/xhdpi -->
</tr>
<tr><th scope="row">xlarge</th>
<td></td> <!-- xlarge/ldpi -->
-<td>3.1%</td> <!-- xlarge/mdpi -->
+<td>4.8%</td> <!-- xlarge/mdpi -->
<td></td> <!-- xlarge/hdpi -->
<td></td> <!-- xlarge/xhdpi -->
</tr>
</table>
-<p><em>Data collected during a 7-day period ending on December 1, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on February 1, 2012</em></p>
</div>
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index 8df419fd5a6a..848303751a1c 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -1,7 +1,8 @@
<ul>
<li>
- <h2><span class="en">Android Training</span>
- </h2>
+ <span class="heading">
+ <span class="en">Android Training</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>training/index.html">
@@ -237,8 +238,9 @@
<li>
- <h2><span class="en">Technical Resources</span>
- </h2>
+ <span class="heading">
+ <span class="en">Technical Resources</span>
+ </span>
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>resources/browser.html?tag=sample">
@@ -288,29 +290,31 @@
</ul>
</li>
<li>
- <h2><span class="en">Community</span>
- <span style="display:none" class="de"></span>
- <span style="display:none" class="es">Comunidad</span>
- <span style="display:none" class="fr">Communauté</span>
- <span style="display:none" class="it"></span>
- <span style="display:none" class="ja">コミュニティ</span>
- <span style="display:none" class="zh-CN">社区</span>
- <span style="display:none" class="zh-TW">社群</span>
- </h2>
+ <span class="heading">
+ <span class="en">Community</span>
+ <span style="display:none" class="de"></span>
+ <span style="display:none" class="es">Comunidad</span>
+ <span style="display:none" class="fr">Communauté</span>
+ <span style="display:none" class="it"></span>
+ <span style="display:none" class="ja">コミュニティ</span>
+ <span style="display:none" class="zh-CN">社区</span>
+ <span style="display:none" class="zh-TW">社群</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>resources/community-groups.html">
<span class="en">Developer Forums</span>
</a></li>
<li><a href="<?cs var:toroot ?>resources/community-more.html">
- <span class="en">IRC, Twitter</span>
+ <span class="en">IRC, G+, Twitter</span>
</a></li>
</ul>
</li>
<?cs
if:android.whichdoc == "online" ?>
<li>
- <h2><span class="en">Device Dashboard</span>
- </h2>
+ <span class="heading">
+ <span class="en">Device Dashboard</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>resources/dashboard/platform-versions.html">
<span class="en">Platform Versions</span>
@@ -327,7 +331,9 @@
?>
<li>
- <h2><span class="en">More</span></h2>
+ <span class="heading">
+ <span class="en">More</span>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>resources/faq/commontasks.html">
<span class="en">Common Tasks </span>
diff --git a/docs/html/sdk/android-2.3.3.jd b/docs/html/sdk/android-2.3.3.jd
index 7a5b044c9687..023e2e41294a 100644
--- a/docs/html/sdk/android-2.3.3.jd
+++ b/docs/html/sdk/android-2.3.3.jd
@@ -336,7 +336,7 @@ descriptor).</p>
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/android-2.3.4.jd b/docs/html/sdk/android-2.3.4.jd
index 4cb44b921b5a..eeaa69ab169f 100644
--- a/docs/html/sdk/android-2.3.4.jd
+++ b/docs/html/sdk/android-2.3.4.jd
@@ -296,7 +296,7 @@ descriptor).</p>
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/android-2.3.jd b/docs/html/sdk/android-2.3.jd
index e7aa0fac727a..fc4f5aa95a24 100644
--- a/docs/html/sdk/android-2.3.jd
+++ b/docs/html/sdk/android-2.3.jd
@@ -859,7 +859,7 @@ descriptor).</p>
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/android-3.0.jd b/docs/html/sdk/android-3.0.jd
index 96b92d9a59e3..49fefee535d4 100644
--- a/docs/html/sdk/android-3.0.jd
+++ b/docs/html/sdk/android-3.0.jd
@@ -1119,7 +1119,7 @@ descriptor).</p>
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/android-3.1.jd b/docs/html/sdk/android-3.1.jd
index 78f265d2f055..b9cf96940364 100644
--- a/docs/html/sdk/android-3.1.jd
+++ b/docs/html/sdk/android-3.1.jd
@@ -1040,7 +1040,7 @@ descriptor).</p>
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/android-4.0.3.jd b/docs/html/sdk/android-4.0.3.jd
index 1fca8dff35ea..809c83c6e61d 100644
--- a/docs/html/sdk/android-4.0.3.jd
+++ b/docs/html/sdk/android-4.0.3.jd
@@ -435,7 +435,7 @@ image are listed below (with <em>language</em>_<em>country/region</em> locale de
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
index 5f55947bb0e6..2cad86b7a686 100644
--- a/docs/html/sdk/android-4.0.jd
+++ b/docs/html/sdk/android-4.0.jd
@@ -1963,7 +1963,7 @@ image are listed below (with <em>language</em>_<em>country/region</em> locale de
<li>English, New Zealand (en_NZ)</li>
<li>English, Singapore(en_SG)</li>
<li>English, US (en_US)</li>
-<li>English, Zimbabwe (en_ZA)</li>
+<li>English, South Africa (en_ZA)</li>
<li>Spanish (es_ES)</li>
<li>Spanish, US (es_US)</li>
<li>Finnish, Finland (fi_FI)</li>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index f15da78710ad..30825eec060c 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -42,7 +42,7 @@ export signed (or unsigned) {@code .apk} files in order to distribute your appli
<p>Developing in Eclipse with ADT is highly recommended and is the fastest way
to get started. With the guided project setup it provides, as well as tools
-integration, custom XML editors, and debug ouput pane, ADT gives you an
+integration, custom XML editors, and debug output pane, ADT gives you an
incredible boost in developing Android applications. </p>
<p>This document provides step-by-step instructions on how to download the ADT
@@ -1104,7 +1104,7 @@ ADT installation as described in the steps below. </p>
<h3 id="downloading">Downloading the ADT Plugin</h3>
<p>Use the Update Manager feature of your Eclipse installation to install the latest
-revision of ADT on your development computer.<>
+revision of ADT on your development computer.</p>
<p>Assuming that you have a compatible version of the Eclipse IDE installed, as
described in <a href="#preparing">Preparing for Installation</a>, above, follow
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 65a1f465c475..5cf05e0ec1bc 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,4 +1,5 @@
page.title=Android SDK
+page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
sdk.redirect=0
sdk.win_installer=installer_r16-windows.exe
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 5f6a57fc2168..0de477a25dfa 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -1,7 +1,7 @@
<?cs if:!sdk.redirect ?>
<ul>
<li>
- <h2>
+ <span class="heading">
<span class="en">Android SDK Starter Package</span>
<span style="display:none" class="de">Aktuelle SDK-Version</span>
<span style="display:none" class="es">Versión actual del SDK</span>
@@ -10,7 +10,7 @@
<span style="display:none" class="ja">現在リリースされている SDK</span>
<span style="display:none" class="zh-CN">当前的 SDK 版本</span>
<span style="display:none" class="zh-TW">目前 SDK 發行版本</span>
- </h2>
+ </span>
<ul><?cs
if:android.whichdoc == "online" ?>
<li><a href="<?cs var:toroot ?>sdk/index.html">
@@ -37,7 +37,8 @@
</ul>
</li><?cs
if:sdk.preview ?>
- <li><h2>Android 3.0 Preview SDK</h2>
+ <li>
+ <span class="heading">Android 3.0 Preview SDK</span>
<ul>
<li><a href="<?cs var:toroot ?>sdk/preview/start.html">Getting Started</a> <span
class="new">new!</span></li>
@@ -46,13 +47,14 @@ class="new">new!</span></li>
/if ?>
<?cs
if:sdk.preview ?>
- <li><h2>Android x.x Preview</h2>
+ <li>
+ <span class="heading">Android x.x Preview</span>
<ul>
</ul>
</li><?cs
/if ?>
<li>
- <h2>
+ <span class="heading">
<span class="en">Downloadable SDK Components</span>
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
@@ -61,7 +63,7 @@ class="new">new!</span></li>
<span style="display:none" class="ja"></span>
<span style="display:none" class="zh-CN"></span>
<span style="display:none" class="zh-TW"></span>
- </h2>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>sdk/adding-components.html">
<span class="en">Adding SDK Components</span>
@@ -158,7 +160,7 @@ class="new">new!</span></li>
</ul>
</li>
<li>
- <h2>
+ <span class="heading">
<span class="en">ADT Plugin for Eclipse</span>
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
@@ -167,7 +169,7 @@ class="new">new!</span></li>
<span style="display:none" class="ja"></span>
<span style="display:none" class="zh-CN"></span>
<span style="display:none" class="zh-TW"></span>
- </h2>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 16.0.1
<span style="display:none" class="de"></span>
@@ -182,7 +184,8 @@ class="new">new!</span>
</ul>
</li>
<li>
- <h2><span class="en">Native Development Tools</span>
+ <span class="heading">
+ <span class="en">Native Development Tools</span>
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
@@ -190,7 +193,7 @@ class="new">new!</span>
<span style="display:none" class="ja"></span>
<span style="display:none" class="zh-CN"></span>
<span style="display:none" class="zh-TW"></span>
- </h2>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r7</a>
<span class="new">new!</span>
@@ -200,7 +203,7 @@ class="new">new!</span>
</li>
<li>
- <h2>
+ <span class="heading">
<span class="en">More Information</span>
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
@@ -209,7 +212,7 @@ class="new">new!</span>
<span style="display:none" class="ja"></span>
<span style="display:none" class="zh-CN"></span>
<span style="display:none" class="zh-TW"></span>
- </h2>
+ </span>
<ul>
<li><a href="<?cs var:toroot ?>sdk/oem-usb.html">
<span class="en">OEM USB Drivers</span>
diff --git a/docs/html/shareables/adl/2010Q2_Business_Overview.pdf b/docs/html/shareables/adl/2010Q2_Business_Overview.pdf
deleted file mode 100644
index c34ea1566736..000000000000
--- a/docs/html/shareables/adl/2010Q2_Business_Overview.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/html/shareables/adl/2010Q2_Market_Overview.pdf b/docs/html/shareables/adl/2010Q2_Market_Overview.pdf
deleted file mode 100644
index 3752258d2d35..000000000000
--- a/docs/html/shareables/adl/2010Q2_Market_Overview.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/html/shareables/adl/2010Q2_SDK_Overview.pdf b/docs/html/shareables/adl/2010Q2_SDK_Overview.pdf
deleted file mode 100644
index 8796584d2ded..000000000000
--- a/docs/html/shareables/adl/2010Q2_SDK_Overview.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdf b/docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdf
deleted file mode 100644
index 598a27e7c4e7..000000000000
--- a/docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdf b/docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdf
deleted file mode 100644
index 6ef41dd8271b..000000000000
--- a/docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdf b/docs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdf
deleted file mode 100755
index e56d23779dff..000000000000
--- a/docs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdf
+++ /dev/null
Binary files differ
diff --git a/docs/html/shareables/icon_templates-v1.0.zip b/docs/html/shareables/icon_templates-v1.0.zip
deleted file mode 100644
index 94fbcdcea6cc..000000000000
--- a/docs/html/shareables/icon_templates-v1.0.zip
+++ /dev/null
Binary files differ
diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt
index 0298a8ed28c1..cfbda2bac083 100644
--- a/docs/html/sitemap.txt
+++ b/docs/html/sitemap.txt
@@ -231,7 +231,6 @@ http://developer.android.com/resources/samples/JetBoy/index.html
http://developer.android.com/resources/samples/CubeLiveWallpaper/index.html
http://developer.android.com/resources/samples/LunarLander/index.html
http://developer.android.com/resources/samples/MultiResolution/index.html
-http://developer.android.com/resources/samples/NFCDemo/index.html
http://developer.android.com/resources/samples/NotePad/index.html
http://developer.android.com/resources/samples/SampleSyncAdapter/index.html
http://developer.android.com/resources/samples/SearchableDictionary/index.html
@@ -1996,17 +1995,6 @@ http://developer.android.com/reference/java/io/Reader.html
http://developer.android.com/reference/android/content/DialogInterface.html
http://developer.android.com/reference/org/apache/http/message/BasicHeaderIterator.html
http://developer.android.com/reference/org/apache/http/message/BasicListHeaderIterator.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/TagViewer.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/NdefMessageParser.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/record/ParsedNdefRecord.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/record/SmartPoster.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/record/TextRecord.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/record/UriRecord.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/simulator/FakeTagsActivity.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/simulator/MockNdefMessages.html
-http://developer.android.com/resources/samples/NFCDemo/res/index.html
-http://developer.android.com/resources/samples/NFCDemo/src/index.html
-http://developer.android.com/resources/samples/NFCDemo/AndroidManifest.html
http://developer.android.com/reference/java/lang/InternalError.html
http://developer.android.com/reference/java/lang/Error.html
http://developer.android.com/reference/java/lang/VirtualMachineError.html
@@ -3039,7 +3027,6 @@ http://developer.android.com/sdk/api_diff/3/changes/pkg_dalvik.system.html
http://developer.android.com/sdk/api_diff/3/changes/pkg_java.lang.html
http://developer.android.com/sdk/api_diff/3/changes/pkg_java.util.jar.html
http://developer.android.com/sdk/api_diff/3/changes/pkg_java.util.logging.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/index.html
http://developer.android.com/sdk/api_diff/9/changes/alldiffs_index_removals.html
http://developer.android.com/sdk/api_diff/9/changes/alldiffs_index_additions.html
http://developer.android.com/sdk/api_diff/9/changes/alldiffs_index_changes.html
@@ -3514,7 +3501,6 @@ http://developer.android.com/reference/javax/sql/ConnectionPoolDataSource.html
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/LabelView.html
http://developer.android.com/resources/samples/ApiDemos/res/layout/custom_view_1.html
http://developer.android.com/resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/index.html
http://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html
http://developer.android.com/reference/android/location/package-descr.html
http://developer.android.com/resources/samples/AccessibilityService/res/values/strings.html
@@ -3939,10 +3925,6 @@ http://developer.android.com/reference/android/graphics/drawable/shapes/RoundRec
http://developer.android.com/resources/samples/ContactManager/res/drawable-mdpi/icon.html
http://developer.android.com/resources/samples/BackupRestore/src/com/example/index.html
http://developer.android.com/reference/org/apache/http/message/package-descr.html
-http://developer.android.com/resources/samples/NFCDemo/res/drawable/index.html
-http://developer.android.com/resources/samples/NFCDemo/res/layout/index.html
-http://developer.android.com/resources/samples/NFCDemo/res/raw/index.html
-http://developer.android.com/resources/samples/NFCDemo/res/values/index.html
http://developer.android.com/reference/android/bluetooth/package-descr.html
http://developer.android.com/resources/samples/SipDemo/res/drawable/index.html
http://developer.android.com/resources/samples/SipDemo/res/layout/index.html
@@ -4110,7 +4092,6 @@ http://developer.android.com/sdk/api_diff/9/changes/methods_index_removals.html
http://developer.android.com/sdk/api_diff/9/changes/methods_index_additions.html
http://developer.android.com/sdk/api_diff/9/changes/methods_index_changes.html
http://developer.android.com/reference/android/media/audiofx/package-descr.html
-http://developer.android.com/resources/samples/NFCDemo/res/values/strings.html
http://developer.android.com/reference/android/sax/ElementListener.html
http://developer.android.com/reference/android/sax/EndElementListener.html
http://developer.android.com/reference/android/sax/EndTextElementListener.html
@@ -4599,7 +4580,6 @@ http://developer.android.com/resources/samples/SoftKeyboard/src/com/index.html
http://developer.android.com/reference/android/text/method/package-descr.html
http://developer.android.com/resources/samples/JetBoy/JETBOY_content/JETBOY_Music.logic/LgDoc/index.html
http://developer.android.com/resources/samples/TicTacToeMain/res/layout/main.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/index.html
http://developer.android.com/resources/samples/SearchableDictionary/res/drawable-mdpi/ic_menu_search.html
http://developer.android.com/resources/samples/TicTacToeMain/res/values/strings.html
http://developer.android.com/sdk/api_diff/7/changes/alldiffs_index_additions.html
@@ -4637,9 +4617,6 @@ http://developer.android.com/resources/samples/SoftKeyboard/res/values/index.htm
http://developer.android.com/resources/samples/SoftKeyboard/res/values-land/index.html
http://developer.android.com/resources/samples/SoftKeyboard/res/xml/index.html
http://developer.android.com/reference/junit/runner/package-descr.html
-http://developer.android.com/resources/samples/NFCDemo/res/layout/tag_divider.html
-http://developer.android.com/resources/samples/NFCDemo/res/layout/tag_text.html
-http://developer.android.com/resources/samples/NFCDemo/res/layout/tag_viewer.html
http://developer.android.com/resources/samples/AccelerometerPlay/res/drawable-ldpi/icon.html
http://developer.android.com/resources/samples/CubeLiveWallpaper/src/com/example/index.html
http://developer.android.com/reference/android/text/style/package-descr.html
@@ -4726,14 +4703,12 @@ http://developer.android.com/resources/samples/SoftKeyboard/res/values-land/dime
http://developer.android.com/sdk/api_diff/3/changes/classes_index_additions.html
http://developer.android.com/sdk/api_diff/3/changes/classes_index_changes.html
http://developer.android.com/resources/samples/WiktionarySimple/src/com/index.html
-http://developer.android.com/resources/samples/NFCDemo/res/drawable/icon.html
http://developer.android.com/resources/samples/SearchableDictionary/res/drawable-hdpi/ic_menu_search.html
http://developer.android.com/resources/samples/SipDemo/res/values/strings.html
http://developer.android.com/resources/samples/SpinnerTest/src/com/android/index.html
http://developer.android.com/sdk/api_diff/3/changes/methods_index_removals.html
http://developer.android.com/sdk/api_diff/3/changes/methods_index_additions.html
http://developer.android.com/sdk/api_diff/3/changes/methods_index_changes.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/index.html
http://developer.android.com/resources/samples/SoftKeyboard/res/xml/method.html
http://developer.android.com/resources/samples/SoftKeyboard/res/xml/qwerty.html
http://developer.android.com/resources/samples/SoftKeyboard/res/xml/symbols.html
@@ -5326,8 +5301,6 @@ http://developer.android.com/resources/samples/ApiDemos/res/drawable-ldpi/stylog
http://developer.android.com/sdk/api_diff/5/changes/alldiffs_index_removals.html
http://developer.android.com/sdk/api_diff/5/changes/alldiffs_index_additions.html
http://developer.android.com/sdk/api_diff/5/changes/alldiffs_index_changes.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/record/index.html
-http://developer.android.com/resources/samples/NFCDemo/src/com/example/android/nfc/simulator/index.html
http://developer.android.com/resources/samples/BackupRestore/src/com/example/android/index.html
http://developer.android.com/resources/samples/BluetoothChat/src/com/example/android/BluetoothChat/index.html
http://developer.android.com/resources/samples/ContactManager/src/com/example/android/index.html
diff --git a/docs/html/training/design-navigation/ancestral-temporal.jd b/docs/html/training/design-navigation/ancestral-temporal.jd
index 02e43e150bd1..c0b1aef738e9 100644
--- a/docs/html/training/design-navigation/ancestral-temporal.jd
+++ b/docs/html/training/design-navigation/ancestral-temporal.jd
@@ -21,6 +21,7 @@ next.link=wireframing.html
<h2>You should also read</h2>
<ul>
+ <li><a href="{@docRoot}design/patterns/navigation.html">Android Design: Navigation</a></li>
<li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a></li>
</ul>
@@ -30,6 +31,11 @@ next.link=wireframing.html
<p>Now that users can navigate <a href="descendant-lateral.html">deep into</a> the application's screen hierarchy, we need to provide a method for navigating up the hierarchy, to parent and ancestor screens. Additionally, we should ensure that temporal navigation via the BACK button is respected to respect Android conventions.</p>
+<div class="design-announce">
+<p><strong>Back/Up Navigation Design</strong></p>
+ <p>For design guidelines, read Android Design's <a
+ href="{@docRoot}design/patterns/navigation.html">Navigation</a> pattern guide.</p>
+</div>
<h2 id="temporal-navigation">Support Temporal Navigation: <em>Back</em></h2>
@@ -49,7 +55,7 @@ next.link=wireframing.html
<h2 id="ancestral-navigation">Provide Ancestral Navigation: <em>Up</em> and <em>Home</em></h2>
-<p>Before Android 3.0, the most common form of ancestral navigation was the <em>Home</em> metaphor. This was generally implemented as a <em>Home</em> item accessible via the device's MENU button, or a <em>Home</em> button at the top-left of the screen, usually as a component of the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>. Upon selecting <em>Home</em>, the user would be taken to the screen at the top of the screen hierarchy, generally known as the application's home screen.</p>
+<p>Before Android 3.0, the most common form of ancestral navigation was the <em>Home</em> metaphor. This was generally implemented as a <em>Home</em> item accessible via the device's MENU button, or a <em>Home</em> button at the top-left of the screen, usually as a component of the Action Bar (<a href="{@docRoot}design/patterns/actionbar.html">pattern docs</a> at Android Design). Upon selecting <em>Home</em>, the user would be taken to the screen at the top of the screen hierarchy, generally known as the application's home screen.</p>
<p>Providing direct access to the application's home screen can give the user a sense of comfort and security. Regardless of where they are in the application, if they get lost in the app, they can select <em>Home</em> to arrive back at the familiar home screen.</p>
diff --git a/docs/html/training/design-navigation/descendant-lateral.jd b/docs/html/training/design-navigation/descendant-lateral.jd
index ebfd913fe848..0064bd495c2d 100644
--- a/docs/html/training/design-navigation/descendant-lateral.jd
+++ b/docs/html/training/design-navigation/descendant-lateral.jd
@@ -18,9 +18,18 @@ next.link=ancestral-temporal.html
<li><a href="#buttons">Buttons and Simple Targets</a></li>
<li><a href="#lists">Lists, Grids, Carousels, and Stacks</a></li>
<li><a href="#tabs">Tabs</a></li>
- <li><a href="#paging">Horizontal Paging</a></li>
+ <li><a href="#paging">Horizontal Paging (Swipe Views)</a></li>
</ol>
+<h2>You should also read</h2>
+<ul>
+ <li><a href="{@docRoot}design/building-blocks/buttons.html">Android Design: Buttons</a></li>
+ <li><a href="{@docRoot}design/building-blocks/lists.html">Android Design: Lists</a></li>
+ <li><a href="{@docRoot}design/building-blocks/grid-lists.html">Android Design: Grid Lists</a></li>
+ <li><a href="{@docRoot}design/building-blocks/tabs.html">Android Design: Tabs</a></li>
+ <li><a href="{@docRoot}design/patterns/swipe-views.html">Android Design: Swipe Views</a></li>
+</ul>
+
</div>
</div>
@@ -48,6 +57,12 @@ next.link=ancestral-temporal.html
<h2 id="buttons">Buttons and Simple Targets</h2>
+<div class="design-announce">
+<p><strong>Button Design</strong></p>
+ <p>For design guidelines, read Android Design's <a
+ href="{@docRoot}design/building-blocks/buttons.html">Buttons</a> guide.</p>
+</div>
+
<p>For section-related screens, offering touchable and keyboard-focusable targets in the parent is generally the most straightforward and familiar kind of touch-based navigation interface. Examples of such targets include buttons, fixed-size list views, or text links, although the latter is not an ideal UI (user interface) element for touch-based navigation. Upon selecting one of these targets, the child screen is opened, replacing the current context (screen) entirely. Buttons and other simple targets are rarely used for representing items in a collection.</p>
@@ -64,6 +79,13 @@ next.link=ancestral-temporal.html
<h2 id="lists">Lists, Grids, Carousels, and Stacks</h2>
+<div class="design-announce">
+<p><strong>List and Grid List Design</strong></p>
+ <p>For design guidelines, read Android Design's <a
+ href="{@docRoot}design/building-blocks/lists.html">Lists</a> and <a
+ href="{@docRoot}design/building-blocks/grid-lists.html">Grid Lists</a> guides.</p>
+</div>
+
<p>For collection-related screens, and especially for textual information, vertically scrolling lists are often the most straightforward and familiar kind of interface. For more visual or media-rich content items such as photos or videos, vertically scrolling grids of items, horizontally scrolling lists (sometimes referred to as <em>carousels</em>), or stacks (sometimes referred to as <em>cards</em>) can be used instead. These UI elements are generally best used for presenting item collections or large sets of child screens (for example, a list of stories or a list of 10 or more news topics), rather than a small set of unrelated, sibling child screens.</p>
@@ -80,6 +102,12 @@ next.link=ancestral-temporal.html
<h2 id="tabs">Tabs</h2>
+<div class="design-announce">
+<p><strong>Tab Design</strong></p>
+ <p>For design guidelines, read Android Design's <a
+ href="{@docRoot}design/building-blocks/tabs.html">Tabs</a> guide.</p>
+</div>
+
<p>Using tabs is a very popular solution for lateral navigation. This pattern allows grouping of sibling screens, in that the tab content container in the parent screen can embed child screens that otherwise would be entirely separate contexts. Tabs are most appropriate for small sets (4 or fewer) of section-related screens.</p>
@@ -89,7 +117,7 @@ next.link=ancestral-temporal.html
<p class="img-caption"><strong>Figure 5.</strong> Example phone and tablet tab-based navigation interfaces with relevant screen map excerpt.</p>
-<p>Several best practices apply when using tabs. Tabs should be persistent across immediate related screens. Only the designated content region should change when selecting a tab, and tab indicators should remain available at all times. Additionally, tab switches should not be treated as history. For example, if a user switches from a tab <em>A</em> to another tab <em>B</em>, pressing the BACK button (more on that in the <a href="ancestral-temporal.html">next lesson</a>) should not re-select tab <em>A</em>. Tabs are usually laid out horizontally, although other presentations of tab navigation such as using a drop-down list in the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> are sometimes appropriate. Lastly, and most importantly, <em>tabs should always run along the top of the screen</em>, and should not be aligned to the bottom of the screen.</p>
+<p>Several best practices apply when using tabs. Tabs should be persistent across immediate related screens. Only the designated content region should change when selecting a tab, and tab indicators should remain available at all times. Additionally, tab switches should not be treated as history. For example, if a user switches from a tab <em>A</em> to another tab <em>B</em>, pressing the BACK button (more on that in the <a href="ancestral-temporal.html">next lesson</a>) should not re-select tab <em>A</em>. Tabs are usually laid out horizontally, although other presentations of tab navigation such as using a drop-down list in the Action Bar (<a href="{@docRoot}design/patterns/actionbar.html">pattern docs</a> at Android Design) are sometimes appropriate. Lastly, and most importantly, <em>tabs should always run along the top of the screen</em>, and should not be aligned to the bottom of the screen.</p>
<p>There are some obvious immediate benefits of tabs over simpler list- and button-based navigation:</p>
@@ -101,9 +129,15 @@ next.link=ancestral-temporal.html
<p>A common criticism is that space must be reserved for the tab indicators, detracting from the space available to tab contents. This consequence is usually acceptable, and the tradeoff commonly weighs in favor of using this pattern. You should also feel free to customize tab indicators, showing text and/or icons to make optimal use of vertical space. When adjusting indicator heights however, ensure that tab indicators are large enough for a human finger to touch without error.</p>
-<h2 id="paging">Horizontal Paging</h2>
+<h2 id="paging">Horizontal Paging (Swipe Views)</h2>
+
+<div class="design-announce">
+<p><strong>Swipe Views Design</strong></p>
+ <p>For design guidelines, read Android Design's <a
+ href="{@docRoot}design/patterns/swipe-views.html">Swipe Views</a> pattern guides.</p>
+</div>
-<p>Another popular lateral navigation pattern is horizontal paging. This pattern applies best to collection-related sibling screens, such as a list of categories (world, business, technology, and health stories). Like tabs, this pattern also allows grouping screens in that the parent presents the contents of child screens embedded within its own layout.</p>
+<p>Another popular lateral navigation pattern is horizontal paging, also referred to as swipe views. This pattern applies best to collection-related sibling screens, such as a list of categories (world, business, technology, and health stories). Like tabs, this pattern also allows grouping screens in that the parent presents the contents of child screens embedded within its own layout.</p>
<img src="{@docRoot}images/training/app-navigation-descendant-lateral-paging.png"
diff --git a/docs/html/training/design-navigation/index.jd b/docs/html/training/design-navigation/index.jd
index e02d52eb279f..cb20a606861e 100644
--- a/docs/html/training/design-navigation/index.jd
+++ b/docs/html/training/design-navigation/index.jd
@@ -14,7 +14,7 @@ next.link=screen-planning.html
<p>This class is not specific to any particular version of the Android platform. It is also primarily design-focused and does not require knowledge of the Android SDK. That said, you should have experience using an Android device for a better understanding of the context in which Android applications run.</p>
-<p>You should also have basic familiarity with the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>, used across most applications in devices running Android 3.0 and later.</p>
+<p>You should also have basic familiarity with the Action Bar (<a href="{@docRoot}design/patterns/actionbar.html">pattern docs</a> at Android Design), used across most applications in devices running Android 3.0 and later.</p>
</div>
diff --git a/docs/html/training/design-navigation/multiple-sizes.jd b/docs/html/training/design-navigation/multiple-sizes.jd
index 7a8139f08910..ebaec0f567a0 100644
--- a/docs/html/training/design-navigation/multiple-sizes.jd
+++ b/docs/html/training/design-navigation/multiple-sizes.jd
@@ -22,6 +22,7 @@ next.link=descendant-lateral.html
<h2>You should also read</h2>
<ul>
+ <li><a href="{@docRoot}design/patterns/multi-pane-layouts.html">Android Design: Multi-pane Layouts</a></li>
<li><a href="{@docRoot}training/multiscreen/index.html">Designing for Multiple Screens</a></li>
</ul>
@@ -35,6 +36,12 @@ next.link=descendant-lateral.html
<h2 id="multi-pane-layouts">Group Screens with Multi-pane Layouts</h2>
+<div class="design-announce">
+<p><strong>Multi-pane Layout Design</strong></p>
+ <p>For design guidelines, read Android Design's <a
+ href="{@docRoot}design/patterns/multi-pane-layouts.html">Multi-pane Layouts</a> pattern guide.</p>
+</div>
+
<p>3 to 4-inch screens are generally only suitable for showing a single vertical pane of content at a time, be it a list of items, or detail information about an item, etc. Thus on such devices, screens generally map one-to-one with levels in the information hierarchy (<em>categories</em> &rarr; <em>object list</em> &rarr; <em>object detail</em>).</p>
<p>Larger screens such as those found on tablets and TVs, on the other hand, generally have much more available screen space and are able to present multiple panes of content. In landscape, panes are usually ordered from left to right in increasing detail order. Users are especially accustomed to multiple panes on larger screens from years and years of desktop application and desktop web site use. Many desktop applications and websites offer a left-hand navigation pane or use a master/detail two-pane layout.</p>
@@ -76,12 +83,12 @@ next.link=descendant-lateral.html
<li><strong>Expand/collapse</strong>
<img src="{@docRoot}images/training/app-navigation-multiple-sizes-strategy-collapse.png"
alt="Expand/collapse strategy">
- <p>A variation on the stretch strategy is to collapse the contents of the left pane when in portrait. This works quite well with master/detail panes where the left (master) pane contains easily collapsible list items. An example would be for a realtime chat application. In landscape, the left list could contain chat contact photos, names, and online statuses. In portrait, horizontal space could be collapsed by hiding contact names and only showing photos and online status indicator icons.</p></li>
+ <p>A variation on the stretch strategy is to collapse the contents of the left pane when in portrait. This works quite well with master/detail panes where the left (master) pane contains easily collapsible list items. An example would be for a realtime chat application. In landscape, the left list could contain chat contact photos, names, and online statuses. In portrait, horizontal space could be collapsed by hiding contact names and only showing photos and online status indicator icons. Optionally also provide an expand control that allows the user to expand the left pane content to its larger width and vice versa.</p></li>
<li><strong>Show/Hide</strong>
<img src="{@docRoot}images/training/app-navigation-multiple-sizes-strategy-show-hide.png"
alt="Show/Hide strategy">
- <p>In this scenario, the left pane is completely hidden in portrait mode. However, <em>to ensure the functional parity</em> of your screen in portrait and landscape, the left pane should be made available via an onscreen affordance (such as a button). It's usually appropriate to use the <em>Up</em> button in the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> to show the left pane, as is discussed in a <a href="ancestral-temporal.html">later lesson</a>.</p></li>
+ <p>In this scenario, the left pane is completely hidden in portrait mode. However, <em>to ensure the functional parity</em> of your screen in portrait and landscape, the left pane should be made available via an onscreen affordance (such as a button). It's usually appropriate to use the <em>Up</em> button in the Action Bar (<a href="{@docRoot}design/patterns/actionbar.html">pattern docs</a> at Android Design) to show the left pane, as is discussed in a <a href="ancestral-temporal.html">later lesson</a>.</p></li>
<li><strong>Stack</strong>
<img src="{@docRoot}images/training/app-navigation-multiple-sizes-strategy-stack.png"
diff --git a/docs/html/training/design-navigation/wireframing.jd b/docs/html/training/design-navigation/wireframing.jd
index c7687dd265ff..6deceb1b4653 100644
--- a/docs/html/training/design-navigation/wireframing.jd
+++ b/docs/html/training/design-navigation/wireframing.jd
@@ -121,5 +121,5 @@ previous.link=ancestral-temporal.html
<li><a href="{@docRoot}guide/topics/ui/index.html">Developer's Guide: User Interface</a>: learn how to implement your user interface designs using the Android SDK.</li>
<li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a>: implement tabs, up navigation, on-screen actions, etc.
<li><a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a>: implement re-usable, multi-pane layouts
- <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a>: implement horizontal paging using <code>ViewPager</code></li>
+ <li><a href="{@docRoot}sdk/compatibility-library.html">Support Library</a>: implement horizontal paging (swipe views) using <code>ViewPager</code></li>
</ul>
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 82ed1992bac3..96a71e390713 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -28,8 +28,8 @@ public class LinearGradient extends Shader {
the the colors are distributed evenly along the gradient line.
@param tile The Shader tiling mode
*/
- public LinearGradient(float x0, float y0, float x1, float y1,
- int colors[], float positions[], TileMode tile) {
+ public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
+ TileMode tile) {
if (colors.length < 2) {
throw new IllegalArgumentException("needs >= 2 number of colors");
}
@@ -50,8 +50,8 @@ public class LinearGradient extends Shader {
@param color1 The color at the end of the gradient line.
@param tile The Shader tiling mode
*/
- public LinearGradient(float x0, float y0, float x1, float y1,
- int color0, int color1, TileMode tile) {
+ public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
+ TileMode tile) {
native_instance = nativeCreate2(x0, y0, x1, y1, color0, color1, tile.nativeInt);
native_shader = nativePostCreate2(native_instance, x0, y0, x1, y1, color0, color1,
tile.nativeInt);
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 78302244e1c1..0ada1fbdcd8d 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -76,13 +76,21 @@ public final class Rect implements Parcelable {
}
@Override
- public boolean equals(Object obj) {
- Rect r = (Rect) obj;
- if (r != null) {
- return left == r.left && top == r.top && right == r.right
- && bottom == r.bottom;
- }
- return false;
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Rect r = (Rect) o;
+ return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = left;
+ result = 31 * result + top;
+ result = 31 * result + right;
+ result = 31 * result + bottom;
+ return result;
}
@Override
diff --git a/graphics/java/android/graphics/RectF.java b/graphics/java/android/graphics/RectF.java
index 00e9609a71bf..293dfccb4b5d 100644
--- a/graphics/java/android/graphics/RectF.java
+++ b/graphics/java/android/graphics/RectF.java
@@ -79,6 +79,24 @@ public class RectF implements Parcelable {
bottom = r.bottom;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Rect r = (Rect) o;
+ return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (left != +0.0f ? Float.floatToIntBits(left) : 0);
+ result = 31 * result + (top != +0.0f ? Float.floatToIntBits(top) : 0);
+ result = 31 * result + (right != +0.0f ? Float.floatToIntBits(right) : 0);
+ result = 31 * result + (bottom != +0.0f ? Float.floatToIntBits(bottom) : 0);
+ return result;
+ }
+
public String toString() {
return "RectF(" + left + ", " + top + ", "
+ right + ", " + bottom + ")";
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 50964d5e5546..5b50bebd64ac 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -173,9 +173,20 @@ public class GradientDrawable extends Drawable {
}
/**
- * Specify radii for each of the 4 corners. For each corner, the array
- * contains 2 values, [X_radius, Y_radius]. The corners are ordered
- * top-left, top-right, bottom-right, bottom-left
+ * <p>Specify radii for each of the 4 corners. For each corner, the array
+ * contains 2 values, <code>[X_radius, Y_radius]</code>. The corners are ordered
+ * top-left, top-right, bottom-right, bottom-left. This property
+ * is honored only when the shape is of type {@link #RECTANGLE}.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param radii 4 pairs of X and Y radius for each corner, specified in pixels.
+ * The length of this array must be >= 8
+ *
+ * @see #mutate()
+ * @see #setCornerRadii(float[])
+ * @see #setShape(int)
*/
public void setCornerRadii(float[] radii) {
mGradientState.setCornerRadii(radii);
@@ -184,23 +195,57 @@ public class GradientDrawable extends Drawable {
}
/**
- * Specify radius for the corners of the gradient. If this is > 0, then the
- * drawable is drawn in a round-rectangle, rather than a rectangle.
+ * <p>Specify radius for the corners of the gradient. If this is > 0, then the
+ * drawable is drawn in a round-rectangle, rather than a rectangle. This property
+ * is honored only when the shape is of type {@link #RECTANGLE}.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param radius The radius in pixels of the corners of the rectangle shape
+ *
+ * @see #mutate()
+ * @see #setCornerRadii(float[])
+ * @see #setShape(int)
*/
public void setCornerRadius(float radius) {
mGradientState.setCornerRadius(radius);
mPathIsDirty = true;
invalidateSelf();
}
-
+
/**
- * Set the stroke width and color for the drawable. If width is zero,
- * then no stroke is drawn.
+ * <p>Set the stroke width and color for the drawable. If width is zero,
+ * then no stroke is drawn.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param width The width in pixels of the stroke
+ * @param color The color of the stroke
+ *
+ * @see #mutate()
+ * @see #setStroke(int, int, float, float)
*/
public void setStroke(int width, int color) {
setStroke(width, color, 0, 0);
}
-
+
+ /**
+ * <p>Set the stroke width and color for the drawable. If width is zero,
+ * then no stroke is drawn. This method can also be used to dash the stroke.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param width The width in pixels of the stroke
+ * @param color The color of the stroke
+ * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
+ * @param dashGap The gap in pixels between dashes
+ *
+ * @see #mutate()
+ * @see #setStroke(int, int)
+ */
public void setStroke(int width, int color, float dashWidth, float dashGap) {
mGradientState.setStroke(width, color, dashWidth, dashGap);
@@ -218,13 +263,37 @@ public class GradientDrawable extends Drawable {
mStrokePaint.setPathEffect(e);
invalidateSelf();
}
-
+
+
+ /**
+ * <p>Sets the size of the shape drawn by this drawable.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param width The width of the shape used by this drawable
+ * @param height The height of the shape used by this drawable
+ *
+ * @see #mutate()
+ * @see #setGradientType(int)
+ */
public void setSize(int width, int height) {
mGradientState.setSize(width, height);
mPathIsDirty = true;
invalidateSelf();
}
-
+
+ /**
+ * <p>Sets the type of shape used to draw the gradient.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param shape The desired shape for this drawable: {@link #LINE},
+ * {@link #OVAL}, {@link #RECTANGLE} or {@link #RING}
+ *
+ * @see #mutate()
+ */
public void setShape(int shape) {
mRingPath = null;
mPathIsDirty = true;
@@ -232,24 +301,73 @@ public class GradientDrawable extends Drawable {
invalidateSelf();
}
+ /**
+ * <p>Sets the type of gradient used by this drawable..</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param gradient The type of the gradient: {@link #LINEAR_GRADIENT},
+ * {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT}
+ *
+ * @see #mutate()
+ */
public void setGradientType(int gradient) {
mGradientState.setGradientType(gradient);
mRectIsDirty = true;
invalidateSelf();
}
+ /**
+ * <p>Sets the center location of the gradient. The radius is honored only when
+ * the gradient type is set to {@link #RADIAL_GRADIENT} or {@link #SWEEP_GRADIENT}.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param x The x coordinate of the gradient's center
+ * @param y The y coordinate of the gradient's center
+ *
+ * @see #mutate()
+ * @see #setGradientType(int)
+ */
public void setGradientCenter(float x, float y) {
mGradientState.setGradientCenter(x, y);
mRectIsDirty = true;
invalidateSelf();
}
+ /**
+ * <p>Sets the radius of the gradient. The radius is honored only when the
+ * gradient type is set to {@link #RADIAL_GRADIENT}.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param gradientRadius The radius of the gradient in pixels
+ *
+ * @see #mutate()
+ * @see #setGradientType(int)
+ */
public void setGradientRadius(float gradientRadius) {
mGradientState.setGradientRadius(gradientRadius);
mRectIsDirty = true;
invalidateSelf();
}
+ /**
+ * <p>Sets whether or not this drawable will honor its <code>level</code>
+ * property.</p>
+ * <p><strong>Note</strong>: changing this property will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing this property.</p>
+ *
+ * @param useLevel True if this drawable should honor its level, false otherwise
+ *
+ * @see #mutate()
+ * @see #setLevel(int)
+ * @see #getLevel()
+ */
public void setUseLevel(boolean useLevel) {
mGradientState.mUseLevel = useLevel;
mRectIsDirty = true;
@@ -261,6 +379,47 @@ public class GradientDrawable extends Drawable {
return alpha * scale >> 8;
}
+ /**
+ * Returns the orientation of the gradient defined in this drawable.
+ */
+ public Orientation getOrientation() {
+ return mGradientState.mOrientation;
+ }
+
+ /**
+ * <p>Changes the orientation of the gradient defined in this drawable.</p>
+ * <p><strong>Note</strong>: changing orientation will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing the orientation.</p>
+ *
+ * @param orientation The desired orientation (angle) of the gradient
+ *
+ * @see #mutate()
+ */
+ public void setOrientation(Orientation orientation) {
+ mGradientState.mOrientation = orientation;
+ mRectIsDirty = true;
+ invalidateSelf();
+ }
+
+ /**
+ * <p>Sets the colors used to draw the gradient. Each color is specified as an
+ * ARGB integer and the array must contain at least 2 colors.</p>
+ * <p><strong>Note</strong>: changing orientation will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing the orientation.</p>
+ *
+ * @param colors 2 or more ARGB colors
+ *
+ * @see #mutate()
+ * @see #setColor(int)
+ */
+ public void setColors(int[] colors) {
+ mGradientState.setColors(colors);
+ mRectIsDirty = true;
+ invalidateSelf();
+ }
+
@Override
public void draw(Canvas canvas) {
if (!ensureValidRect()) {
@@ -442,6 +601,17 @@ public class GradientDrawable extends Drawable {
return ringPath;
}
+ /**
+ * <p>Changes this drawbale to use a single color instead of a gradient.</p>
+ * <p><strong>Note</strong>: changing orientation will affect all instances
+ * of a drawable loaded from a resource. It is recommended to invoke
+ * {@link #mutate()} before changing the orientation.</p>
+ *
+ * @param argb The color used to fill the shape
+ *
+ * @see #mutate()
+ * @see #setColors(int[])
+ */
public void setColor(int argb) {
mGradientState.setSolidColor(argb);
mFillPaint.setColor(argb);
@@ -450,10 +620,9 @@ public class GradientDrawable extends Drawable {
@Override
public int getChangingConfigurations() {
- return super.getChangingConfigurations()
- | mGradientState.mChangingConfigurations;
+ return super.getChangingConfigurations() | mGradientState.mChangingConfigurations;
}
-
+
@Override
public void setAlpha(int alpha) {
if (alpha != mAlpha) {
@@ -480,7 +649,6 @@ public class GradientDrawable extends Drawable {
@Override
public int getOpacity() {
- // XXX need to figure out the actual opacity...
return PixelFormat.TRANSLUCENT;
}
@@ -911,11 +1079,6 @@ public class GradientDrawable extends Drawable {
private float mGradientRadius = 0.5f;
private boolean mUseLevel;
private boolean mUseLevelForShape;
-
-
- GradientState() {
- mOrientation = Orientation.TOP_BOTTOM;
- }
GradientState(Orientation orientation, int[] colors) {
mOrientation = orientation;
@@ -987,6 +1150,11 @@ public class GradientDrawable extends Drawable {
mCenterY = y;
}
+ public void setColors(int[] colors) {
+ mHasSolidColor = false;
+ mColors = colors;
+ }
+
public void setSolidColor(int argb) {
mHasSolidColor = true;
mSolidColor = argb;
@@ -1055,4 +1223,3 @@ public class GradientDrawable extends Drawable {
}
}
}
-
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index bc1db4dc3310..07bf7bf62f82 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -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.
@@ -567,7 +567,7 @@ nAllocationElementData1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc,
jint len = _env->GetArrayLength(data);
LOG_API("nAllocationElementData1D, con(%p), alloc(%p), offset(%i), comp(%i), len(%i), sizeBytes(%i)", con, (RsAllocation)alloc, offset, compIdx, len, sizeBytes);
jbyte *ptr = _env->GetByteArrayElements(data, NULL);
- rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, compIdx, sizeBytes);
+ rsAllocation1DElementData(con, (RsAllocation)alloc, offset, lod, ptr, sizeBytes, compIdx);
_env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
}
diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h
index dccc1643c93a..a28137785e9a 100644
--- a/include/gui/DisplayEventReceiver.h
+++ b/include/gui/DisplayEventReceiver.h
@@ -63,7 +63,9 @@ public:
public:
/*
* DisplayEventReceiver creates and registers an event connection with
- * SurfaceFlinger. Events start being delivered immediately.
+ * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate
+ * or requestNextVsync to receive them.
+ * Other events start being delivered immediately.
*/
DisplayEventReceiver();
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 756e91db2a65..76ec3b1190eb 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -149,7 +149,7 @@ public:
RECORD_IIR_ENABLE = AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE,
};
- AudioRecord(int inputSource,
+ AudioRecord(audio_source_t inputSource,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
@@ -175,7 +175,7 @@ public:
* - NO_INIT: audio server or audio hardware not initialized
* - PERMISSION_DENIED: recording is not allowed for the requesting process
* */
- status_t set(int inputSource = 0,
+ status_t set(audio_source_t inputSource = AUDIO_SOURCE_DEFAULT,
uint32_t sampleRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channelMask = AUDIO_CHANNEL_IN_MONO,
@@ -208,7 +208,7 @@ public:
int channels() const;
uint32_t frameCount() const;
size_t frameSize() const;
- int inputSource() const;
+ audio_source_t inputSource() const;
/* After it's created the track is not active. Call start() to
@@ -367,8 +367,7 @@ private:
audio_track_cblk_t* mCblk;
audio_format_t mFormat;
uint8_t mChannelCount;
- uint8_t mInputSource;
- uint8_t mReserved[2];
+ audio_source_t mInputSource;
status_t mStatus;
uint32_t mLatency;
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index c6368fb22833..6b12c1451ca6 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -163,7 +163,7 @@ public:
audio_stream_type_t stream,
int session = 0);
static void releaseOutput(audio_io_handle_t output);
- static audio_io_handle_t getInput(int inputSource,
+ static audio_io_handle_t getInput(audio_source_t inputSource,
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = AUDIO_CHANNEL_IN_MONO,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 07d17c5b0767..4d88297eaf8a 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -60,7 +60,7 @@ public:
audio_stream_type_t stream,
int session = 0) = 0;
virtual void releaseOutput(audio_io_handle_t output) = 0;
- virtual audio_io_handle_t getInput(int inputSource,
+ virtual audio_io_handle_t getInput(audio_source_t inputSource,
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index c4cc947a8902..a295e9a19281 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -42,10 +42,10 @@ public:
typedef void *buffer_id;
typedef void *node_id;
- // Given the calling process' pid, returns true iff
+ // Given a node_id and the calling process' pid, returns true iff
// the implementation of the OMX interface lives in the same
// process.
- virtual bool livesLocally(pid_t pid) = 0;
+ virtual bool livesLocally(node_id node, pid_t pid) = 0;
struct ComponentInfo {
String8 mName;
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 19bd31b7e594..2427e2fe9967 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -34,7 +34,7 @@ struct AudioSource : public MediaSource, public MediaBufferObserver {
// Note that the "channels" parameter is _not_ the number of channels,
// but a bitmask of audio_channels_t constants.
AudioSource(
- int inputSource, uint32_t sampleRate,
+ audio_source_t inputSource, uint32_t sampleRate,
uint32_t channels = AUDIO_CHANNEL_IN_MONO);
status_t initCheck() const;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 84f8282f64b7..4c30e0437bc7 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -172,6 +172,7 @@ private:
uint32_t mFlags;
bool mIsEncoder;
+ bool mIsVideo;
char *mMIME;
char *mComponentName;
sp<MetaData> mOutputFormat;
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 46420c1316bf..c496da6bac56 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -444,23 +444,31 @@ public:
void uninit();
+ // Return string entry as UTF16; if the pool is UTF8, the string will
+ // be converted before returning.
inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
return stringAt(ref.index, outLen);
}
const char16_t* stringAt(size_t idx, size_t* outLen) const;
+ // Note: returns null if the string pool is not UTF8.
const char* string8At(size_t idx, size_t* outLen) const;
+ // Return string whether the pool is UTF8 or UTF16. Does not allow you
+ // to distinguish null.
+ const String8 string8ObjectAt(size_t idx) const;
+
const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
const ResStringPool_span* styleAt(size_t idx) const;
ssize_t indexOfString(const char16_t* str, size_t strLen) const;
size_t size() const;
+ size_t styleCount() const;
+ size_t bytes() const;
-#ifndef HAVE_ANDROID_OS
+ bool isSorted() const;
bool isUTF8() const;
-#endif
private:
status_t mError;
@@ -746,7 +754,9 @@ private:
/**
* Header for a resource table. Its data contains a series of
* additional chunks:
- * * A ResStringPool_header containing all table values.
+ * * A ResStringPool_header containing all table values. This string pool
+ * contains all of the string values in the entire resource table (not
+ * the names of entries or type identifiers however).
* * One or more ResTable_package chunks.
*
* Specific entries within a resource table can be uniquely identified
@@ -843,6 +853,8 @@ struct ResTable_config
DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
DENSITY_TV = ACONFIGURATION_DENSITY_TV,
DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
+ DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,
+ DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH,
DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
};
@@ -982,68 +994,15 @@ struct ResTable_config
uint32_t screenSizeDp;
};
- inline void copyFromDeviceNoSwap(const ResTable_config& o) {
- const size_t size = dtohl(o.size);
- if (size >= sizeof(ResTable_config)) {
- *this = o;
- } else {
- memcpy(this, &o, size);
- memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
- }
- }
+ void copyFromDeviceNoSwap(const ResTable_config& o);
- inline void copyFromDtoH(const ResTable_config& o) {
- copyFromDeviceNoSwap(o);
- size = sizeof(ResTable_config);
- mcc = dtohs(mcc);
- mnc = dtohs(mnc);
- density = dtohs(density);
- screenWidth = dtohs(screenWidth);
- screenHeight = dtohs(screenHeight);
- sdkVersion = dtohs(sdkVersion);
- minorVersion = dtohs(minorVersion);
- smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
- screenWidthDp = dtohs(screenWidthDp);
- screenHeightDp = dtohs(screenHeightDp);
- }
-
- inline void swapHtoD() {
- size = htodl(size);
- mcc = htods(mcc);
- mnc = htods(mnc);
- density = htods(density);
- screenWidth = htods(screenWidth);
- screenHeight = htods(screenHeight);
- sdkVersion = htods(sdkVersion);
- minorVersion = htods(minorVersion);
- smallestScreenWidthDp = htods(smallestScreenWidthDp);
- screenWidthDp = htods(screenWidthDp);
- screenHeightDp = htods(screenHeightDp);
- }
-
- inline int compare(const ResTable_config& o) const {
- int32_t diff = (int32_t)(imsi - o.imsi);
- if (diff != 0) return diff;
- diff = (int32_t)(locale - o.locale);
- if (diff != 0) return diff;
- diff = (int32_t)(screenType - o.screenType);
- if (diff != 0) return diff;
- diff = (int32_t)(input - o.input);
- if (diff != 0) return diff;
- diff = (int32_t)(screenSize - o.screenSize);
- if (diff != 0) return diff;
- diff = (int32_t)(version - o.version);
- if (diff != 0) return diff;
- diff = (int32_t)(screenLayout - o.screenLayout);
- if (diff != 0) return diff;
- diff = (int32_t)(uiMode - o.uiMode);
- if (diff != 0) return diff;
- diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
- if (diff != 0) return diff;
- diff = (int32_t)(screenSizeDp - o.screenSizeDp);
- return (int)diff;
- }
+ void copyFromDtoH(const ResTable_config& o);
+ void swapHtoD();
+
+ int compare(const ResTable_config& o) const;
+ int compareLogical(const ResTable_config& o) const;
+
// Flags indicating a set of config values. These flag constants must
// match the corresponding ones in android.content.pm.ActivityInfo and
// attrs_manifest.xml.
@@ -1066,158 +1025,10 @@ struct ResTable_config
// Compare two configuration, returning CONFIG_* flags set for each value
// that is different.
- inline int diff(const ResTable_config& o) const {
- int diffs = 0;
- if (mcc != o.mcc) diffs |= CONFIG_MCC;
- if (mnc != o.mnc) diffs |= CONFIG_MNC;
- if (locale != o.locale) diffs |= CONFIG_LOCALE;
- if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
- if (density != o.density) diffs |= CONFIG_DENSITY;
- if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
- if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
- diffs |= CONFIG_KEYBOARD_HIDDEN;
- if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
- if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
- if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
- if (version != o.version) diffs |= CONFIG_VERSION;
- if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
- if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
- if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
- if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
- return diffs;
- }
+ int diff(const ResTable_config& o) const;
// Return true if 'this' is more specific than 'o'.
- inline bool
- isMoreSpecificThan(const ResTable_config& o) const {
- // The order of the following tests defines the importance of one
- // configuration parameter over another. Those tests first are more
- // important, trumping any values in those following them.
- if (imsi || o.imsi) {
- if (mcc != o.mcc) {
- if (!mcc) return false;
- if (!o.mcc) return true;
- }
-
- if (mnc != o.mnc) {
- if (!mnc) return false;
- if (!o.mnc) return true;
- }
- }
-
- if (locale || o.locale) {
- if (language[0] != o.language[0]) {
- if (!language[0]) return false;
- if (!o.language[0]) return true;
- }
-
- if (country[0] != o.country[0]) {
- if (!country[0]) return false;
- if (!o.country[0]) return true;
- }
- }
-
- if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
- if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
- if (!smallestScreenWidthDp) return false;
- if (!o.smallestScreenWidthDp) return true;
- }
- }
-
- if (screenSizeDp || o.screenSizeDp) {
- if (screenWidthDp != o.screenWidthDp) {
- if (!screenWidthDp) return false;
- if (!o.screenWidthDp) return true;
- }
-
- if (screenHeightDp != o.screenHeightDp) {
- if (!screenHeightDp) return false;
- if (!o.screenHeightDp) return true;
- }
- }
-
- if (screenLayout || o.screenLayout) {
- if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
- if (!(screenLayout & MASK_SCREENSIZE)) return false;
- if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
- }
- if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
- if (!(screenLayout & MASK_SCREENLONG)) return false;
- if (!(o.screenLayout & MASK_SCREENLONG)) return true;
- }
- }
-
- if (orientation != o.orientation) {
- if (!orientation) return false;
- if (!o.orientation) return true;
- }
-
- if (uiMode || o.uiMode) {
- if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
- if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
- if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
- }
- if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
- if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
- if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
- }
- }
-
- // density is never 'more specific'
- // as the default just equals 160
-
- if (touchscreen != o.touchscreen) {
- if (!touchscreen) return false;
- if (!o.touchscreen) return true;
- }
-
- if (input || o.input) {
- if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
- if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
- if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
- }
-
- if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
- if (!(inputFlags & MASK_NAVHIDDEN)) return false;
- if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
- }
-
- if (keyboard != o.keyboard) {
- if (!keyboard) return false;
- if (!o.keyboard) return true;
- }
-
- if (navigation != o.navigation) {
- if (!navigation) return false;
- if (!o.navigation) return true;
- }
- }
-
- if (screenSize || o.screenSize) {
- if (screenWidth != o.screenWidth) {
- if (!screenWidth) return false;
- if (!o.screenWidth) return true;
- }
-
- if (screenHeight != o.screenHeight) {
- if (!screenHeight) return false;
- if (!o.screenHeight) return true;
- }
- }
-
- if (version || o.version) {
- if (sdkVersion != o.sdkVersion) {
- if (!sdkVersion) return false;
- if (!o.sdkVersion) return true;
- }
-
- if (minorVersion != o.minorVersion) {
- if (!minorVersion) return false;
- if (!o.minorVersion) return true;
- }
- }
- return false;
- }
+ bool isMoreSpecificThan(const ResTable_config& o) const;
// Return true if 'this' is a better match than 'o' for the 'requested'
// configuration. This assumes that match() has already been used to
@@ -1229,222 +1040,7 @@ struct ResTable_config
// they are not equal then one must be generic because only generic and
// '==requested' will pass the match() call. So if this is not generic,
// it wins. If this IS generic, o wins (return false).
- inline bool
- isBetterThan(const ResTable_config& o,
- const ResTable_config* requested) const {
- if (requested) {
- if (imsi || o.imsi) {
- if ((mcc != o.mcc) && requested->mcc) {
- return (mcc);
- }
-
- if ((mnc != o.mnc) && requested->mnc) {
- return (mnc);
- }
- }
-
- if (locale || o.locale) {
- if ((language[0] != o.language[0]) && requested->language[0]) {
- return (language[0]);
- }
-
- if ((country[0] != o.country[0]) && requested->country[0]) {
- return (country[0]);
- }
- }
-
- if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
- // The configuration closest to the actual size is best.
- // We assume that larger configs have already been filtered
- // out at this point. That means we just want the largest one.
- return smallestScreenWidthDp >= o.smallestScreenWidthDp;
- }
-
- if (screenSizeDp || o.screenSizeDp) {
- // "Better" is based on the sum of the difference between both
- // width and height from the requested dimensions. We are
- // assuming the invalid configs (with smaller dimens) have
- // already been filtered. Note that if a particular dimension
- // is unspecified, we will end up with a large value (the
- // difference between 0 and the requested dimension), which is
- // good since we will prefer a config that has specified a
- // dimension value.
- int myDelta = 0, otherDelta = 0;
- if (requested->screenWidthDp) {
- myDelta += requested->screenWidthDp - screenWidthDp;
- otherDelta += requested->screenWidthDp - o.screenWidthDp;
- }
- if (requested->screenHeightDp) {
- myDelta += requested->screenHeightDp - screenHeightDp;
- otherDelta += requested->screenHeightDp - o.screenHeightDp;
- }
- //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
- // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
- // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
- return (myDelta <= otherDelta);
- }
-
- if (screenLayout || o.screenLayout) {
- if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
- && (requested->screenLayout & MASK_SCREENSIZE)) {
- // A little backwards compatibility here: undefined is
- // considered equivalent to normal. But only if the
- // requested size is at least normal; otherwise, small
- // is better than the default.
- int mySL = (screenLayout & MASK_SCREENSIZE);
- int oSL = (o.screenLayout & MASK_SCREENSIZE);
- int fixedMySL = mySL;
- int fixedOSL = oSL;
- if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
- if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
- if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
- }
- // For screen size, the best match is the one that is
- // closest to the requested screen size, but not over
- // (the not over part is dealt with in match() below).
- if (fixedMySL == fixedOSL) {
- // If the two are the same, but 'this' is actually
- // undefined, then the other is really a better match.
- if (mySL == 0) return false;
- return true;
- }
- return fixedMySL >= fixedOSL;
- }
- if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
- && (requested->screenLayout & MASK_SCREENLONG)) {
- return (screenLayout & MASK_SCREENLONG);
- }
- }
-
- if ((orientation != o.orientation) && requested->orientation) {
- return (orientation);
- }
-
- if (uiMode || o.uiMode) {
- if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
- && (requested->uiMode & MASK_UI_MODE_TYPE)) {
- return (uiMode & MASK_UI_MODE_TYPE);
- }
- if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
- && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
- return (uiMode & MASK_UI_MODE_NIGHT);
- }
- }
-
- if (screenType || o.screenType) {
- if (density != o.density) {
- // density is tough. Any density is potentially useful
- // because the system will scale it. Scaling down
- // is generally better than scaling up.
- // Default density counts as 160dpi (the system default)
- // TODO - remove 160 constants
- int h = (density?density:160);
- int l = (o.density?o.density:160);
- bool bImBigger = true;
- if (l > h) {
- int t = h;
- h = l;
- l = t;
- bImBigger = false;
- }
-
- int reqValue = (requested->density?requested->density:160);
- if (reqValue >= h) {
- // requested value higher than both l and h, give h
- return bImBigger;
- }
- if (l >= reqValue) {
- // requested value lower than both l and h, give l
- return !bImBigger;
- }
- // saying that scaling down is 2x better than up
- if (((2 * l) - reqValue) * h > reqValue * reqValue) {
- return !bImBigger;
- } else {
- return bImBigger;
- }
- }
-
- if ((touchscreen != o.touchscreen) && requested->touchscreen) {
- return (touchscreen);
- }
- }
-
- if (input || o.input) {
- const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
- const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
- if (keysHidden != oKeysHidden) {
- const int reqKeysHidden =
- requested->inputFlags & MASK_KEYSHIDDEN;
- if (reqKeysHidden) {
-
- if (!keysHidden) return false;
- if (!oKeysHidden) return true;
- // For compatibility, we count KEYSHIDDEN_NO as being
- // the same as KEYSHIDDEN_SOFT. Here we disambiguate
- // these by making an exact match more specific.
- if (reqKeysHidden == keysHidden) return true;
- if (reqKeysHidden == oKeysHidden) return false;
- }
- }
-
- const int navHidden = inputFlags & MASK_NAVHIDDEN;
- const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
- if (navHidden != oNavHidden) {
- const int reqNavHidden =
- requested->inputFlags & MASK_NAVHIDDEN;
- if (reqNavHidden) {
-
- if (!navHidden) return false;
- if (!oNavHidden) return true;
- }
- }
-
- if ((keyboard != o.keyboard) && requested->keyboard) {
- return (keyboard);
- }
-
- if ((navigation != o.navigation) && requested->navigation) {
- return (navigation);
- }
- }
-
- if (screenSize || o.screenSize) {
- // "Better" is based on the sum of the difference between both
- // width and height from the requested dimensions. We are
- // assuming the invalid configs (with smaller sizes) have
- // already been filtered. Note that if a particular dimension
- // is unspecified, we will end up with a large value (the
- // difference between 0 and the requested dimension), which is
- // good since we will prefer a config that has specified a
- // size value.
- int myDelta = 0, otherDelta = 0;
- if (requested->screenWidth) {
- myDelta += requested->screenWidth - screenWidth;
- otherDelta += requested->screenWidth - o.screenWidth;
- }
- if (requested->screenHeight) {
- myDelta += requested->screenHeight - screenHeight;
- otherDelta += requested->screenHeight - o.screenHeight;
- }
- return (myDelta <= otherDelta);
- }
-
- if (version || o.version) {
- if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
- return (sdkVersion > o.sdkVersion);
- }
-
- if ((minorVersion != o.minorVersion) &&
- requested->minorVersion) {
- return (minorVersion);
- }
- }
-
- return false;
- }
- return isMoreSpecificThan(o);
- }
+ bool isBetterThan(const ResTable_config& o, const ResTable_config* requested) const;
// Return true if 'this' can be considered a match for the parameters in
// 'settings'.
@@ -1452,150 +1048,11 @@ struct ResTable_config
// but a request for the default should not match odd specifics
// (ie, request with no mcc should not match a particular mcc's data)
// settings is the requested settings
- inline bool match(const ResTable_config& settings) const {
- if (imsi != 0) {
- if (mcc != 0 && mcc != settings.mcc) {
- return false;
- }
- if (mnc != 0 && mnc != settings.mnc) {
- return false;
- }
- }
- if (locale != 0) {
- if (language[0] != 0
- && (language[0] != settings.language[0]
- || language[1] != settings.language[1])) {
- return false;
- }
- if (country[0] != 0
- && (country[0] != settings.country[0]
- || country[1] != settings.country[1])) {
- return false;
- }
- }
- if (screenConfig != 0) {
- const int screenSize = screenLayout&MASK_SCREENSIZE;
- const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
- // Any screen sizes for larger screens than the setting do not
- // match.
- if (screenSize != 0 && screenSize > setScreenSize) {
- return false;
- }
-
- const int screenLong = screenLayout&MASK_SCREENLONG;
- const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
- if (screenLong != 0 && screenLong != setScreenLong) {
- return false;
- }
-
- const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
- const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
- if (uiModeType != 0 && uiModeType != setUiModeType) {
- return false;
- }
-
- const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
- const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
- if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
- return false;
- }
-
- if (smallestScreenWidthDp != 0
- && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
- return false;
- }
- }
- if (screenSizeDp != 0) {
- if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
- //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
- return false;
- }
- if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
- //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
- return false;
- }
- }
- if (screenType != 0) {
- if (orientation != 0 && orientation != settings.orientation) {
- return false;
- }
- // density always matches - we can scale it. See isBetterThan
- if (touchscreen != 0 && touchscreen != settings.touchscreen) {
- return false;
- }
- }
- if (input != 0) {
- const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
- const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
- if (keysHidden != 0 && keysHidden != setKeysHidden) {
- // For compatibility, we count a request for KEYSHIDDEN_NO as also
- // matching the more recent KEYSHIDDEN_SOFT. Basically
- // KEYSHIDDEN_NO means there is some kind of keyboard available.
- //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
- if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
- //ALOGI("No match!");
- return false;
- }
- }
- const int navHidden = inputFlags&MASK_NAVHIDDEN;
- const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
- if (navHidden != 0 && navHidden != setNavHidden) {
- return false;
- }
- if (keyboard != 0 && keyboard != settings.keyboard) {
- return false;
- }
- if (navigation != 0 && navigation != settings.navigation) {
- return false;
- }
- }
- if (screenSize != 0) {
- if (screenWidth != 0 && screenWidth > settings.screenWidth) {
- return false;
- }
- if (screenHeight != 0 && screenHeight > settings.screenHeight) {
- return false;
- }
- }
- if (version != 0) {
- if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {
- return false;
- }
- if (minorVersion != 0 && minorVersion != settings.minorVersion) {
- return false;
- }
- }
- return true;
- }
+ bool match(const ResTable_config& settings) const;
- void getLocale(char str[6]) const {
- memset(str, 0, 6);
- if (language[0]) {
- str[0] = language[0];
- str[1] = language[1];
- if (country[0]) {
- str[2] = '_';
- str[3] = country[0];
- str[4] = country[1];
- }
- }
- }
+ void getLocale(char str[6]) const;
- String8 toString() const {
- char buf[200];
- sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d "
- "kbd=%d nav=%d input=%d ssz=%dx%d sw%ddp w%ddp h%ddp sz=%d long=%d "
- "ui=%d night=%d vers=%d.%d",
- mcc, mnc,
- language[0] ? language[0] : '-', language[1] ? language[1] : '-',
- country[0] ? country[0] : '-', country[1] ? country[1] : '-',
- orientation, touchscreen, density, keyboard, navigation, inputFlags,
- screenWidth, screenHeight, smallestScreenWidthDp, screenWidthDp, screenHeightDp,
- screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
- uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT,
- sdkVersion, minorVersion);
- return String8(buf);
- }
+ String8 toString() const;
};
/**
@@ -2054,8 +1511,14 @@ public:
const char16_t* getBasePackageName(size_t idx) const;
uint32_t getBasePackageId(size_t idx) const;
+ // Return the number of resource tables that the object contains.
size_t getTableCount() const;
+ // Return the values string pool for the resource table at the given
+ // index. This string pool contains all of the strings for values
+ // contained in the resource table -- that is the item values themselves,
+ // but not the names their entries or types.
const ResStringPool* getTableStringBlock(size_t index) const;
+ // Return unique cookie identifier for the given resource table.
void* getTableCookie(size_t index) const;
// Return the configurations (ResTable_config) that we know about
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index b8be67d446ce..b6f5b9e8e855 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -34,6 +34,13 @@ LOCAL_SHARED_LIBRARIES := \
LOCAL_MODULE:= libgui
+ifeq ($(TARGET_BOARD_PLATFORM), omap4)
+ LOCAL_CFLAGS += -DUSE_FENCE_SYNC
+endif
+ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
+ LOCAL_CFLAGS += -DUSE_FENCE_SYNC
+endif
+
ifeq ($(TARGET_BOARD_PLATFORM), tegra)
LOCAL_CFLAGS += -DALLOW_DEQUEUE_CURRENT_BUFFER
endif
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index d1af1a3161a8..0ef846903343 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -55,6 +55,16 @@ Caches::Caches(): Singleton<Caches>(), mInitialized(false) {
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ if (extensions.hasDebugMarker()) {
+ eventMark = glInsertEventMarkerEXT;
+ startMark = glPushGroupMarkerEXT;
+ endMark = glPopGroupMarkerEXT;
+ } else {
+ eventMark = eventMarkNull;
+ startMark = startMarkNull;
+ endMark = endMarkNull;
+ }
+
init();
mDebugLevel = readDebugLevel();
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 409584fb0e06..f8c7bccad628 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -240,7 +240,15 @@ public:
GammaFontRenderer fontRenderer;
ResourceCache resourceCache;
+ PFNGLINSERTEVENTMARKEREXTPROC eventMark;
+ PFNGLPUSHGROUPMARKEREXTPROC startMark;
+ PFNGLPOPGROUPMARKEREXTPROC endMark;
+
private:
+ static void eventMarkNull(GLsizei length, const GLchar *marker) { }
+ static void startMarkNull(GLsizei length, const GLchar *marker) { }
+ static void endMarkNull() { }
+
GLuint mCurrentBuffer;
GLuint mCurrentIndicesBuffer;
void* mCurrentPositionPointer;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ee935e44381f..1a11fbcfad68 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -19,9 +19,10 @@
#include "DisplayListLogBuffer.h"
#include "DisplayListRenderer.h"
-#include <utils/String8.h>
#include "Caches.h"
+#include <utils/String8.h>
+
namespace android {
namespace uirenderer {
@@ -217,7 +218,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
indent[i] = ' ';
}
indent[count] = '\0';
- ALOGD("%sStart display list (%p)", (char*) indent + 2, this);
+ ALOGD("%sStart display list (%p, %s)", (char*) indent + 2, this, mName.string());
int saveCount = renderer.getSaveCount() - 1;
@@ -562,9 +563,11 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
indent[i] = ' ';
}
indent[count] = '\0';
- DISPLAY_LIST_LOGD("%sStart display list (%p)", (char*) indent + 2, this);
+ DISPLAY_LIST_LOGD("%sStart display list (%p, %s)", (char*) indent + 2, this, mName.string());
#endif
+ renderer.startMark(mName.string());
+
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
int saveCount = renderer.getSaveCount() - 1;
while (!mReader.eof()) {
@@ -575,7 +578,9 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
case DrawGLFunction: {
Functor *functor = (Functor *) getInt();
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
+ renderer.startMark("GL functor");
needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
+ renderer.endMark();
}
break;
case Save: {
@@ -934,6 +939,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
}
}
+ renderer.endMark();
+
DISPLAY_LIST_LOGD("%sDone, returning %d", (char*) indent + 2, needsInvalidate);
return needsInvalidate;
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 6fe4205b7443..46506e4e9a96 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -28,6 +28,8 @@
#include <cutils/compiler.h>
+#include <utils/String8.h>
+
#include "DisplayListLogBuffer.h"
#include "OpenGLRenderer.h"
#include "utils/Functor.h"
@@ -128,6 +130,12 @@ public:
return mIsRenderable;
}
+ void setName(const char* name) {
+ if (name) {
+ mName.setTo(name);
+ }
+ }
+
private:
void init();
@@ -224,6 +232,8 @@ private:
size_t mSize;
bool mIsRenderable;
+
+ String8 mName;
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 1069e3f7fbd0..f11fecc7ae9c 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -67,6 +67,7 @@ public:
mHasNPot = hasExtension("GL_OES_texture_npot");
mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
+ mHasDebugMarker = hasExtension("GL_EXT_debug_marker");
const char* vendor = (const char*) glGetString(GL_VENDOR);
EXT_LOGD("Vendor: %s", vendor);
@@ -82,6 +83,7 @@ public:
inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
+ inline bool hasDebugMarker() const { return mHasDebugMarker; }
bool hasExtension(const char* extension) const {
const String8 s(extension);
@@ -101,6 +103,7 @@ private:
bool mNeedsHighpTexCoords;
bool mHasFramebufferFetch;
bool mHasDiscardFramebuffer;
+ bool mHasDebugMarker;
}; // class Extensions
}; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cc0e05ef914b..bd213d52b453 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -124,9 +124,25 @@ OpenGLRenderer::~OpenGLRenderer() {
}
///////////////////////////////////////////////////////////////////////////////
+// Debug
+///////////////////////////////////////////////////////////////////////////////
+
+void OpenGLRenderer::startMark(const char* name) const {
+ mCaches.startMark(0, name);
+}
+
+void OpenGLRenderer::endMark() const {
+ mCaches.endMark();
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Setup
///////////////////////////////////////////////////////////////////////////////
+uint32_t OpenGLRenderer::getStencilSize() {
+ return STENCIL_BUFFER_SIZE;
+}
+
void OpenGLRenderer::setViewport(int width, int height) {
mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index ae355bba4e9b..3c2d09e81769 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -141,6 +141,11 @@ public:
SkPaint* filterPaint(SkPaint* paint);
+ ANDROID_API static uint32_t getStencilSize();
+
+ void startMark(const char* name) const;
+ void endMark() const;
+
protected:
/**
* Compose the layer defined in the current snapshot with the layer
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 2eae0f18bbb8..71fb8da6e817 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -37,6 +37,11 @@
// Textures used by layers must have dimensions multiples of this number
#define LAYER_SIZE 64
+// Defines the size in bits of the stencil buffer
+// Note: We only want 1 bit, but in practice we'll get 8 bits on all GPUs
+// for the foreseeable future
+#define STENCIL_BUFFER_SIZE 0
+
/**
* Debug level for app developers.
*/
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index b53a68cf9efd..7acc05487f82 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -340,9 +340,9 @@ bool rsdGLInit(const Context *rsc) {
dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
"GL_OES_texture_npot");
- dc->gl.gl.GL_IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
+ dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
"GL_IMG_texture_npot");
- dc->gl.gl.GL_NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
+ dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
"GL_NV_texture_npot_2D_mipmap");
dc->gl.gl.EXT_texture_max_aniso = 1.0f;
bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h
index fc33885d5362..51893c305ec8 100644
--- a/libs/rs/driver/rsdGL.h
+++ b/libs/rs/driver/rsdGL.h
@@ -61,8 +61,8 @@ typedef struct RsdGLRec {
int32_t maxVertexTextureUnits;
bool OES_texture_npot;
- bool GL_IMG_texture_npot;
- bool GL_NV_texture_npot_2D_mipmap;
+ bool IMG_texture_npot;
+ bool NV_texture_npot_2D_mipmap;
float EXT_texture_max_aniso;
} gl;
diff --git a/libs/rs/driver/rsdRuntimeMath.cpp b/libs/rs/driver/rsdRuntimeMath.cpp
index e31553969329..753ef7356ab7 100644
--- a/libs/rs/driver/rsdRuntimeMath.cpp
+++ b/libs/rs/driver/rsdRuntimeMath.cpp
@@ -329,6 +329,16 @@ static int32_t SC_AtomicXor(volatile int32_t *ptr, int32_t value) {
return prev;
}
+static uint32_t SC_AtomicUMin(volatile uint32_t *ptr, uint32_t value) {
+ uint32_t prev, status;
+ do {
+ prev = *ptr;
+ uint32_t n = rsMin(value, prev);
+ status = android_atomic_release_cas((int32_t) prev, (int32_t)n, (volatile int32_t*) ptr);
+ } while (CC_UNLIKELY(status != 0));
+ return prev;
+}
+
static int32_t SC_AtomicMin(volatile int32_t *ptr, int32_t value) {
int32_t prev, status;
do {
@@ -339,6 +349,16 @@ static int32_t SC_AtomicMin(volatile int32_t *ptr, int32_t value) {
return prev;
}
+static uint32_t SC_AtomicUMax(volatile uint32_t *ptr, uint32_t value) {
+ uint32_t prev, status;
+ do {
+ prev = *ptr;
+ uint32_t n = rsMax(value, prev);
+ status = android_atomic_release_cas((int32_t) prev, (int32_t) n, (volatile int32_t*) ptr);
+ } while (CC_UNLIKELY(status != 0));
+ return prev;
+}
+
static int32_t SC_AtomicMax(volatile int32_t *ptr, int32_t value) {
int32_t prev, status;
do {
@@ -524,9 +544,9 @@ static RsdSymbolTable gSyms[] = {
{ "_Z11rsAtomicXorPVii", (void *)&SC_AtomicXor, true },
{ "_Z11rsAtomicXorPVjj", (void *)&SC_AtomicXor, true },
{ "_Z11rsAtomicMinPVii", (void *)&SC_AtomicMin, true },
- { "_Z11rsAtomicMinPVjj", (void *)&SC_AtomicMin, true },
+ { "_Z11rsAtomicMinPVjj", (void *)&SC_AtomicUMin, true },
{ "_Z11rsAtomicMaxPVii", (void *)&SC_AtomicMax, true },
- { "_Z11rsAtomicMaxPVjj", (void *)&SC_AtomicMax, true },
+ { "_Z11rsAtomicMaxPVjj", (void *)&SC_AtomicUMax, true },
{ "_Z11rsAtomicCasPViii", (void *)&SC_AtomicCas, true },
{ "_Z11rsAtomicCasPVjjj", (void *)&SC_AtomicCas, true },
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index a10deb41a734..c70193aead19 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -349,8 +349,8 @@ void RsdShader::setupSampler(const Context *rsc, const Sampler *s, const Allocat
if (!dc->gl.gl.OES_texture_npot && tex->getType()->getIsNp2()) {
if (tex->getHasGraphicsMipmaps() &&
- (dc->gl.gl.GL_NV_texture_npot_2D_mipmap || dc->gl.gl.GL_IMG_texture_npot)) {
- if (dc->gl.gl.GL_NV_texture_npot_2D_mipmap) {
+ (dc->gl.gl.NV_texture_npot_2D_mipmap || dc->gl.gl.IMG_texture_npot)) {
+ if (dc->gl.gl.NV_texture_npot_2D_mipmap) {
RSD_CALL_GL(glTexParameteri, target, GL_TEXTURE_MIN_FILTER,
trans[s->mHal.state.minFilter]);
} else {
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 20b1f52104da..6887b22095e1 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -162,7 +162,7 @@ Allocation1DElementData {
param uint32_t x
param uint32_t lod
param const void *data
- param uint32_t comp_offset
+ param size_t comp_offset
}
Allocation2DData {
@@ -183,7 +183,7 @@ Allocation2DElementData {
param uint32_t lod
param RsAllocationCubemapFace face
param const void *data
- param uint32_t element_offset
+ param size_t element_offset
}
AllocationGenerateMipmaps {
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 2773d5c661c5..972e3d655115 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.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.
@@ -71,11 +71,11 @@ void Allocation::read(void *data) {
}
void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
- uint32_t count, const void *data, uint32_t sizeBytes) {
- const uint32_t eSize = mHal.state.type->getElementSizeBytes();
+ uint32_t count, const void *data, size_t sizeBytes) {
+ const size_t eSize = mHal.state.type->getElementSizeBytes();
if ((count * eSize) != sizeBytes) {
- ALOGE("Allocation::subData called with mismatched size expected %i, got %i",
+ ALOGE("Allocation::subData called with mismatched size expected %zu, got %zu",
(count * eSize), sizeBytes);
mHal.state.type->dumpLOGV("type info");
return;
@@ -86,14 +86,14 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
}
void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
- uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
- const uint32_t eSize = mHal.state.elementSizeBytes;
- const uint32_t lineSize = eSize * w;
+ uint32_t w, uint32_t h, const void *data, size_t sizeBytes) {
+ const size_t eSize = mHal.state.elementSizeBytes;
+ const size_t lineSize = eSize * w;
//ALOGE("data2d %p, %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
if ((lineSize * h) != sizeBytes) {
- ALOGE("Allocation size mismatch, expected %i, got %i", (lineSize * h), sizeBytes);
+ ALOGE("Allocation size mismatch, expected %zu, got %zu", (lineSize * h), sizeBytes);
rsAssert(!"Allocation::subData called with mismatched size");
return;
}
@@ -104,12 +104,12 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod,
void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
uint32_t lod, RsAllocationCubemapFace face,
- uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
+ uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes) {
}
void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
- uint32_t cIdx, uint32_t sizeBytes) {
- uint32_t eSize = mHal.state.elementSizeBytes;
+ uint32_t cIdx, size_t sizeBytes) {
+ size_t eSize = mHal.state.elementSizeBytes;
if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
ALOGE("Error Allocation::subElementData component %i out of range.", cIdx);
@@ -125,7 +125,7 @@ void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
const Element * e = mHal.state.type->getElement()->getField(cIdx);
if (sizeBytes != e->getSizeBytes()) {
- ALOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
+ ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes());
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
return;
}
@@ -135,8 +135,8 @@ void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
}
void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
- const void *data, uint32_t cIdx, uint32_t sizeBytes) {
- uint32_t eSize = mHal.state.elementSizeBytes;
+ const void *data, uint32_t cIdx, size_t sizeBytes) {
+ size_t eSize = mHal.state.elementSizeBytes;
if (x >= mHal.state.dimensionX) {
ALOGE("Error Allocation::subElementData X offset %i out of range.", x);
@@ -159,7 +159,7 @@ void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
const Element * e = mHal.state.type->getElement()->getField(cIdx);
if (sizeBytes != e->getSizeBytes()) {
- ALOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
+ ALOGE("Error Allocation::subElementData data size %zu does not match field size %zu.", sizeBytes, e->getSizeBytes());
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
return;
}
@@ -249,7 +249,7 @@ void Allocation::writePackedData(const Type *type,
delete[] sizeUnpadded;
}
-void Allocation::unpackVec3Allocation(const void *data, uint32_t dataSize) {
+void Allocation::unpackVec3Allocation(const void *data, size_t dataSize) {
const uint8_t *src = (const uint8_t*)data;
uint8_t *dst = (uint8_t*)getPtr();
@@ -519,13 +519,13 @@ void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t
}
void rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
- const void *data, size_t eoff, uint32_t sizeBytes) { // TODO: this seems wrong, eoff and sizeBytes may be swapped
+ const void *data, size_t sizeBytes, size_t eoff) {
Allocation *a = static_cast<Allocation *>(va);
a->elementData(rsc, x, y, data, eoff, sizeBytes);
}
void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
- const void *data, size_t eoff, uint32_t sizeBytes) { // TODO: this seems wrong, eoff and sizeBytes may be swapped
+ const void *data, size_t sizeBytes, size_t eoff) {
Allocation *a = static_cast<Allocation *>(va);
a->elementData(rsc, x, data, eoff, sizeBytes);
}
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 4ce863ab927f..20201ca793ea 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.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.
@@ -80,16 +80,16 @@ public:
void resize1D(Context *rsc, uint32_t dimX);
void resize2D(Context *rsc, uint32_t dimX, uint32_t dimY);
- void data(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, const void *data, uint32_t sizeBytes);
+ void data(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, const void *data, size_t sizeBytes);
void data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
- uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes);
+ uint32_t w, uint32_t h, const void *data, size_t sizeBytes);
void data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, RsAllocationCubemapFace face,
- uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes);
+ uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes);
void elementData(Context *rsc, uint32_t x,
- const void *data, uint32_t elementOff, uint32_t sizeBytes);
+ const void *data, uint32_t elementOff, size_t sizeBytes);
void elementData(Context *rsc, uint32_t x, uint32_t y,
- const void *data, uint32_t elementOff, uint32_t sizeBytes);
+ const void *data, uint32_t elementOff, size_t sizeBytes);
void read(void *data);
@@ -138,7 +138,7 @@ private:
uint32_t getPackedSize() const;
static void writePackedData(const Type *type, uint8_t *dst, const uint8_t *src, bool dstPadded);
- void unpackVec3Allocation(const void *data, uint32_t dataSize);
+ void unpackVec3Allocation(const void *data, size_t dataSize);
void packVec3Allocation(OStream *stream) const;
};
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 8ba1a0e4294d..191777428712 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -124,7 +124,6 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t time
while (!mToCore.isEmpty() || waitForCommand) {
uint32_t cmdID = 0;
uint32_t cmdSize = 0;
- ret = true;
if (con->props.mLogTimes) {
con->timerSet(Context::RS_TIMER_IDLE);
}
@@ -136,11 +135,17 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t time
delay = 0;
}
}
+
+ if (delay == 0 && timeToWait != 0 && mToCore.isEmpty()) {
+ break;
+ }
+
const void * data = mToCore.get(&cmdID, &cmdSize, delay);
if (!cmdSize) {
// exception or timeout occurred.
- return false;
+ break;
}
+ ret = true;
if (con->props.mLogTimes) {
con->timerSet(Context::RS_TIMER_INTERNAL);
}
diff --git a/libs/rs/scriptc/rs_atomic.rsh b/libs/rs/scriptc/rs_atomic.rsh
index 87c6c021b491..a455edd4ae63 100644
--- a/libs/rs/scriptc/rs_atomic.rsh
+++ b/libs/rs/scriptc/rs_atomic.rsh
@@ -242,7 +242,7 @@ extern int32_t __attribute__((overloadable))
* @return old value
*/
extern uint32_t __attribute__((overloadable))
- rsAtomicCas(volatile uint32_t* addr, int32_t compareValue, int32_t newValue);
+ rsAtomicCas(volatile uint32_t* addr, uint32_t compareValue, uint32_t newValue);
#endif //defined(RS_VERSION) && (RS_VERSION >= 14)
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 15b83bbd2cfa..3fa562ec6074 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -221,7 +221,7 @@ static void deserializeInternal(const void* inData, Res_png_9patch* outData) {
static bool assertIdmapHeader(const uint32_t* map, size_t sizeBytes)
{
if (sizeBytes < ResTable::IDMAP_HEADER_SIZE_BYTES) {
- ALOGW("idmap assertion failed: size=%d bytes\n", sizeBytes);
+ ALOGW("idmap assertion failed: size=%d bytes\n", (int)sizeBytes);
return false;
}
if (*map != htodl(IDMAP_MAGIC)) { // htodl: map data expected to be in correct endianess
@@ -250,7 +250,7 @@ static status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key,
return UNKNOWN_ERROR;
}
if (typeCount > size) {
- ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, size);
+ ALOGW("Resource ID map: number of types=%d exceeds size of map=%d\n", typeCount, (int)size);
return UNKNOWN_ERROR;
}
const uint32_t typeOffset = map[type];
@@ -260,7 +260,7 @@ static status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key,
}
if (typeOffset + 1 > size) {
ALOGW("Resource ID map: type offset=%d exceeds reasonable value, size of map=%d\n",
- typeOffset, size);
+ typeOffset, (int)size);
return UNKNOWN_ERROR;
}
const uint32_t entryCount = map[typeOffset];
@@ -271,7 +271,7 @@ static status_t idmapLookup(const uint32_t* map, size_t sizeBytes, uint32_t key,
}
const uint32_t index = typeOffset + 2 + entry - entryOffset;
if (index > size) {
- ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, size);
+ ALOGW("Resource ID map: entry index=%d exceeds size of map=%d\n", index, (int)size);
*outValue = 0;
return NO_ERROR;
}
@@ -659,6 +659,16 @@ const char* ResStringPool::string8At(size_t idx, size_t* outLen) const
return NULL;
}
+const String8 ResStringPool::string8ObjectAt(size_t idx) const
+{
+ size_t len;
+ const char *str = (const char*)string8At(idx, &len);
+ if (str != NULL) {
+ return String8(str);
+ }
+ return String8(stringAt(idx, &len));
+}
+
const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
{
return styleAt(ref.index);
@@ -738,12 +748,25 @@ size_t ResStringPool::size() const
return (mError == NO_ERROR) ? mHeader->stringCount : 0;
}
-#ifndef HAVE_ANDROID_OS
+size_t ResStringPool::styleCount() const
+{
+ return (mError == NO_ERROR) ? mHeader->styleCount : 0;
+}
+
+size_t ResStringPool::bytes() const
+{
+ return (mError == NO_ERROR) ? mHeader->header.size : 0;
+}
+
+bool ResStringPool::isSorted() const
+{
+ return (mHeader->flags&ResStringPool_header::SORTED_FLAG)!=0;
+}
+
bool ResStringPool::isUTF8() const
{
return (mHeader->flags&ResStringPool_header::UTF8_FLAG)!=0;
}
-#endif
// --------------------------------------------------------------------
// --------------------------------------------------------------------
@@ -1367,6 +1390,873 @@ status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
// --------------------------------------------------------------------
// --------------------------------------------------------------------
+void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {
+ const size_t size = dtohl(o.size);
+ if (size >= sizeof(ResTable_config)) {
+ *this = o;
+ } else {
+ memcpy(this, &o, size);
+ memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
+ }
+}
+
+void ResTable_config::copyFromDtoH(const ResTable_config& o) {
+ copyFromDeviceNoSwap(o);
+ size = sizeof(ResTable_config);
+ mcc = dtohs(mcc);
+ mnc = dtohs(mnc);
+ density = dtohs(density);
+ screenWidth = dtohs(screenWidth);
+ screenHeight = dtohs(screenHeight);
+ sdkVersion = dtohs(sdkVersion);
+ minorVersion = dtohs(minorVersion);
+ smallestScreenWidthDp = dtohs(smallestScreenWidthDp);
+ screenWidthDp = dtohs(screenWidthDp);
+ screenHeightDp = dtohs(screenHeightDp);
+}
+
+void ResTable_config::swapHtoD() {
+ size = htodl(size);
+ mcc = htods(mcc);
+ mnc = htods(mnc);
+ density = htods(density);
+ screenWidth = htods(screenWidth);
+ screenHeight = htods(screenHeight);
+ sdkVersion = htods(sdkVersion);
+ minorVersion = htods(minorVersion);
+ smallestScreenWidthDp = htods(smallestScreenWidthDp);
+ screenWidthDp = htods(screenWidthDp);
+ screenHeightDp = htods(screenHeightDp);
+}
+
+int ResTable_config::compare(const ResTable_config& o) const {
+ int32_t diff = (int32_t)(imsi - o.imsi);
+ if (diff != 0) return diff;
+ diff = (int32_t)(locale - o.locale);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenType - o.screenType);
+ if (diff != 0) return diff;
+ diff = (int32_t)(input - o.input);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenSize - o.screenSize);
+ if (diff != 0) return diff;
+ diff = (int32_t)(version - o.version);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenLayout - o.screenLayout);
+ if (diff != 0) return diff;
+ diff = (int32_t)(uiMode - o.uiMode);
+ if (diff != 0) return diff;
+ diff = (int32_t)(smallestScreenWidthDp - o.smallestScreenWidthDp);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenSizeDp - o.screenSizeDp);
+ return (int)diff;
+}
+
+int ResTable_config::compareLogical(const ResTable_config& o) const {
+ if (mcc != o.mcc) {
+ return mcc < o.mcc ? -1 : 1;
+ }
+ if (mnc != o.mnc) {
+ return mnc < o.mnc ? -1 : 1;
+ }
+ if (language[0] != o.language[0]) {
+ return language[0] < o.language[0] ? -1 : 1;
+ }
+ if (language[1] != o.language[1]) {
+ return language[1] < o.language[1] ? -1 : 1;
+ }
+ if (country[0] != o.country[0]) {
+ return country[0] < o.country[0] ? -1 : 1;
+ }
+ if (country[1] != o.country[1]) {
+ return country[1] < o.country[1] ? -1 : 1;
+ }
+ if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+ return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;
+ }
+ if (screenWidthDp != o.screenWidthDp) {
+ return screenWidthDp < o.screenWidthDp ? -1 : 1;
+ }
+ if (screenHeightDp != o.screenHeightDp) {
+ return screenHeightDp < o.screenHeightDp ? -1 : 1;
+ }
+ if (screenWidth != o.screenWidth) {
+ return screenWidth < o.screenWidth ? -1 : 1;
+ }
+ if (screenHeight != o.screenHeight) {
+ return screenHeight < o.screenHeight ? -1 : 1;
+ }
+ if (density != o.density) {
+ return density < o.density ? -1 : 1;
+ }
+ if (orientation != o.orientation) {
+ return orientation < o.orientation ? -1 : 1;
+ }
+ if (touchscreen != o.touchscreen) {
+ return touchscreen < o.touchscreen ? -1 : 1;
+ }
+ if (input != o.input) {
+ return input < o.input ? -1 : 1;
+ }
+ if (screenLayout != o.screenLayout) {
+ return screenLayout < o.screenLayout ? -1 : 1;
+ }
+ if (uiMode != o.uiMode) {
+ return uiMode < o.uiMode ? -1 : 1;
+ }
+ if (version != o.version) {
+ return version < o.version ? -1 : 1;
+ }
+ return 0;
+}
+
+int ResTable_config::diff(const ResTable_config& o) const {
+ int diffs = 0;
+ if (mcc != o.mcc) diffs |= CONFIG_MCC;
+ if (mnc != o.mnc) diffs |= CONFIG_MNC;
+ if (locale != o.locale) diffs |= CONFIG_LOCALE;
+ if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
+ if (density != o.density) diffs |= CONFIG_DENSITY;
+ if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
+ if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
+ diffs |= CONFIG_KEYBOARD_HIDDEN;
+ if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
+ if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
+ if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
+ if (version != o.version) diffs |= CONFIG_VERSION;
+ if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
+ if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
+ if (smallestScreenWidthDp != o.smallestScreenWidthDp) diffs |= CONFIG_SMALLEST_SCREEN_SIZE;
+ if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
+ return diffs;
+}
+
+bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {
+ // The order of the following tests defines the importance of one
+ // configuration parameter over another. Those tests first are more
+ // important, trumping any values in those following them.
+ if (imsi || o.imsi) {
+ if (mcc != o.mcc) {
+ if (!mcc) return false;
+ if (!o.mcc) return true;
+ }
+
+ if (mnc != o.mnc) {
+ if (!mnc) return false;
+ if (!o.mnc) return true;
+ }
+ }
+
+ if (locale || o.locale) {
+ if (language[0] != o.language[0]) {
+ if (!language[0]) return false;
+ if (!o.language[0]) return true;
+ }
+
+ if (country[0] != o.country[0]) {
+ if (!country[0]) return false;
+ if (!o.country[0]) return true;
+ }
+ }
+
+ if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
+ if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+ if (!smallestScreenWidthDp) return false;
+ if (!o.smallestScreenWidthDp) return true;
+ }
+ }
+
+ if (screenSizeDp || o.screenSizeDp) {
+ if (screenWidthDp != o.screenWidthDp) {
+ if (!screenWidthDp) return false;
+ if (!o.screenWidthDp) return true;
+ }
+
+ if (screenHeightDp != o.screenHeightDp) {
+ if (!screenHeightDp) return false;
+ if (!o.screenHeightDp) return true;
+ }
+ }
+
+ if (screenLayout || o.screenLayout) {
+ if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0) {
+ if (!(screenLayout & MASK_SCREENSIZE)) return false;
+ if (!(o.screenLayout & MASK_SCREENSIZE)) return true;
+ }
+ if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0) {
+ if (!(screenLayout & MASK_SCREENLONG)) return false;
+ if (!(o.screenLayout & MASK_SCREENLONG)) return true;
+ }
+ }
+
+ if (orientation != o.orientation) {
+ if (!orientation) return false;
+ if (!o.orientation) return true;
+ }
+
+ if (uiMode || o.uiMode) {
+ if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) {
+ if (!(uiMode & MASK_UI_MODE_TYPE)) return false;
+ if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true;
+ }
+ if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) {
+ if (!(uiMode & MASK_UI_MODE_NIGHT)) return false;
+ if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true;
+ }
+ }
+
+ // density is never 'more specific'
+ // as the default just equals 160
+
+ if (touchscreen != o.touchscreen) {
+ if (!touchscreen) return false;
+ if (!o.touchscreen) return true;
+ }
+
+ if (input || o.input) {
+ if (((inputFlags^o.inputFlags) & MASK_KEYSHIDDEN) != 0) {
+ if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
+ if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
+ }
+
+ if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
+ if (!(inputFlags & MASK_NAVHIDDEN)) return false;
+ if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
+ }
+
+ if (keyboard != o.keyboard) {
+ if (!keyboard) return false;
+ if (!o.keyboard) return true;
+ }
+
+ if (navigation != o.navigation) {
+ if (!navigation) return false;
+ if (!o.navigation) return true;
+ }
+ }
+
+ if (screenSize || o.screenSize) {
+ if (screenWidth != o.screenWidth) {
+ if (!screenWidth) return false;
+ if (!o.screenWidth) return true;
+ }
+
+ if (screenHeight != o.screenHeight) {
+ if (!screenHeight) return false;
+ if (!o.screenHeight) return true;
+ }
+ }
+
+ if (version || o.version) {
+ if (sdkVersion != o.sdkVersion) {
+ if (!sdkVersion) return false;
+ if (!o.sdkVersion) return true;
+ }
+
+ if (minorVersion != o.minorVersion) {
+ if (!minorVersion) return false;
+ if (!o.minorVersion) return true;
+ }
+ }
+ return false;
+}
+
+bool ResTable_config::isBetterThan(const ResTable_config& o,
+ const ResTable_config* requested) const {
+ if (requested) {
+ if (imsi || o.imsi) {
+ if ((mcc != o.mcc) && requested->mcc) {
+ return (mcc);
+ }
+
+ if ((mnc != o.mnc) && requested->mnc) {
+ return (mnc);
+ }
+ }
+
+ if (locale || o.locale) {
+ if ((language[0] != o.language[0]) && requested->language[0]) {
+ return (language[0]);
+ }
+
+ if ((country[0] != o.country[0]) && requested->country[0]) {
+ return (country[0]);
+ }
+ }
+
+ if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
+ // The configuration closest to the actual size is best.
+ // We assume that larger configs have already been filtered
+ // out at this point. That means we just want the largest one.
+ return smallestScreenWidthDp >= o.smallestScreenWidthDp;
+ }
+
+ if (screenSizeDp || o.screenSizeDp) {
+ // "Better" is based on the sum of the difference between both
+ // width and height from the requested dimensions. We are
+ // assuming the invalid configs (with smaller dimens) have
+ // already been filtered. Note that if a particular dimension
+ // is unspecified, we will end up with a large value (the
+ // difference between 0 and the requested dimension), which is
+ // good since we will prefer a config that has specified a
+ // dimension value.
+ int myDelta = 0, otherDelta = 0;
+ if (requested->screenWidthDp) {
+ myDelta += requested->screenWidthDp - screenWidthDp;
+ otherDelta += requested->screenWidthDp - o.screenWidthDp;
+ }
+ if (requested->screenHeightDp) {
+ myDelta += requested->screenHeightDp - screenHeightDp;
+ otherDelta += requested->screenHeightDp - o.screenHeightDp;
+ }
+ //ALOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
+ // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
+ // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+ return (myDelta <= otherDelta);
+ }
+
+ if (screenLayout || o.screenLayout) {
+ if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
+ && (requested->screenLayout & MASK_SCREENSIZE)) {
+ // A little backwards compatibility here: undefined is
+ // considered equivalent to normal. But only if the
+ // requested size is at least normal; otherwise, small
+ // is better than the default.
+ int mySL = (screenLayout & MASK_SCREENSIZE);
+ int oSL = (o.screenLayout & MASK_SCREENSIZE);
+ int fixedMySL = mySL;
+ int fixedOSL = oSL;
+ if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+ if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+ if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+ }
+ // For screen size, the best match is the one that is
+ // closest to the requested screen size, but not over
+ // (the not over part is dealt with in match() below).
+ if (fixedMySL == fixedOSL) {
+ // If the two are the same, but 'this' is actually
+ // undefined, then the other is really a better match.
+ if (mySL == 0) return false;
+ return true;
+ }
+ return fixedMySL >= fixedOSL;
+ }
+ if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
+ && (requested->screenLayout & MASK_SCREENLONG)) {
+ return (screenLayout & MASK_SCREENLONG);
+ }
+ }
+
+ if ((orientation != o.orientation) && requested->orientation) {
+ return (orientation);
+ }
+
+ if (uiMode || o.uiMode) {
+ if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
+ && (requested->uiMode & MASK_UI_MODE_TYPE)) {
+ return (uiMode & MASK_UI_MODE_TYPE);
+ }
+ if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
+ && (requested->uiMode & MASK_UI_MODE_NIGHT)) {
+ return (uiMode & MASK_UI_MODE_NIGHT);
+ }
+ }
+
+ if (screenType || o.screenType) {
+ if (density != o.density) {
+ // density is tough. Any density is potentially useful
+ // because the system will scale it. Scaling down
+ // is generally better than scaling up.
+ // Default density counts as 160dpi (the system default)
+ // TODO - remove 160 constants
+ int h = (density?density:160);
+ int l = (o.density?o.density:160);
+ bool bImBigger = true;
+ if (l > h) {
+ int t = h;
+ h = l;
+ l = t;
+ bImBigger = false;
+ }
+
+ int reqValue = (requested->density?requested->density:160);
+ if (reqValue >= h) {
+ // requested value higher than both l and h, give h
+ return bImBigger;
+ }
+ if (l >= reqValue) {
+ // requested value lower than both l and h, give l
+ return !bImBigger;
+ }
+ // saying that scaling down is 2x better than up
+ if (((2 * l) - reqValue) * h > reqValue * reqValue) {
+ return !bImBigger;
+ } else {
+ return bImBigger;
+ }
+ }
+
+ if ((touchscreen != o.touchscreen) && requested->touchscreen) {
+ return (touchscreen);
+ }
+ }
+
+ if (input || o.input) {
+ const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
+ const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
+ if (keysHidden != oKeysHidden) {
+ const int reqKeysHidden =
+ requested->inputFlags & MASK_KEYSHIDDEN;
+ if (reqKeysHidden) {
+
+ if (!keysHidden) return false;
+ if (!oKeysHidden) return true;
+ // For compatibility, we count KEYSHIDDEN_NO as being
+ // the same as KEYSHIDDEN_SOFT. Here we disambiguate
+ // these by making an exact match more specific.
+ if (reqKeysHidden == keysHidden) return true;
+ if (reqKeysHidden == oKeysHidden) return false;
+ }
+ }
+
+ const int navHidden = inputFlags & MASK_NAVHIDDEN;
+ const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
+ if (navHidden != oNavHidden) {
+ const int reqNavHidden =
+ requested->inputFlags & MASK_NAVHIDDEN;
+ if (reqNavHidden) {
+
+ if (!navHidden) return false;
+ if (!oNavHidden) return true;
+ }
+ }
+
+ if ((keyboard != o.keyboard) && requested->keyboard) {
+ return (keyboard);
+ }
+
+ if ((navigation != o.navigation) && requested->navigation) {
+ return (navigation);
+ }
+ }
+
+ if (screenSize || o.screenSize) {
+ // "Better" is based on the sum of the difference between both
+ // width and height from the requested dimensions. We are
+ // assuming the invalid configs (with smaller sizes) have
+ // already been filtered. Note that if a particular dimension
+ // is unspecified, we will end up with a large value (the
+ // difference between 0 and the requested dimension), which is
+ // good since we will prefer a config that has specified a
+ // size value.
+ int myDelta = 0, otherDelta = 0;
+ if (requested->screenWidth) {
+ myDelta += requested->screenWidth - screenWidth;
+ otherDelta += requested->screenWidth - o.screenWidth;
+ }
+ if (requested->screenHeight) {
+ myDelta += requested->screenHeight - screenHeight;
+ otherDelta += requested->screenHeight - o.screenHeight;
+ }
+ return (myDelta <= otherDelta);
+ }
+
+ if (version || o.version) {
+ if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
+ return (sdkVersion > o.sdkVersion);
+ }
+
+ if ((minorVersion != o.minorVersion) &&
+ requested->minorVersion) {
+ return (minorVersion);
+ }
+ }
+
+ return false;
+ }
+ return isMoreSpecificThan(o);
+}
+
+bool ResTable_config::match(const ResTable_config& settings) const {
+ if (imsi != 0) {
+ if (mcc != 0 && mcc != settings.mcc) {
+ return false;
+ }
+ if (mnc != 0 && mnc != settings.mnc) {
+ return false;
+ }
+ }
+ if (locale != 0) {
+ if (language[0] != 0
+ && (language[0] != settings.language[0]
+ || language[1] != settings.language[1])) {
+ return false;
+ }
+ if (country[0] != 0
+ && (country[0] != settings.country[0]
+ || country[1] != settings.country[1])) {
+ return false;
+ }
+ }
+ if (screenConfig != 0) {
+ const int screenSize = screenLayout&MASK_SCREENSIZE;
+ const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
+ // Any screen sizes for larger screens than the setting do not
+ // match.
+ if (screenSize != 0 && screenSize > setScreenSize) {
+ return false;
+ }
+
+ const int screenLong = screenLayout&MASK_SCREENLONG;
+ const int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
+ if (screenLong != 0 && screenLong != setScreenLong) {
+ return false;
+ }
+
+ const int uiModeType = uiMode&MASK_UI_MODE_TYPE;
+ const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
+ if (uiModeType != 0 && uiModeType != setUiModeType) {
+ return false;
+ }
+
+ const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
+ const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
+ if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
+ return false;
+ }
+
+ if (smallestScreenWidthDp != 0
+ && smallestScreenWidthDp > settings.smallestScreenWidthDp) {
+ return false;
+ }
+ }
+ if (screenSizeDp != 0) {
+ if (screenWidthDp != 0 && screenWidthDp > settings.screenWidthDp) {
+ //ALOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
+ return false;
+ }
+ if (screenHeightDp != 0 && screenHeightDp > settings.screenHeightDp) {
+ //ALOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
+ return false;
+ }
+ }
+ if (screenType != 0) {
+ if (orientation != 0 && orientation != settings.orientation) {
+ return false;
+ }
+ // density always matches - we can scale it. See isBetterThan
+ if (touchscreen != 0 && touchscreen != settings.touchscreen) {
+ return false;
+ }
+ }
+ if (input != 0) {
+ const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
+ const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
+ if (keysHidden != 0 && keysHidden != setKeysHidden) {
+ // For compatibility, we count a request for KEYSHIDDEN_NO as also
+ // matching the more recent KEYSHIDDEN_SOFT. Basically
+ // KEYSHIDDEN_NO means there is some kind of keyboard available.
+ //ALOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
+ if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
+ //ALOGI("No match!");
+ return false;
+ }
+ }
+ const int navHidden = inputFlags&MASK_NAVHIDDEN;
+ const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
+ if (navHidden != 0 && navHidden != setNavHidden) {
+ return false;
+ }
+ if (keyboard != 0 && keyboard != settings.keyboard) {
+ return false;
+ }
+ if (navigation != 0 && navigation != settings.navigation) {
+ return false;
+ }
+ }
+ if (screenSize != 0) {
+ if (screenWidth != 0 && screenWidth > settings.screenWidth) {
+ return false;
+ }
+ if (screenHeight != 0 && screenHeight > settings.screenHeight) {
+ return false;
+ }
+ }
+ if (version != 0) {
+ if (sdkVersion != 0 && sdkVersion > settings.sdkVersion) {
+ return false;
+ }
+ if (minorVersion != 0 && minorVersion != settings.minorVersion) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void ResTable_config::getLocale(char str[6]) const {
+ memset(str, 0, 6);
+ if (language[0]) {
+ str[0] = language[0];
+ str[1] = language[1];
+ if (country[0]) {
+ str[2] = '_';
+ str[3] = country[0];
+ str[4] = country[1];
+ }
+ }
+}
+
+String8 ResTable_config::toString() const {
+ String8 res;
+
+ if (mcc != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("%dmcc", dtohs(mcc));
+ }
+ if (mnc != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("%dmnc", dtohs(mnc));
+ }
+ if (language[0] != 0) {
+ if (res.size() > 0) res.append("-");
+ res.append(language, 2);
+ }
+ if (country[0] != 0) {
+ if (res.size() > 0) res.append("-");
+ res.append(country, 2);
+ }
+ if (smallestScreenWidthDp != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp));
+ }
+ if (screenWidthDp != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("w%ddp", dtohs(screenWidthDp));
+ }
+ if (screenHeightDp != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("h%ddp", dtohs(screenHeightDp));
+ }
+ if ((screenLayout&MASK_SCREENSIZE) != SCREENSIZE_ANY) {
+ if (res.size() > 0) res.append("-");
+ switch (screenLayout&ResTable_config::MASK_SCREENSIZE) {
+ case ResTable_config::SCREENSIZE_SMALL:
+ res.append("small");
+ break;
+ case ResTable_config::SCREENSIZE_NORMAL:
+ res.append("normal");
+ break;
+ case ResTable_config::SCREENSIZE_LARGE:
+ res.append("large");
+ break;
+ case ResTable_config::SCREENSIZE_XLARGE:
+ res.append("xlarge");
+ break;
+ default:
+ res.appendFormat("screenLayoutSize=%d",
+ dtohs(screenLayout&ResTable_config::MASK_SCREENSIZE));
+ break;
+ }
+ }
+ if ((screenLayout&MASK_SCREENLONG) != 0) {
+ if (res.size() > 0) res.append("-");
+ switch (screenLayout&ResTable_config::MASK_SCREENLONG) {
+ case ResTable_config::SCREENLONG_NO:
+ res.append("notlong");
+ break;
+ case ResTable_config::SCREENLONG_YES:
+ res.append("long");
+ break;
+ default:
+ res.appendFormat("screenLayoutLong=%d",
+ dtohs(screenLayout&ResTable_config::MASK_SCREENLONG));
+ break;
+ }
+ }
+ if (orientation != ORIENTATION_ANY) {
+ if (res.size() > 0) res.append("-");
+ switch (orientation) {
+ case ResTable_config::ORIENTATION_PORT:
+ res.append("port");
+ break;
+ case ResTable_config::ORIENTATION_LAND:
+ res.append("land");
+ break;
+ case ResTable_config::ORIENTATION_SQUARE:
+ res.append("square");
+ break;
+ default:
+ res.appendFormat("orientation=%d", dtohs(orientation));
+ break;
+ }
+ }
+ if ((uiMode&MASK_UI_MODE_TYPE) != UI_MODE_TYPE_ANY) {
+ if (res.size() > 0) res.append("-");
+ switch (uiMode&ResTable_config::MASK_UI_MODE_TYPE) {
+ case ResTable_config::UI_MODE_TYPE_DESK:
+ res.append("desk");
+ break;
+ case ResTable_config::UI_MODE_TYPE_CAR:
+ res.append("car");
+ break;
+ case ResTable_config::UI_MODE_TYPE_TELEVISION:
+ res.append("television");
+ break;
+ case ResTable_config::UI_MODE_TYPE_APPLIANCE:
+ res.append("appliance");
+ break;
+ default:
+ res.appendFormat("uiModeType=%d",
+ dtohs(screenLayout&ResTable_config::MASK_UI_MODE_TYPE));
+ break;
+ }
+ }
+ if ((uiMode&MASK_UI_MODE_NIGHT) != 0) {
+ if (res.size() > 0) res.append("-");
+ switch (uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {
+ case ResTable_config::UI_MODE_NIGHT_NO:
+ res.append("notnight");
+ break;
+ case ResTable_config::UI_MODE_NIGHT_YES:
+ res.append("night");
+ break;
+ default:
+ res.appendFormat("uiModeNight=%d",
+ dtohs(uiMode&MASK_UI_MODE_NIGHT));
+ break;
+ }
+ }
+ if (density != DENSITY_DEFAULT) {
+ if (res.size() > 0) res.append("-");
+ switch (density) {
+ case ResTable_config::DENSITY_LOW:
+ res.append("ldpi");
+ break;
+ case ResTable_config::DENSITY_MEDIUM:
+ res.append("mdpi");
+ break;
+ case ResTable_config::DENSITY_TV:
+ res.append("tvdpi");
+ break;
+ case ResTable_config::DENSITY_HIGH:
+ res.append("hdpi");
+ break;
+ case ResTable_config::DENSITY_XHIGH:
+ res.append("xhdpi");
+ break;
+ case ResTable_config::DENSITY_XXHIGH:
+ res.append("xxhdpi");
+ break;
+ case ResTable_config::DENSITY_NONE:
+ res.append("nodpi");
+ break;
+ default:
+ res.appendFormat("density=%d", dtohs(density));
+ break;
+ }
+ }
+ if (touchscreen != TOUCHSCREEN_ANY) {
+ if (res.size() > 0) res.append("-");
+ switch (touchscreen) {
+ case ResTable_config::TOUCHSCREEN_NOTOUCH:
+ res.append("notouch");
+ break;
+ case ResTable_config::TOUCHSCREEN_FINGER:
+ res.append("finger");
+ break;
+ case ResTable_config::TOUCHSCREEN_STYLUS:
+ res.append("stylus");
+ break;
+ default:
+ res.appendFormat("touchscreen=%d", dtohs(touchscreen));
+ break;
+ }
+ }
+ if (keyboard != KEYBOARD_ANY) {
+ if (res.size() > 0) res.append("-");
+ switch (keyboard) {
+ case ResTable_config::KEYBOARD_NOKEYS:
+ res.append("nokeys");
+ break;
+ case ResTable_config::KEYBOARD_QWERTY:
+ res.append("qwerty");
+ break;
+ case ResTable_config::KEYBOARD_12KEY:
+ res.append("12key");
+ break;
+ default:
+ res.appendFormat("keyboard=%d", dtohs(keyboard));
+ break;
+ }
+ }
+ if ((inputFlags&MASK_KEYSHIDDEN) != 0) {
+ if (res.size() > 0) res.append("-");
+ switch (inputFlags&MASK_KEYSHIDDEN) {
+ case ResTable_config::KEYSHIDDEN_NO:
+ res.append("keysexposed");
+ break;
+ case ResTable_config::KEYSHIDDEN_YES:
+ res.append("keyshidden");
+ break;
+ case ResTable_config::KEYSHIDDEN_SOFT:
+ res.append("keyssoft");
+ break;
+ }
+ }
+ if (navigation != NAVIGATION_ANY) {
+ if (res.size() > 0) res.append("-");
+ switch (navigation) {
+ case ResTable_config::NAVIGATION_NONAV:
+ res.append("nonav");
+ break;
+ case ResTable_config::NAVIGATION_DPAD:
+ res.append("dpad");
+ break;
+ case ResTable_config::NAVIGATION_TRACKBALL:
+ res.append("trackball");
+ break;
+ case ResTable_config::NAVIGATION_WHEEL:
+ res.append("wheel");
+ break;
+ default:
+ res.appendFormat("navigation=%d", dtohs(navigation));
+ break;
+ }
+ }
+ if ((inputFlags&MASK_NAVHIDDEN) != 0) {
+ if (res.size() > 0) res.append("-");
+ switch (inputFlags&MASK_NAVHIDDEN) {
+ case ResTable_config::NAVHIDDEN_NO:
+ res.append("navsexposed");
+ break;
+ case ResTable_config::NAVHIDDEN_YES:
+ res.append("navhidden");
+ break;
+ default:
+ res.appendFormat("inputFlagsNavHidden=%d",
+ dtohs(inputFlags&MASK_NAVHIDDEN));
+ break;
+ }
+ }
+ if (screenSize != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("%dx%d", dtohs(screenWidth), dtohs(screenHeight));
+ }
+ if (version != 0) {
+ if (res.size() > 0) res.append("-");
+ res.appendFormat("v%d", dtohs(sdkVersion));
+ if (minorVersion != 0) {
+ res.appendFormat(".%d", dtohs(minorVersion));
+ }
+ }
+
+ return res;
+}
+
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+// --------------------------------------------------------------------
+
struct ResTable::Header
{
Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),
@@ -3953,43 +4843,9 @@ ssize_t ResTable::getEntry(
ResTable_config thisConfig;
thisConfig.copyFromDtoH(thisType->config);
- TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d "
- "lang:%c%c=%c%c cnt:%c%c=%c%c orien:%d=%d touch:%d=%d "
- "density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d "
- "swdp:%d=%d wdp:%d=%d hdp:%d=%d\n",
+ TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): %s\n",
entryIndex, typeIndex+1, dtohl(thisType->config.size),
- thisConfig.mcc, thisConfig.mnc,
- config ? config->mcc : 0, config ? config->mnc : 0,
- thisConfig.language[0] ? thisConfig.language[0] : '-',
- thisConfig.language[1] ? thisConfig.language[1] : '-',
- config && config->language[0] ? config->language[0] : '-',
- config && config->language[1] ? config->language[1] : '-',
- thisConfig.country[0] ? thisConfig.country[0] : '-',
- thisConfig.country[1] ? thisConfig.country[1] : '-',
- config && config->country[0] ? config->country[0] : '-',
- config && config->country[1] ? config->country[1] : '-',
- thisConfig.orientation,
- config ? config->orientation : 0,
- thisConfig.touchscreen,
- config ? config->touchscreen : 0,
- thisConfig.density,
- config ? config->density : 0,
- thisConfig.keyboard,
- config ? config->keyboard : 0,
- thisConfig.inputFlags,
- config ? config->inputFlags : 0,
- thisConfig.navigation,
- config ? config->navigation : 0,
- thisConfig.screenWidth,
- config ? config->screenWidth : 0,
- thisConfig.screenHeight,
- config ? config->screenHeight : 0,
- thisConfig.smallestScreenWidthDp,
- config ? config->smallestScreenWidthDp : 0,
- thisConfig.screenWidthDp,
- config ? config->screenWidthDp : 0,
- thisConfig.screenHeightDp,
- config ? config->screenHeightDp : 0));
+ thisConfig.toString().string()));
// Check to make sure this one is valid for the current parameters.
if (config && !thisConfig.match(*config)) {
@@ -4273,26 +5129,8 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
TABLE_GETENTRY(
ResTable_config thisConfig;
thisConfig.copyFromDtoH(type->config);
- ALOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d "
- "swdp:%d wdp:%d hdp:%d\n",
- type->id,
- thisConfig.mcc, thisConfig.mnc,
- thisConfig.language[0] ? thisConfig.language[0] : '-',
- thisConfig.language[1] ? thisConfig.language[1] : '-',
- thisConfig.country[0] ? thisConfig.country[0] : '-',
- thisConfig.country[1] ? thisConfig.country[1] : '-',
- thisConfig.orientation,
- thisConfig.touchscreen,
- thisConfig.density,
- thisConfig.keyboard,
- thisConfig.inputFlags,
- thisConfig.navigation,
- thisConfig.screenWidth,
- thisConfig.screenHeight,
- thisConfig.smallestScreenWidthDp,
- thisConfig.screenWidthDp,
- thisConfig.screenHeightDp));
+ ALOGI("Adding config to type %d: %s\n",
+ type->id, thisConfig.toString().string()));
t->configs.add(type);
} else {
status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
@@ -4622,186 +5460,9 @@ void ResTable::print(bool inclValues) const
printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type);
continue;
}
- char density[16];
- uint16_t dval = dtohs(type->config.density);
- if (dval == ResTable_config::DENSITY_DEFAULT) {
- strcpy(density, "def");
- } else if (dval == ResTable_config::DENSITY_NONE) {
- strcpy(density, "no");
- } else {
- sprintf(density, "%d", (int)dval);
- }
- printf(" config %d", (int)configIndex);
- if (type->config.mcc != 0) {
- printf(" mcc=%d", dtohs(type->config.mcc));
- }
- if (type->config.mnc != 0) {
- printf(" mnc=%d", dtohs(type->config.mnc));
- }
- if (type->config.locale != 0) {
- printf(" lang=%c%c cnt=%c%c",
- type->config.language[0] ? type->config.language[0] : '-',
- type->config.language[1] ? type->config.language[1] : '-',
- type->config.country[0] ? type->config.country[0] : '-',
- type->config.country[1] ? type->config.country[1] : '-');
- }
- if (type->config.screenLayout != 0) {
- printf(" sz=%d",
- type->config.screenLayout&ResTable_config::MASK_SCREENSIZE);
- switch (type->config.screenLayout&ResTable_config::MASK_SCREENSIZE) {
- case ResTable_config::SCREENSIZE_SMALL:
- printf(" (small)");
- break;
- case ResTable_config::SCREENSIZE_NORMAL:
- printf(" (normal)");
- break;
- case ResTable_config::SCREENSIZE_LARGE:
- printf(" (large)");
- break;
- case ResTable_config::SCREENSIZE_XLARGE:
- printf(" (xlarge)");
- break;
- }
- printf(" lng=%d",
- type->config.screenLayout&ResTable_config::MASK_SCREENLONG);
- switch (type->config.screenLayout&ResTable_config::MASK_SCREENLONG) {
- case ResTable_config::SCREENLONG_NO:
- printf(" (notlong)");
- break;
- case ResTable_config::SCREENLONG_YES:
- printf(" (long)");
- break;
- }
- }
- if (type->config.orientation != 0) {
- printf(" orient=%d", type->config.orientation);
- switch (type->config.orientation) {
- case ResTable_config::ORIENTATION_PORT:
- printf(" (port)");
- break;
- case ResTable_config::ORIENTATION_LAND:
- printf(" (land)");
- break;
- case ResTable_config::ORIENTATION_SQUARE:
- printf(" (square)");
- break;
- }
- }
- if (type->config.uiMode != 0) {
- printf(" type=%d",
- type->config.uiMode&ResTable_config::MASK_UI_MODE_TYPE);
- switch (type->config.uiMode&ResTable_config::MASK_UI_MODE_TYPE) {
- case ResTable_config::UI_MODE_TYPE_NORMAL:
- printf(" (normal)");
- break;
- case ResTable_config::UI_MODE_TYPE_CAR:
- printf(" (car)");
- break;
- }
- printf(" night=%d",
- type->config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT);
- switch (type->config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT) {
- case ResTable_config::UI_MODE_NIGHT_NO:
- printf(" (no)");
- break;
- case ResTable_config::UI_MODE_NIGHT_YES:
- printf(" (yes)");
- break;
- }
- }
- if (dval != 0) {
- printf(" density=%s", density);
- }
- if (type->config.touchscreen != 0) {
- printf(" touch=%d", type->config.touchscreen);
- switch (type->config.touchscreen) {
- case ResTable_config::TOUCHSCREEN_NOTOUCH:
- printf(" (notouch)");
- break;
- case ResTable_config::TOUCHSCREEN_STYLUS:
- printf(" (stylus)");
- break;
- case ResTable_config::TOUCHSCREEN_FINGER:
- printf(" (finger)");
- break;
- }
- }
- if (type->config.inputFlags != 0) {
- printf(" keyhid=%d", type->config.inputFlags&ResTable_config::MASK_KEYSHIDDEN);
- switch (type->config.inputFlags&ResTable_config::MASK_KEYSHIDDEN) {
- case ResTable_config::KEYSHIDDEN_NO:
- printf(" (no)");
- break;
- case ResTable_config::KEYSHIDDEN_YES:
- printf(" (yes)");
- break;
- case ResTable_config::KEYSHIDDEN_SOFT:
- printf(" (soft)");
- break;
- }
- printf(" navhid=%d", type->config.inputFlags&ResTable_config::MASK_NAVHIDDEN);
- switch (type->config.inputFlags&ResTable_config::MASK_NAVHIDDEN) {
- case ResTable_config::NAVHIDDEN_NO:
- printf(" (no)");
- break;
- case ResTable_config::NAVHIDDEN_YES:
- printf(" (yes)");
- break;
- }
- }
- if (type->config.keyboard != 0) {
- printf(" kbd=%d", type->config.keyboard);
- switch (type->config.keyboard) {
- case ResTable_config::KEYBOARD_NOKEYS:
- printf(" (nokeys)");
- break;
- case ResTable_config::KEYBOARD_QWERTY:
- printf(" (qwerty)");
- break;
- case ResTable_config::KEYBOARD_12KEY:
- printf(" (12key)");
- break;
- }
- }
- if (type->config.navigation != 0) {
- printf(" nav=%d", type->config.navigation);
- switch (type->config.navigation) {
- case ResTable_config::NAVIGATION_NONAV:
- printf(" (nonav)");
- break;
- case ResTable_config::NAVIGATION_DPAD:
- printf(" (dpad)");
- break;
- case ResTable_config::NAVIGATION_TRACKBALL:
- printf(" (trackball)");
- break;
- case ResTable_config::NAVIGATION_WHEEL:
- printf(" (wheel)");
- break;
- }
- }
- if (type->config.screenWidth != 0) {
- printf(" w=%d", dtohs(type->config.screenWidth));
- }
- if (type->config.screenHeight != 0) {
- printf(" h=%d", dtohs(type->config.screenHeight));
- }
- if (type->config.smallestScreenWidthDp != 0) {
- printf(" swdp=%d", dtohs(type->config.smallestScreenWidthDp));
- }
- if (type->config.screenWidthDp != 0) {
- printf(" wdp=%d", dtohs(type->config.screenWidthDp));
- }
- if (type->config.screenHeightDp != 0) {
- printf(" hdp=%d", dtohs(type->config.screenHeightDp));
- }
- if (type->config.sdkVersion != 0) {
- printf(" sdk=%d", dtohs(type->config.sdkVersion));
- }
- if (type->config.minorVersion != 0) {
- printf(" mver=%d", dtohs(type->config.minorVersion));
- }
- printf("\n");
+ String8 configStr = type->config.toString();
+ printf(" config %s:\n", configStr.size() > 0
+ ? configStr.string() : "(default)");
size_t entryCount = dtohl(type->entryCount);
uint32_t entriesStart = dtohl(type->entriesStart);
if ((entriesStart&0x3) != 0) {
diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java
index bc6847280210..8b7eee2b7baf 100644
--- a/media/java/android/media/AmrInputStream.java
+++ b/media/java/android/media/AmrInputStream.java
@@ -44,7 +44,7 @@ public final class AmrInputStream extends InputStream
private int mGae;
// result amr stream
- private byte[] mBuf = new byte[SAMPLES_PER_FRAME * 2];
+ private final byte[] mBuf = new byte[SAMPLES_PER_FRAME * 2];
private int mBufIn = 0;
private int mBufOut = 0;
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index 09aec2e6a647..804528e4d43f 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -49,7 +49,7 @@ public class AsyncPlayer {
}
}
- private LinkedList<Command> mCmdQueue = new LinkedList();
+ private final LinkedList<Command> mCmdQueue = new LinkedList();
private void startSound(Command cmd) {
// Preparing can be slow, so if there is something else
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 936ec0ff1c37..78eb89f3dc2a 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1509,7 +1509,7 @@ public class AudioManager {
* Map to convert focus event listener IDs, as used in the AudioService audio focus stack,
* to actual listener objects.
*/
- private HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap =
+ private final HashMap<String, OnAudioFocusChangeListener> mAudioFocusIdListenerMap =
new HashMap<String, OnAudioFocusChangeListener>();
/**
* Lock to prevent concurrent changes to the list of focus listeners for this AudioManager
@@ -1524,7 +1524,7 @@ public class AudioManager {
/**
* Handler for audio focus events coming from the audio service.
*/
- private FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate =
+ private final FocusEventHandlerDelegate mAudioFocusEventHandlerDelegate =
new FocusEventHandlerDelegate();
/**
@@ -1563,7 +1563,7 @@ public class AudioManager {
}
}
- private IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
+ private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
public void dispatchAudioFocusChange(int focusChange, String id) {
Message m = mAudioFocusEventHandlerDelegate.getHandler().obtainMessage(focusChange, id);
@@ -1649,11 +1649,46 @@ public class AudioManager {
mAudioFocusDispatcher, getIdForAudioFocusListener(l),
mContext.getPackageName() /* package name */);
} catch (RemoteException e) {
- Log.e(TAG, "Can't call requestAudioFocus() from AudioService due to "+e);
+ Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e);
}
return status;
}
+ /**
+ * @hide
+ * Used internally by telephony package to request audio focus. Will cause the focus request
+ * to be associated with the "voice communication" identifier only used in AudioService
+ * to identify this use case.
+ * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for
+ * the establishment of the call
+ * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so
+ * media applications resume after a call
+ */
+ public void requestAudioFocusForCall(int streamType, int durationHint) {
+ IAudioService service = getService();
+ try {
+ service.requestAudioFocus(streamType, durationHint, mICallBack, null,
+ AudioService.IN_VOICE_COMM_FOCUS_ID,
+ "system" /* dump-friendly package name */);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e);
+ }
+ }
+
+ /**
+ * @hide
+ * Used internally by telephony package to abandon audio focus, typically after a call or
+ * when ringing ends and the call is rejected or not answered.
+ * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}.
+ */
+ public void abandonAudioFocusForCall() {
+ IAudioService service = getService();
+ try {
+ service.abandonAudioFocus(null, AudioService.IN_VOICE_COMM_FOCUS_ID);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Can't call abandonAudioFocusForCall() on AudioService due to "+e);
+ }
+ }
/**
* Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
@@ -1668,7 +1703,7 @@ public class AudioManager {
status = service.abandonAudioFocus(mAudioFocusDispatcher,
getIdForAudioFocusListener(l));
} catch (RemoteException e) {
- Log.e(TAG, "Can't call abandonAudioFocus() from AudioService due to "+e);
+ Log.e(TAG, "Can't call abandonAudioFocus() on AudioService due to "+e);
}
return status;
}
@@ -1920,7 +1955,7 @@ public class AudioManager {
/**
* {@hide}
*/
- private IBinder mICallBack = new Binder();
+ private final IBinder mICallBack = new Binder();
/**
* Checks whether the phone is in silent mode, with or without vibrate.
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 855e831541ce..5cc24c003928 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -161,7 +161,7 @@ public class AudioRecord
/**
* Lock to make sure mRecordingState updates are reflecting the actual state of the object.
*/
- private Object mRecordingStateLock = new Object();
+ private final Object mRecordingStateLock = new Object();
/**
* The listener the AudioRecord notifies when the record position reaches a marker
* or for periodic updates during the progression of the record head.
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2eafd68f57e5..13e3982541ac 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -151,7 +151,7 @@ public class AudioService extends IAudioService.Stub {
private boolean mMediaServerOk;
private SoundPool mSoundPool;
- private Object mSoundEffectsLock = new Object();
+ private final Object mSoundEffectsLock = new Object();
private static final int NUM_SOUNDPOOL_CHANNELS = 4;
private static final int SOUND_EFFECT_VOLUME = 1000;
@@ -168,7 +168,7 @@ public class AudioService extends IAudioService.Stub {
/* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to
* file index in SOUND_EFFECT_FILES[] (first column) and indicating if effect
* uses soundpool (second column) */
- private int[][] SOUND_EFFECT_FILES_MAP = new int[][] {
+ private final int[][] SOUND_EFFECT_FILES_MAP = new int[][] {
{0, -1}, // FX_KEY_CLICK
{0, -1}, // FX_FOCUS_NAVIGATION_UP
{0, -1}, // FX_FOCUS_NAVIGATION_DOWN
@@ -181,7 +181,7 @@ public class AudioService extends IAudioService.Stub {
};
/** @hide Maximum volume index values for audio streams */
- private int[] MAX_STREAM_VOLUME = new int[] {
+ private final int[] MAX_STREAM_VOLUME = new int[] {
5, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
7, // STREAM_RING
@@ -197,7 +197,7 @@ public class AudioService extends IAudioService.Stub {
* of another stream: This avoids multiplying the volume settings for hidden
* stream types that follow other stream behavior for volume settings
* NOTE: do not create loops in aliases! */
- private int[] STREAM_VOLUME_ALIAS = new int[] {
+ private final int[] STREAM_VOLUME_ALIAS = new int[] {
AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL
AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM
AudioSystem.STREAM_RING, // STREAM_RING
@@ -210,7 +210,7 @@ public class AudioService extends IAudioService.Stub {
AudioSystem.STREAM_MUSIC // STREAM_TTS
};
- private AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
+ private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
case AudioSystem.AUDIO_STATUS_SERVER_DIED:
@@ -270,17 +270,17 @@ public class AudioService extends IAudioService.Stub {
private boolean mIsRinging = false;
// Devices currently connected
- private HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();
+ private final HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();
// Forced device usage for communications
private int mForcedUseForComm;
// List of binder death handlers for setMode() client processes.
// The last process to have called setMode() is at the top of the list.
- private ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>();
+ private final ArrayList <SetModeDeathHandler> mSetModeDeathHandlers = new ArrayList <SetModeDeathHandler>();
// List of clients having issued a SCO start request
- private ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>();
+ private final ArrayList <ScoClient> mScoClients = new ArrayList <ScoClient>();
// BluetoothHeadset API to control SCO connection
private BluetoothHeadset mBluetoothHeadset;
@@ -992,8 +992,6 @@ public class AudioService extends IAudioService.Stub {
if (mode != mMode) {
status = AudioSystem.setPhoneState(mode);
if (status == AudioSystem.AUDIO_STATUS_OK) {
- // automatically handle audio focus for mode changes
- handleFocusForCalls(mMode, mode, cb);
mMode = mode;
} else {
if (hdlr != null) {
@@ -1024,40 +1022,6 @@ public class AudioService extends IAudioService.Stub {
return newModeOwnerPid;
}
- /** pre-condition: oldMode != newMode */
- private void handleFocusForCalls(int oldMode, int newMode, IBinder cb) {
- // if ringing
- if (newMode == AudioSystem.MODE_RINGTONE) {
- // if not ringing silently
- int ringVolume = AudioService.this.getStreamVolume(AudioManager.STREAM_RING);
- if (ringVolume > 0) {
- // request audio focus for the communication focus entry
- requestAudioFocus(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
- null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
- IN_VOICE_COMM_FOCUS_ID /*clientId*/,
- "system");
-
- }
- }
- // if entering call
- else if ((newMode == AudioSystem.MODE_IN_CALL)
- || (newMode == AudioSystem.MODE_IN_COMMUNICATION)) {
- // request audio focus for the communication focus entry
- // (it's ok if focus was already requested during ringing)
- requestAudioFocus(AudioManager.STREAM_RING,
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, cb,
- null /* IAudioFocusDispatcher allowed to be null only for this clientId */,
- IN_VOICE_COMM_FOCUS_ID /*clientId*/,
- "system");
- }
- // if exiting call
- else if (newMode == AudioSystem.MODE_NORMAL) {
- // abandon audio focus for communication focus entry
- abandonAudioFocus(null, IN_VOICE_COMM_FOCUS_ID);
- }
- }
-
/** @see AudioManager#getMode() */
public int getMode() {
return mMode;
@@ -2896,9 +2860,10 @@ public class AudioService extends IAudioService.Stub {
//==========================================================================================
/* constant to identify focus stack entry that is used to hold the focus while the phone
- * is ringing or during a call
+ * is ringing or during a call. Used by com.android.internal.telephony.CallManager when
+ * entering and exiting calls.
*/
- private final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
+ public final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
private final static Object mAudioFocusLock = new Object();
@@ -2980,7 +2945,7 @@ public class AudioService extends IAudioService.Stub {
}
}
- private Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
+ private final Stack<FocusStackEntry> mFocusStack = new Stack<FocusStackEntry>();
/**
* Helper function:
@@ -3357,7 +3322,7 @@ public class AudioService extends IAudioService.Stub {
* synchronized on mRCStack, but also BEFORE on mFocusLock as any change in either
* stack, audio focus or RC, can lead to a change in the remote control display
*/
- private Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
+ private final Stack<RemoteControlStackEntry> mRCStack = new Stack<RemoteControlStackEntry>();
/**
* Helper function:
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 7b2f1b7dca59..7d4c28285851 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -840,7 +840,10 @@ public class AudioTrack
/**
* Stops playing the audio data.
- *
+ * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing
+ * after the last buffer that was written has been played. For an immediate stop, use
+ * {@link #pause()}, followed by {@link #flush()} to discard audio data that hasn't been played
+ * back yet.
* @throws IllegalStateException
*/
public void stop()
@@ -859,7 +862,7 @@ public class AudioTrack
/**
* Pauses the playback of the audio data. Data that has not been played
* back will not be discarded. Subsequent calls to {@link #play} will play
- * this data back.
+ * this data back. See {@link #flush()} to discard this data.
*
* @throws IllegalStateException
*/
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 925f965d6236..9d6c9f6c0466 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -111,7 +111,7 @@ public class ExifInterface {
// there can only be one user at a time for the native functions (and
// they cannot keep state in the native code across function calls). We
// use sLock to serialize the accesses.
- private static Object sLock = new Object();
+ private static final Object sLock = new Object();
/**
* Reads Exif tags from the specified JPEG file.
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index e275aa66dc2a..7f7e284cda8e 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -120,18 +120,18 @@ public class MediaFile {
}
}
- private static HashMap<String, MediaFileType> sFileTypeMap
+ private static final HashMap<String, MediaFileType> sFileTypeMap
= new HashMap<String, MediaFileType>();
- private static HashMap<String, Integer> sMimeTypeMap
+ private static final HashMap<String, Integer> sMimeTypeMap
= new HashMap<String, Integer>();
// maps file extension to MTP format code
- private static HashMap<String, Integer> sFileTypeToFormatMap
+ private static final HashMap<String, Integer> sFileTypeToFormatMap
= new HashMap<String, Integer>();
// maps mime type to MTP format code
- private static HashMap<String, Integer> sMimeTypeToFormatMap
+ private static final HashMap<String, Integer> sMimeTypeToFormatMap
= new HashMap<String, Integer>();
// maps MTP format code to mime type
- private static HashMap<Integer, String> sFormatToMimeTypeMap
+ private static final HashMap<Integer, String> sFormatToMimeTypeMap
= new HashMap<Integer, String>();
static void addFileType(String extension, int fileType, String mimeType) {
diff --git a/media/java/android/media/MediaInserter.java b/media/java/android/media/MediaInserter.java
index a998407ca6b2..e92c710a3edd 100644
--- a/media/java/android/media/MediaInserter.java
+++ b/media/java/android/media/MediaInserter.java
@@ -32,7 +32,7 @@ import java.util.List;
* {@hide}
*/
public class MediaInserter {
- private HashMap<Uri, List<ContentValues>> mRowMap =
+ private final HashMap<Uri, List<ContentValues>> mRowMap =
new HashMap<Uri, List<ContentValues>>();
private IContentProvider mProvider;
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 08e603252c5c..a720c0a398ad 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -138,10 +138,13 @@ public class MediaRecorder
*/
public final class AudioSource {
/* Do not change these values without updating their counterparts
- * in include/media/mediarecorder.h!
+ * in system/core/include/system/audio.h!
*/
private AudioSource() {}
+
+ /** Default audio source **/
public static final int DEFAULT = 0;
+
/** Microphone audio source */
public static final int MIC = 1;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index b06ef9516918..b640e9a3e901 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -35,6 +35,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.MediaStore;
+import android.provider.MediaStore.Files.FileColumns;
import android.provider.Settings;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Files;
@@ -58,6 +59,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Locale;
/**
* Internal service helper that no-one should use directly.
@@ -345,7 +347,7 @@ public class MediaScanner
// this should be set when scanning files on a case insensitive file system.
private boolean mCaseInsensitivePaths;
- private BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+ private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
private static class FileCacheEntry {
long mRowId;
@@ -401,7 +403,7 @@ public class MediaScanner
+ Settings.System.ALARM_ALERT);
}
- private MyMediaScannerClient mClient = new MyMediaScannerClient();
+ private final MyMediaScannerClient mClient = new MyMediaScannerClient();
private boolean isDrmEnabled() {
String prop = SystemProperties.get("drm.service.enabled");
@@ -946,6 +948,22 @@ public class MediaScanner
// path should never change, and we want to avoid replacing mixed cased paths
// with squashed lower case paths
values.remove(MediaStore.MediaColumns.DATA);
+
+ int mediaType = 0;
+ if (!MediaScanner.isNoMediaPath(entry.mPath)) {
+ int fileType = MediaFile.getFileTypeForMimeType(mMimeType);
+ if (MediaFile.isAudioFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_AUDIO;
+ } else if (MediaFile.isVideoFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_VIDEO;
+ } else if (MediaFile.isImageFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_IMAGE;
+ } else if (MediaFile.isPlayListFileType(fileType)) {
+ mediaType = FileColumns.MEDIA_TYPE_PLAYLIST;
+ }
+ values.put(FileColumns.MEDIA_TYPE, mediaType);
+ }
+
mMediaProvider.update(result, values, null, null);
}
@@ -1035,7 +1053,7 @@ public class MediaScanner
// First read existing files from the files table
c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
- where, selectionArgs, null);
+ where, selectionArgs, null, null);
if (c != null) {
mWasEmptyPriorToScan = c.getCount() == 0;
@@ -1072,7 +1090,7 @@ public class MediaScanner
// compute original size of images
mOriginalCount = 0;
- c = mMediaProvider.query(mImagesUri, ID_PROJECTION, null, null, null);
+ c = mMediaProvider.query(mImagesUri, ID_PROJECTION, null, null, null, null);
if (c != null) {
mOriginalCount = c.getCount();
c.close();
@@ -1107,7 +1125,7 @@ public class MediaScanner
new String [] { "_data" },
null,
null,
- null);
+ null, null);
Log.v(TAG, "pruneDeadThumbnailFiles... " + c);
if (c != null && c.moveToFirst()) {
do {
@@ -1180,6 +1198,10 @@ public class MediaScanner
mMediaProvider.delete(ContentUris.withAppendedId(mFilesUri, entry.mRowId),
null, null);
iterator.remove();
+ if (entry.mPath.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+ File f = new File(path);
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, f.getParent(), null);
+ }
}
}
}
@@ -1472,7 +1494,7 @@ public class MediaScanner
if (bestMatch.mRowId == 0) {
Cursor c = mMediaProvider.query(mAudioUri, ID_PROJECTION,
MediaStore.Files.FileColumns.DATA + "=?",
- new String[] { bestMatch.mPath }, null);
+ new String[] { bestMatch.mPath }, null, null);
if (c != null) {
if (c.moveToNext()) {
bestMatch.mRowId = c.getLong(0);
diff --git a/media/java/android/media/MediaScannerConnection.java b/media/java/android/media/MediaScannerConnection.java
index 969da3934d18..21b6e14d3413 100644
--- a/media/java/android/media/MediaScannerConnection.java
+++ b/media/java/android/media/MediaScannerConnection.java
@@ -46,7 +46,7 @@ public class MediaScannerConnection implements ServiceConnection {
private IMediaScannerService mService;
private boolean mConnected; // true if connect() has been called since last disconnect()
- private IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() {
+ private final IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() {
public void scanCompleted(String path, Uri uri) {
MediaScannerConnectionClient client = mClient;
if (client != null) {
diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java
index df141c1919a2..63b149c66092 100644
--- a/media/java/android/media/MiniThumbFile.java
+++ b/media/java/android/media/MiniThumbFile.java
@@ -52,7 +52,7 @@ public class MiniThumbFile {
private RandomAccessFile mMiniThumbFile;
private FileChannel mChannel;
private ByteBuffer mBuffer;
- private static Hashtable<String, MiniThumbFile> sThumbFiles =
+ private static final Hashtable<String, MiniThumbFile> sThumbFiles =
new Hashtable<String, MiniThumbFile>();
/**
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 77acfe6beae8..18b4ee6f8437 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -576,6 +576,7 @@ public class RemoteControlClient
/**
* Cache for the metadata strings.
* Access synchronized on mCacheLock
+ * This is re-initialized in apply() and so cannot be final.
*/
private Bundle mMetadata = new Bundle();
@@ -621,7 +622,7 @@ public class RemoteControlClient
/**
* The IRemoteControlClient implementation
*/
- private IRemoteControlClient mIRCC = new IRemoteControlClient.Stub() {
+ private final IRemoteControlClient mIRCC = new IRemoteControlClient.Stub() {
public void onInformationRequested(int clientGeneration, int infoFlags,
int artWidth, int artHeight) {
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 9c0819fe3ceb..7aaf4aac10de 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -224,7 +224,7 @@ public class RingtoneManager {
* If a column (item from this list) exists in the Cursor, its value must
* be true (value of 1) for the row to be returned.
*/
- private List<String> mFilterColumns = new ArrayList<String>();
+ private final List<String> mFilterColumns = new ArrayList<String>();
private boolean mStopPreviousRingtone = true;
private Ringtone mPreviousRingtone;
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 19db1c017718..18aa4b3b394b 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -266,7 +266,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, PATH_WHERE,
- new String[] { path }, null);
+ new String[] { path }, null, null);
if (c != null && c.getCount() > 0) {
Log.w(TAG, "file already exists in beginSendObject: " + path);
return -1;
@@ -433,7 +433,7 @@ public class MtpDatabase {
}
}
- return mMediaProvider.query(mObjectsUri, ID_PROJECTION, where, whereArgs, null);
+ return mMediaProvider.query(mObjectsUri, ID_PROJECTION, where, whereArgs, null, null);
}
private int[] getObjectList(int storageID, int format, int parent) {
@@ -699,7 +699,7 @@ public class MtpDatabase {
String path = null;
String[] whereArgs = new String[] { Integer.toString(handle) };
try {
- c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null);
+ c = mMediaProvider.query(mObjectsUri, PATH_PROJECTION, ID_WHERE, whereArgs, null, null);
if (c != null && c.moveToNext()) {
path = c.getString(1);
}
@@ -752,6 +752,29 @@ public class MtpDatabase {
return MtpConstants.RESPONSE_GENERAL_ERROR;
}
+ // check if nomedia status changed
+ if (newFile.isDirectory()) {
+ // for directories, check if renamed from something hidden to something non-hidden
+ if (oldFile.getName().startsWith(".") && !newPath.startsWith(".")) {
+ // directory was unhidden
+ try {
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, newPath, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to unhide/rescan for " + newPath);
+ }
+ }
+ } else {
+ // for files, check if renamed from .nomedia to something else
+ if (oldFile.getName().toLowerCase(Locale.US).equals(".nomedia")
+ && !newPath.toLowerCase(Locale.US).equals(".nomedia")) {
+ try {
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, oldFile.getParent(), null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to unhide/rescan for " + newPath);
+ }
+ }
+ }
+
return MtpConstants.RESPONSE_OK;
}
@@ -815,7 +838,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
- ID_WHERE, new String[] { Integer.toString(handle) }, null);
+ ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
outStorageFormatParent[0] = c.getInt(1);
outStorageFormatParent[1] = c.getInt(2);
@@ -858,7 +881,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
- ID_WHERE, new String[] { Integer.toString(handle) }, null);
+ ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
String path = c.getString(1);
path.getChars(0, path.length(), outFilePath, 0);
@@ -887,7 +910,7 @@ public class MtpDatabase {
Cursor c = null;
try {
c = mMediaProvider.query(mObjectsUri, PATH_SIZE_FORMAT_PROJECTION,
- ID_WHERE, new String[] { Integer.toString(handle) }, null);
+ ID_WHERE, new String[] { Integer.toString(handle) }, null, null);
if (c != null && c.moveToNext()) {
// don't convert to media path here, since we will be matching
// against paths in the database matching /data/media
@@ -915,6 +938,15 @@ public class MtpDatabase {
Uri uri = Files.getMtpObjectsUri(mVolumeName, handle);
if (mMediaProvider.delete(uri, null, null) > 0) {
+ if (format != MtpConstants.FORMAT_ASSOCIATION
+ && path.toLowerCase(Locale.US).endsWith("/.nomedia")) {
+ try {
+ String parentPath = path.substring(0, path.lastIndexOf("/"));
+ mMediaProvider.call(MediaStore.UNHIDE_CALL, parentPath, null);
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to unhide/rescan for " + path);
+ }
+ }
return MtpConstants.RESPONSE_OK;
} else {
return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
@@ -933,7 +965,7 @@ public class MtpDatabase {
Uri uri = Files.getMtpReferencesUri(mVolumeName, handle);
Cursor c = null;
try {
- c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null);
+ c = mMediaProvider.query(uri, ID_PROJECTION, null, null, null, null);
if (c == null) {
return null;
}
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index 76c8569389e4..dab54547ec03 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -191,7 +191,7 @@ class MtpPropertyGroup {
// for now we are only reading properties from the "objects" table
c = mProvider.query(mUri,
new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
+ ID_WHERE, new String[] { Integer.toString(id) }, null, null);
if (c != null && c.moveToNext()) {
return c.getString(1);
} else {
@@ -211,7 +211,7 @@ class MtpPropertyGroup {
try {
c = mProvider.query(Audio.Media.getContentUri(mVolumeName),
new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
+ ID_WHERE, new String[] { Integer.toString(id) }, null, null);
if (c != null && c.moveToNext()) {
return c.getString(1);
} else {
@@ -232,7 +232,7 @@ class MtpPropertyGroup {
Uri uri = Audio.Genres.getContentUriForAudioId(mVolumeName, id);
c = mProvider.query(uri,
new String [] { Files.FileColumns._ID, Audio.GenresColumns.NAME },
- null, null, null);
+ null, null, null, null);
if (c != null && c.moveToNext()) {
return c.getString(1);
} else {
@@ -254,7 +254,7 @@ class MtpPropertyGroup {
// for now we are only reading properties from the "objects" table
c = mProvider.query(mUri,
new String [] { Files.FileColumns._ID, column },
- ID_WHERE, new String[] { Integer.toString(id) }, null);
+ ID_WHERE, new String[] { Integer.toString(id) }, null, null);
if (c != null && c.moveToNext()) {
return new Long(c.getLong(1));
}
@@ -323,7 +323,7 @@ class MtpPropertyGroup {
try {
// don't query if not necessary
if (depth > 0 || handle == 0xFFFFFFFF || mColumns.length > 1) {
- c = mProvider.query(mUri, mColumns, where, whereArgs, null);
+ c = mProvider.query(mUri, mColumns, where, whereArgs, null, null);
if (c == null) {
return new MtpPropertyList(0, MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE);
}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index ee96a959eeae..23cc0e2f3228 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -28,7 +28,11 @@ LOCAL_SHARED_LIBRARIES := \
libcamera_client \
libmtp \
libusbhost \
- libexif
+ libexif \
+ libstagefright_amrnb_common \
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrnbenc
LOCAL_C_INCLUDES += \
external/jhead \
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 5b5b0769ed00..2b3ea386c55b 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -84,7 +84,7 @@ AudioRecord::AudioRecord()
}
AudioRecord::AudioRecord(
- int inputSource,
+ audio_source_t inputSource,
uint32_t sampleRate,
audio_format_t format,
uint32_t channelMask,
@@ -119,7 +119,7 @@ AudioRecord::~AudioRecord()
}
status_t AudioRecord::set(
- int inputSource,
+ audio_source_t inputSource,
uint32_t sampleRate,
audio_format_t format,
uint32_t channelMask,
@@ -228,7 +228,7 @@ status_t AudioRecord::set(
mMarkerReached = false;
mNewPosition = 0;
mUpdatePeriod = 0;
- mInputSource = (uint8_t)inputSource;
+ mInputSource = inputSource;
mFlags = flags;
mInput = input;
AudioSystem::acquireAudioSessionId(mSessionId);
@@ -272,9 +272,9 @@ size_t AudioRecord::frameSize() const
}
}
-int AudioRecord::inputSource() const
+audio_source_t AudioRecord::inputSource() const
{
- return (int)mInputSource;
+ return mInputSource;
}
// -------------------------------------------------------------------------
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 952d6343f428..124032b36949 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -630,7 +630,7 @@ void AudioSystem::releaseOutput(audio_io_handle_t output)
aps->releaseOutput(output);
}
-audio_io_handle_t AudioSystem::getInput(int inputSource,
+audio_io_handle_t AudioSystem::getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
uint32_t channels,
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index b5c857f9a869..99385aa4f80a 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -172,7 +172,7 @@ public:
}
virtual audio_io_handle_t getInput(
- int inputSource,
+ audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
uint32_t channels,
@@ -181,7 +181,7 @@ public:
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
- data.writeInt32(inputSource);
+ data.writeInt32((int32_t) inputSource);
data.writeInt32(samplingRate);
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channels);
@@ -461,7 +461,7 @@ status_t BnAudioPolicyService::onTransact(
case GET_INPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- int inputSource = data.readInt32();
+ audio_source_t inputSource = (audio_source_t) data.readInt32();
uint32_t samplingRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
uint32_t channels = data.readInt32();
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index d2f5f71b572d..27c7e03b0cd1 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -59,9 +59,10 @@ public:
: BpInterface<IOMX>(impl) {
}
- virtual bool livesLocally(pid_t pid) {
+ virtual bool livesLocally(node_id node, pid_t pid) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+ data.writeIntPtr((intptr_t)node);
data.writeInt32(pid);
remote()->transact(LIVES_LOCALLY, data, &reply);
@@ -417,7 +418,9 @@ status_t BnOMX::onTransact(
case LIVES_LOCALLY:
{
CHECK_INTERFACE(IOMX, data, reply);
- reply->writeInt32(livesLocally((pid_t)data.readInt32()));
+ node_id node = (void *)data.readIntPtr();
+ pid_t pid = (pid_t)data.readInt32();
+ reply->writeInt32(livesLocally(node, pid));
return OK;
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 0aeb515d0181..03e8a0611cd6 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -74,12 +74,10 @@ LOCAL_SHARED_LIBRARIES := \
libcrypto \
libssl \
libgui \
+ libstagefright_omx \
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
- libstagefright_aacenc \
- libstagefright_amrnbenc \
- libstagefright_amrwbenc \
libstagefright_avcenc \
libstagefright_m4vh263enc \
libstagefright_matroska \
@@ -141,7 +139,6 @@ endif # ifeq ($(HTTP_STACK),chrome)
################################################################################
LOCAL_SHARED_LIBRARIES += \
- libstagefright_amrnb_common \
libstagefright_enc_common \
libstagefright_avc_common \
libstagefright_foundation \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 2172cc0d9d41..8bdb7c589d23 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -47,7 +47,7 @@ static void AudioRecordCallbackFunction(int event, void *user, void *info) {
}
AudioSource::AudioSource(
- int inputSource, uint32_t sampleRate, uint32_t channels)
+ audio_source_t inputSource, uint32_t sampleRate, uint32_t channels)
: mStarted(false),
mSampleRate(sampleRate),
mPrevSampleTimeUs(0),
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 8480b6d7466f..8073af88ce76 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -30,7 +30,7 @@
#include "include/MPEG2TSExtractor.h"
#include "include/WVMExtractor.h"
-#include "timedtext/TimedTextPlayer.h"
+#include "timedtext/TimedTextDriver.h"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -192,7 +192,7 @@ AwesomePlayer::AwesomePlayer()
mVideoBuffer(NULL),
mDecryptHandle(NULL),
mLastVideoTimeUs(-1),
- mTextPlayer(NULL) {
+ mTextDriver(NULL) {
CHECK_EQ(mClient.connect(), (status_t)OK);
DataSource::RegisterDefaultSniffers();
@@ -530,9 +530,9 @@ void AwesomePlayer::reset_l() {
delete mAudioPlayer;
mAudioPlayer = NULL;
- if (mTextPlayer != NULL) {
- delete mTextPlayer;
- mTextPlayer = NULL;
+ if (mTextDriver != NULL) {
+ delete mTextDriver;
+ mTextDriver = NULL;
}
mVideoRenderer.clear();
@@ -1118,7 +1118,7 @@ status_t AwesomePlayer::pause_l(bool at_eos) {
}
if (mFlags & TEXTPLAYER_STARTED) {
- mTextPlayer->pause();
+ mTextDriver->pause();
modifyFlags(TEXT_RUNNING, CLEAR);
}
@@ -1272,9 +1272,9 @@ status_t AwesomePlayer::seekTo(int64_t timeUs) {
}
status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
- if (mTextPlayer != NULL) {
+ if (mTextDriver != NULL) {
if (index >= 0) { // to turn on a text track
- status_t err = mTextPlayer->setTimedTextTrackIndex(index);
+ status_t err = mTextDriver->setTimedTextTrackIndex(index);
if (err != OK) {
return err;
}
@@ -1290,7 +1290,7 @@ status_t AwesomePlayer::setTimedTextTrackIndex(int32_t index) {
modifyFlags(TEXTPLAYER_STARTED, CLEAR);
}
- return mTextPlayer->setTimedTextTrackIndex(index);
+ return mTextDriver->setTimedTextTrackIndex(index);
}
} else {
return INVALID_OPERATION;
@@ -1319,7 +1319,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
seekAudioIfNecessary_l();
if (mFlags & TEXTPLAYER_STARTED) {
- mTextPlayer->seekTo(mSeekTimeUs);
+ mTextDriver->seekToAsync(mSeekTimeUs);
}
if (!(mFlags & PLAYING)) {
@@ -1364,11 +1364,11 @@ void AwesomePlayer::addTextSource(sp<MediaSource> source) {
Mutex::Autolock autoLock(mTimedTextLock);
CHECK(source != NULL);
- if (mTextPlayer == NULL) {
- mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
+ if (mTextDriver == NULL) {
+ mTextDriver = new TimedTextDriver(mListener);
}
- mTextPlayer->addTextSource(source);
+ mTextDriver->addInBandTextSource(source);
}
status_t AwesomePlayer::initAudioDecoder() {
@@ -1695,7 +1695,7 @@ void AwesomePlayer::onVideoEvent() {
}
if ((mFlags & TEXTPLAYER_STARTED) && !(mFlags & (TEXT_RUNNING | SEEK_PREVIEW))) {
- mTextPlayer->resume();
+ mTextDriver->resume();
modifyFlags(TEXT_RUNNING, SET);
}
@@ -2241,11 +2241,11 @@ status_t AwesomePlayer::setParameter(int key, const Parcel &request) {
case KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE:
{
Mutex::Autolock autoLock(mTimedTextLock);
- if (mTextPlayer == NULL) {
- mTextPlayer = new TimedTextPlayer(this, mListener, &mQueue);
+ if (mTextDriver == NULL) {
+ mTextDriver = new TimedTextDriver(mListener);
}
- return mTextPlayer->setParameter(key, request);
+ return mTextDriver->addOutOfBandTextSource(request);
}
case KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS:
{
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index bc8801514346..6c95d4e5d351 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -20,7 +20,6 @@
#include "include/MPEG4Extractor.h"
#include "include/SampleTable.h"
#include "include/ESDS.h"
-#include "timedtext/TimedTextPlayer.h"
#include <arpa/inet.h>
@@ -2430,4 +2429,3 @@ bool SniffMPEG4(
}
} // namespace android
-
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 9de873eceed5..7a805aa73afc 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -20,11 +20,299 @@
#include <binder/IServiceManager.h>
#include <media/IMediaPlayerService.h>
-#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/OMXClient.h>
+#include <utils/KeyedVector.h>
+
+#include "include/OMX.h"
namespace android {
+struct MuxOMX : public IOMX {
+ MuxOMX(const sp<IOMX> &remoteOMX);
+ virtual ~MuxOMX();
+
+ virtual IBinder *onAsBinder() { return NULL; }
+
+ virtual bool livesLocally(node_id node, pid_t pid);
+
+ virtual status_t listNodes(List<ComponentInfo> *list);
+
+ virtual status_t allocateNode(
+ const char *name, const sp<IOMXObserver> &observer,
+ node_id *node);
+
+ virtual status_t freeNode(node_id node);
+
+ virtual status_t sendCommand(
+ node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param);
+
+ virtual status_t getParameter(
+ node_id node, OMX_INDEXTYPE index,
+ void *params, size_t size);
+
+ virtual status_t setParameter(
+ node_id node, OMX_INDEXTYPE index,
+ const void *params, size_t size);
+
+ virtual status_t getConfig(
+ node_id node, OMX_INDEXTYPE index,
+ void *params, size_t size);
+
+ virtual status_t setConfig(
+ node_id node, OMX_INDEXTYPE index,
+ const void *params, size_t size);
+
+ virtual status_t getState(
+ node_id node, OMX_STATETYPE* state);
+
+ virtual status_t storeMetaDataInBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL enable);
+
+ virtual status_t enableGraphicBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL enable);
+
+ virtual status_t getGraphicBufferUsage(
+ node_id node, OMX_U32 port_index, OMX_U32* usage);
+
+ virtual status_t useBuffer(
+ node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+ buffer_id *buffer);
+
+ virtual status_t useGraphicBuffer(
+ node_id node, OMX_U32 port_index,
+ const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer);
+
+ virtual status_t allocateBuffer(
+ node_id node, OMX_U32 port_index, size_t size,
+ buffer_id *buffer, void **buffer_data);
+
+ virtual status_t allocateBufferWithBackup(
+ node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+ buffer_id *buffer);
+
+ virtual status_t freeBuffer(
+ node_id node, OMX_U32 port_index, buffer_id buffer);
+
+ virtual status_t fillBuffer(node_id node, buffer_id buffer);
+
+ virtual status_t emptyBuffer(
+ node_id node,
+ buffer_id buffer,
+ OMX_U32 range_offset, OMX_U32 range_length,
+ OMX_U32 flags, OMX_TICKS timestamp);
+
+ virtual status_t getExtensionIndex(
+ node_id node,
+ const char *parameter_name,
+ OMX_INDEXTYPE *index);
+
+private:
+ mutable Mutex mLock;
+
+ sp<IOMX> mRemoteOMX;
+ sp<IOMX> mLocalOMX;
+
+ KeyedVector<node_id, bool> mIsLocalNode;
+
+ bool isLocalNode(node_id node) const;
+ bool isLocalNode_l(node_id node) const;
+ const sp<IOMX> &getOMX(node_id node) const;
+ const sp<IOMX> &getOMX_l(node_id node) const;
+
+ static bool IsSoftwareComponent(const char *name);
+
+ DISALLOW_EVIL_CONSTRUCTORS(MuxOMX);
+};
+
+MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX)
+ : mRemoteOMX(remoteOMX) {
+}
+
+MuxOMX::~MuxOMX() {
+}
+
+bool MuxOMX::isLocalNode(node_id node) const {
+ Mutex::Autolock autoLock(mLock);
+
+ return isLocalNode_l(node);
+}
+
+bool MuxOMX::isLocalNode_l(node_id node) const {
+ return mIsLocalNode.indexOfKey(node) >= 0;
+}
+
+// static
+bool MuxOMX::IsSoftwareComponent(const char *name) {
+ return !strncasecmp(name, "OMX.google.", 11);
+}
+
+const sp<IOMX> &MuxOMX::getOMX(node_id node) const {
+ return isLocalNode(node) ? mLocalOMX : mRemoteOMX;
+}
+
+const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const {
+ return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX;
+}
+
+bool MuxOMX::livesLocally(node_id node, pid_t pid) {
+ return getOMX(node)->livesLocally(node, pid);
+}
+
+status_t MuxOMX::listNodes(List<ComponentInfo> *list) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mLocalOMX == NULL) {
+ mLocalOMX = new OMX;
+ }
+
+ return mLocalOMX->listNodes(list);
+}
+
+status_t MuxOMX::allocateNode(
+ const char *name, const sp<IOMXObserver> &observer,
+ node_id *node) {
+ Mutex::Autolock autoLock(mLock);
+
+ sp<IOMX> omx;
+
+ if (IsSoftwareComponent(name)) {
+ if (mLocalOMX == NULL) {
+ mLocalOMX = new OMX;
+ }
+ omx = mLocalOMX;
+ } else {
+ omx = mRemoteOMX;
+ }
+
+ status_t err = omx->allocateNode(name, observer, node);
+
+ if (err != OK) {
+ return err;
+ }
+
+ if (omx == mLocalOMX) {
+ mIsLocalNode.add(*node, true);
+ }
+
+ return OK;
+}
+
+status_t MuxOMX::freeNode(node_id node) {
+ Mutex::Autolock autoLock(mLock);
+
+ status_t err = getOMX_l(node)->freeNode(node);
+
+ if (err != OK) {
+ return err;
+ }
+
+ mIsLocalNode.removeItem(node);
+
+ return OK;
+}
+
+status_t MuxOMX::sendCommand(
+ node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
+ return getOMX(node)->sendCommand(node, cmd, param);
+}
+
+status_t MuxOMX::getParameter(
+ node_id node, OMX_INDEXTYPE index,
+ void *params, size_t size) {
+ return getOMX(node)->getParameter(node, index, params, size);
+}
+
+status_t MuxOMX::setParameter(
+ node_id node, OMX_INDEXTYPE index,
+ const void *params, size_t size) {
+ return getOMX(node)->setParameter(node, index, params, size);
+}
+
+status_t MuxOMX::getConfig(
+ node_id node, OMX_INDEXTYPE index,
+ void *params, size_t size) {
+ return getOMX(node)->getConfig(node, index, params, size);
+}
+
+status_t MuxOMX::setConfig(
+ node_id node, OMX_INDEXTYPE index,
+ const void *params, size_t size) {
+ return getOMX(node)->setConfig(node, index, params, size);
+}
+
+status_t MuxOMX::getState(
+ node_id node, OMX_STATETYPE* state) {
+ return getOMX(node)->getState(node, state);
+}
+
+status_t MuxOMX::storeMetaDataInBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+ return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable);
+}
+
+status_t MuxOMX::enableGraphicBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+ return getOMX(node)->enableGraphicBuffers(node, port_index, enable);
+}
+
+status_t MuxOMX::getGraphicBufferUsage(
+ node_id node, OMX_U32 port_index, OMX_U32* usage) {
+ return getOMX(node)->getGraphicBufferUsage(node, port_index, usage);
+}
+
+status_t MuxOMX::useBuffer(
+ node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+ buffer_id *buffer) {
+ return getOMX(node)->useBuffer(node, port_index, params, buffer);
+}
+
+status_t MuxOMX::useGraphicBuffer(
+ node_id node, OMX_U32 port_index,
+ const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
+ return getOMX(node)->useGraphicBuffer(
+ node, port_index, graphicBuffer, buffer);
+}
+
+status_t MuxOMX::allocateBuffer(
+ node_id node, OMX_U32 port_index, size_t size,
+ buffer_id *buffer, void **buffer_data) {
+ return getOMX(node)->allocateBuffer(
+ node, port_index, size, buffer, buffer_data);
+}
+
+status_t MuxOMX::allocateBufferWithBackup(
+ node_id node, OMX_U32 port_index, const sp<IMemory> &params,
+ buffer_id *buffer) {
+ return getOMX(node)->allocateBufferWithBackup(
+ node, port_index, params, buffer);
+}
+
+status_t MuxOMX::freeBuffer(
+ node_id node, OMX_U32 port_index, buffer_id buffer) {
+ return getOMX(node)->freeBuffer(node, port_index, buffer);
+}
+
+status_t MuxOMX::fillBuffer(node_id node, buffer_id buffer) {
+ return getOMX(node)->fillBuffer(node, buffer);
+}
+
+status_t MuxOMX::emptyBuffer(
+ node_id node,
+ buffer_id buffer,
+ OMX_U32 range_offset, OMX_U32 range_length,
+ OMX_U32 flags, OMX_TICKS timestamp) {
+ return getOMX(node)->emptyBuffer(
+ node, buffer, range_offset, range_length, flags, timestamp);
+}
+
+status_t MuxOMX::getExtensionIndex(
+ node_id node,
+ const char *parameter_name,
+ OMX_INDEXTYPE *index) {
+ return getOMX(node)->getExtensionIndex(node, parameter_name, index);
+}
+
OMXClient::OMXClient() {
}
@@ -38,6 +326,11 @@ status_t OMXClient::connect() {
mOMX = service->getOMX();
CHECK(mOMX.get() != NULL);
+ if (!mOMX->livesLocally(NULL /* node */, getpid())) {
+ ALOGI("Using client-side OMX mux.");
+ mOMX = new MuxOMX(mOMX);
+ }
+
return OK;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 60d9bb727800..af4aa797fb70 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -18,9 +18,6 @@
#define LOG_TAG "OMXCodec"
#include <utils/Log.h>
-#include "include/AACEncoder.h"
-#include "include/AMRNBEncoder.h"
-#include "include/AMRWBEncoder.h"
#include "include/AVCEncoder.h"
#include "include/M4vH263Encoder.h"
@@ -71,9 +68,6 @@ static sp<MediaSource> Make##name(const sp<MediaSource> &source, const sp<MetaDa
#define FACTORY_REF(name) { #name, Make##name },
-FACTORY_CREATE_ENCODER(AMRNBEncoder)
-FACTORY_CREATE_ENCODER(AMRWBEncoder)
-FACTORY_CREATE_ENCODER(AACEncoder)
FACTORY_CREATE_ENCODER(AVCEncoder)
FACTORY_CREATE_ENCODER(M4vH263Encoder)
@@ -86,9 +80,6 @@ static sp<MediaSource> InstantiateSoftwareEncoder(
};
static const FactoryInfo kFactoryInfo[] = {
- FACTORY_REF(AMRNBEncoder)
- FACTORY_REF(AMRWBEncoder)
- FACTORY_REF(AACEncoder)
FACTORY_REF(AVCEncoder)
FACTORY_REF(M4vH263Encoder)
};
@@ -149,11 +140,11 @@ static const CodecInfo kDecoderInfo[] = {
static const CodecInfo kEncoderInfo[] = {
{ MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
- { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBEncoder" },
+ { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.google.amrnb.encoder" },
{ MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
- { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" },
+ { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.google.amrwb.encoder" },
{ MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
- { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" },
+ { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.google.aac.encoder" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.DUCATI1.VIDEO.MPEG4E" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
@@ -1482,11 +1473,12 @@ OMXCodec::OMXCodec(
const sp<MediaSource> &source,
const sp<ANativeWindow> &nativeWindow)
: mOMX(omx),
- mOMXLivesLocally(omx->livesLocally(getpid())),
+ mOMXLivesLocally(omx->livesLocally(node, getpid())),
mNode(node),
mQuirks(quirks),
mFlags(flags),
mIsEncoder(isEncoder),
+ mIsVideo(!strncasecmp("video/", mime, 6)),
mMIME(strdup(mime)),
mComponentName(strdup(componentName)),
mSource(source),
@@ -2192,7 +2184,7 @@ error:
}
int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) {
- CHECK(mIsEncoder);
+ CHECK(mIsEncoder && mIsVideo);
if (mDecodingTimeList.empty()) {
CHECK(mSignalledEOS || mNoMoreOutputData);
@@ -2387,7 +2379,7 @@ void OMXCodec::on_message(const omx_message &msg) {
mNoMoreOutputData = true;
}
- if (mIsEncoder) {
+ if (mIsEncoder && mIsVideo) {
int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific);
buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
}
@@ -3249,7 +3241,7 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
int64_t lastBufferTimeUs;
CHECK(srcBuffer->meta_data()->findInt64(kKeyTime, &lastBufferTimeUs));
CHECK(lastBufferTimeUs >= 0);
- if (mIsEncoder) {
+ if (mIsEncoder && mIsVideo) {
mDecodingTimeList.push_back(lastBufferTimeUs);
}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC.cpp b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
index da9d28067793..ea6c3608bbf6 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
@@ -218,6 +218,18 @@ OMX_ERRORTYPE SoftAAC::internalSetParameter(
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioPcm:
+ {
+ const OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
default:
return SimpleSoftOMXComponent::internalSetParameter(index, params);
}
diff --git a/media/libstagefright/codecs/aacenc/Android.mk b/media/libstagefright/codecs/aacenc/Android.mk
index 8318ba4479fb..34a27967ec87 100644
--- a/media/libstagefright/codecs/aacenc/Android.mk
+++ b/media/libstagefright/codecs/aacenc/Android.mk
@@ -85,3 +85,29 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
endif
include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftAACEncoder.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+ frameworks/base/media/libstagefright/codecs/common/include \
+
+LOCAL_CFLAGS := -DOSCL_IMPORT_REF=
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_aacenc
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_omx libstagefright_foundation libutils \
+ libstagefright_enc_common
+
+LOCAL_MODULE := libstagefright_soft_aacenc
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp
new file mode 100644
index 000000000000..c6724c260d56
--- /dev/null
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder.cpp
@@ -0,0 +1,560 @@
+/*
+ * 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 "SoftAACEncoder"
+#include <utils/Log.h>
+
+#include "SoftAACEncoder.h"
+
+#include "voAAC.h"
+#include "cmnMemory.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftAACEncoder::SoftAACEncoder(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mEncoderHandle(NULL),
+ mApiHandle(NULL),
+ mMemOperator(NULL),
+ mNumChannels(1),
+ mSampleRate(44100),
+ mBitRate(0),
+ mSentCodecSpecificData(false),
+ mInputSize(0),
+ mInputFrame(NULL),
+ mInputTimeUs(-1ll),
+ mSawInputEOS(false),
+ mSignalledError(false) {
+ initPorts();
+ CHECK_EQ(initEncoder(), (status_t)OK);
+
+ setAudioParams();
+}
+
+SoftAACEncoder::~SoftAACEncoder() {
+ delete[] mInputFrame;
+ mInputFrame = NULL;
+
+ if (mEncoderHandle) {
+ CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
+ mEncoderHandle = NULL;
+ }
+
+ delete mApiHandle;
+ mApiHandle = NULL;
+
+ delete mMemOperator;
+ mMemOperator = NULL;
+}
+
+void SoftAACEncoder::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t) * 2;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/aac");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+
+ addPort(def);
+}
+
+status_t SoftAACEncoder::initEncoder() {
+ mApiHandle = new VO_AUDIO_CODECAPI;
+
+ if (VO_ERR_NONE != voGetAACEncAPI(mApiHandle)) {
+ ALOGE("Failed to get api handle");
+ return UNKNOWN_ERROR;
+ }
+
+ mMemOperator = new VO_MEM_OPERATOR;
+ mMemOperator->Alloc = cmnMemAlloc;
+ mMemOperator->Copy = cmnMemCopy;
+ mMemOperator->Free = cmnMemFree;
+ mMemOperator->Set = cmnMemSet;
+ mMemOperator->Check = cmnMemCheck;
+
+ VO_CODEC_INIT_USERDATA userData;
+ memset(&userData, 0, sizeof(userData));
+ userData.memflag = VO_IMF_USERMEMOPERATOR;
+ userData.memData = (VO_PTR) mMemOperator;
+ if (VO_ERR_NONE !=
+ mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAAC, &userData)) {
+ ALOGE("Failed to init AAC encoder");
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+OMX_ERRORTYPE SoftAACEncoder::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAAC;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
+ (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
+
+ if (aacParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ aacParams->nBitRate = mBitRate;
+ aacParams->nAudioBandWidth = 0;
+ aacParams->nAACtools = 0;
+ aacParams->nAACERtools = 0;
+ aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
+ aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
+ aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
+
+ aacParams->nChannels = mNumChannels;
+ aacParams->nSampleRate = mSampleRate;
+ aacParams->nFrameLength = 0;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+
+ pcmParams->nChannels = mNumChannels;
+ pcmParams->nSamplingRate = mSampleRate;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAACEncoder::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_encoder.aac",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingAAC)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE *aacParams =
+ (OMX_AUDIO_PARAM_AACPROFILETYPE *)params;
+
+ if (aacParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ mBitRate = aacParams->nBitRate;
+ mNumChannels = aacParams->nChannels;
+ mSampleRate = aacParams->nSampleRate;
+
+ if (setAudioParams() != OK) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ mNumChannels = pcmParams->nChannels;
+ mSampleRate = pcmParams->nSamplingRate;
+
+ if (setAudioParams() != OK) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+status_t SoftAACEncoder::setAudioParams() {
+ // We call this whenever sample rate, number of channels or bitrate change
+ // in reponse to setParameter calls.
+
+ ALOGV("setAudioParams: %lu Hz, %lu channels, %lu bps",
+ mSampleRate, mNumChannels, mBitRate);
+
+ status_t err = setAudioSpecificConfigData();
+
+ if (err != OK) {
+ return err;
+ }
+
+ AACENC_PARAM params;
+ memset(&params, 0, sizeof(params));
+ params.sampleRate = mSampleRate;
+ params.bitRate = mBitRate;
+ params.nChannels = mNumChannels;
+ params.adtsUsed = 0; // We add adts header in the file writer if needed.
+ if (VO_ERR_NONE != mApiHandle->SetParam(
+ mEncoderHandle, VO_PID_AAC_ENCPARAM, &params)) {
+ ALOGE("Failed to set AAC encoder parameters");
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+static status_t getSampleRateTableIndex(int32_t sampleRate, int32_t &index) {
+ static const int32_t kSampleRateTable[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000
+ };
+ const int32_t tableSize =
+ sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
+
+ for (int32_t i = 0; i < tableSize; ++i) {
+ if (sampleRate == kSampleRateTable[i]) {
+ index = i;
+ return OK;
+ }
+ }
+
+ return UNKNOWN_ERROR;
+}
+
+status_t SoftAACEncoder::setAudioSpecificConfigData() {
+ // The AAC encoder's audio specific config really only encodes
+ // number of channels and the sample rate (mapped to an index into
+ // a fixed sample rate table).
+
+ int32_t index;
+ status_t err = getSampleRateTableIndex(mSampleRate, index);
+ if (err != OK) {
+ ALOGE("Unsupported sample rate (%lu Hz)", mSampleRate);
+ return err;
+ }
+
+ if (mNumChannels > 2 || mNumChannels <= 0) {
+ ALOGE("Unsupported number of channels(%lu)", mNumChannels);
+ return UNKNOWN_ERROR;
+ }
+
+ // OMX_AUDIO_AACObjectLC
+ mAudioSpecificConfigData[0] = ((0x02 << 3) | (index >> 1));
+ mAudioSpecificConfigData[1] = ((index & 0x01) << 7) | (mNumChannels << 3);
+
+ return OK;
+}
+
+void SoftAACEncoder::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ if (!mSentCodecSpecificData) {
+ // The very first thing we want to output is the codec specific
+ // data. It does not require any input data but we will need an
+ // output buffer to store it in.
+
+ if (outQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ outHeader->nFilledLen = sizeof(mAudioSpecificConfigData);
+ outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
+
+ uint8_t *out = outHeader->pBuffer + outHeader->nOffset;
+ memcpy(out, mAudioSpecificConfigData, sizeof(mAudioSpecificConfigData));
+
+#if 0
+ ALOGI("sending codec specific data.");
+ hexdump(out, sizeof(mAudioSpecificConfigData));
+#endif
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+
+ mSentCodecSpecificData = true;
+ }
+
+ size_t numBytesPerInputFrame =
+ mNumChannels * kNumSamplesPerFrame * sizeof(int16_t);
+
+ for (;;) {
+ // We do the following until we run out of buffers.
+
+ while (mInputSize < numBytesPerInputFrame) {
+ // As long as there's still input data to be read we
+ // will drain "kNumSamplesPerFrame * mNumChannels" samples
+ // into the "mInputFrame" buffer and then encode those
+ // as a unit into an output buffer.
+
+ if (mSawInputEOS || inQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ const void *inData = inHeader->pBuffer + inHeader->nOffset;
+
+ size_t copy = numBytesPerInputFrame - mInputSize;
+ if (copy > inHeader->nFilledLen) {
+ copy = inHeader->nFilledLen;
+ }
+
+ if (mInputFrame == NULL) {
+ mInputFrame = new int16_t[kNumSamplesPerFrame * mNumChannels];
+ }
+
+ if (mInputSize == 0) {
+ mInputTimeUs = inHeader->nTimeStamp;
+ }
+
+ memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy);
+ mInputSize += copy;
+
+ inHeader->nOffset += copy;
+ inHeader->nFilledLen -= copy;
+
+ // "Time" on the input buffer has in effect advanced by the
+ // number of audio frames we just advanced nOffset by.
+ inHeader->nTimeStamp +=
+ (copy * 1000000ll / mSampleRate)
+ / (mNumChannels * sizeof(int16_t));
+
+ if (inHeader->nFilledLen == 0) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ ALOGV("saw input EOS");
+ mSawInputEOS = true;
+
+ // Pad any remaining data with zeroes.
+ memset((uint8_t *)mInputFrame + mInputSize,
+ 0,
+ numBytesPerInputFrame - mInputSize);
+
+ mInputSize = numBytesPerInputFrame;
+ }
+
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ inData = NULL;
+ inHeader = NULL;
+ inInfo = NULL;
+ }
+ }
+
+ // At this point we have all the input data necessary to encode
+ // a single frame, all we need is an output buffer to store the result
+ // in.
+
+ if (outQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ VO_CODECBUFFER inputData;
+ memset(&inputData, 0, sizeof(inputData));
+ inputData.Buffer = (unsigned char *)mInputFrame;
+ inputData.Length = numBytesPerInputFrame;
+ CHECK(VO_ERR_NONE ==
+ mApiHandle->SetInputData(mEncoderHandle, &inputData));
+
+ VO_CODECBUFFER outputData;
+ memset(&outputData, 0, sizeof(outputData));
+ VO_AUDIO_OUTPUTINFO outputInfo;
+ memset(&outputInfo, 0, sizeof(outputInfo));
+
+ uint8_t *outPtr = (uint8_t *)outHeader->pBuffer + outHeader->nOffset;
+ size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset;
+
+ VO_U32 ret = VO_ERR_NONE;
+ size_t nOutputBytes = 0;
+ do {
+ outputData.Buffer = outPtr;
+ outputData.Length = outAvailable - nOutputBytes;
+ ret = mApiHandle->GetOutputData(
+ mEncoderHandle, &outputData, &outputInfo);
+ if (ret == VO_ERR_NONE) {
+ outPtr += outputData.Length;
+ nOutputBytes += outputData.Length;
+ }
+ } while (ret != VO_ERR_INPUT_BUFFER_SMALL);
+
+ outHeader->nFilledLen = nOutputBytes;
+
+ outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
+
+ if (mSawInputEOS) {
+ // We also tag this output buffer with EOS if it corresponds
+ // to the final input buffer.
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ }
+
+ outHeader->nTimeStamp = mInputTimeUs;
+
+#if 0
+ ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)",
+ nOutputBytes, mInputTimeUs, outHeader->nFlags);
+
+ hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen);
+#endif
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+
+ outHeader = NULL;
+ outInfo = NULL;
+
+ mInputSize = 0;
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftAACEncoder(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder.h b/media/libstagefright/codecs/aacenc/SoftAACEncoder.h
new file mode 100644
index 000000000000..d148eb7630f2
--- /dev/null
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SOFT_AAC_ENCODER_H_
+
+#define SOFT_AAC_ENCODER_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+struct VO_AUDIO_CODECAPI;
+struct VO_MEM_OPERATOR;
+
+namespace android {
+
+struct SoftAACEncoder : public SimpleSoftOMXComponent {
+ SoftAACEncoder(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftAACEncoder();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kNumSamplesPerFrame = 1024,
+ };
+
+ void *mEncoderHandle;
+ VO_AUDIO_CODECAPI *mApiHandle;
+ VO_MEM_OPERATOR *mMemOperator;
+
+ OMX_U32 mNumChannels;
+ OMX_U32 mSampleRate;
+ OMX_U32 mBitRate;
+
+ bool mSentCodecSpecificData;
+ size_t mInputSize;
+ int16_t *mInputFrame;
+ int64_t mInputTimeUs;
+
+ bool mSawInputEOS;
+
+ uint8_t mAudioSpecificConfigData[2];
+
+ bool mSignalledError;
+
+ void initPorts();
+ status_t initEncoder();
+
+ status_t setAudioSpecificConfigData();
+ status_t setAudioParams();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftAACEncoder);
+};
+
+} // namespace android
+
+#endif // SOFT_AAC_ENCODER_H_
diff --git a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
index e48af9d51f77..982f4fd44e6d 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
+++ b/media/libstagefright/codecs/aacenc/basic_op/oper_32b.c
@@ -358,4 +358,4 @@ Word32 pow2_xy(Word32 x, Word32 y)
res = pow2Table[(POW2_TABLE_SIZE*fPart)/y] >> iPart;
return(res);
-} \ No newline at end of file
+}
diff --git a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
index c924e2c2b165..2d5d9567f2db 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
@@ -77,12 +77,12 @@ typedef unsigned short UWord16;
/*
********* define 32 bit signed/unsigned types & constants
*/
-typedef long Word32;
-typedef unsigned long UWord32;
+typedef int Word32;
+typedef unsigned int UWord32;
-#ifdef LINUX
+#ifndef _MSC_VER
typedef long long Word64;
typedef unsigned long long UWord64;
#else
diff --git a/media/libstagefright/codecs/aacenc/inc/config.h b/media/libstagefright/codecs/aacenc/inc/config.h
index 3b29cefd8c65..b0b4c26f8aea 100644
--- a/media/libstagefright/codecs/aacenc/inc/config.h
+++ b/media/libstagefright/codecs/aacenc/inc/config.h
@@ -33,4 +33,4 @@
#define MINBITS_COEF 744
-#endif \ No newline at end of file
+#endif
diff --git a/media/libstagefright/codecs/aacenc/inc/sf_estim.h b/media/libstagefright/codecs/aacenc/inc/sf_estim.h
index 9039f25481e0..997eba5b828b 100644
--- a/media/libstagefright/codecs/aacenc/inc/sf_estim.h
+++ b/media/libstagefright/codecs/aacenc/inc/sf_estim.h
@@ -43,4 +43,4 @@ EstimateScaleFactors(PSY_OUT_CHANNEL psyOutChannel[MAX_CHANNELS],
Word16 logSfbFormFactor[MAX_CHANNELS][MAX_GROUPED_SFB],
Word16 sfbNRelevantLines[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels);
-#endif \ No newline at end of file
+#endif
diff --git a/media/libstagefright/codecs/aacenc/inc/transform.h b/media/libstagefright/codecs/aacenc/inc/transform.h
index fbac7aa68796..311cef5e1da0 100644
--- a/media/libstagefright/codecs/aacenc/inc/transform.h
+++ b/media/libstagefright/codecs/aacenc/inc/transform.h
@@ -33,4 +33,4 @@ void Transform_Real(Word16 *mdctDelayBuffer,
Word16 windowSequence
);
-#endif \ No newline at end of file
+#endif
diff --git a/media/libstagefright/codecs/aacenc/src/aac_rom.c b/media/libstagefright/codecs/aacenc/src/aac_rom.c
index 08792e842b56..127322d2ad1a 100644
--- a/media/libstagefright/codecs/aacenc/src/aac_rom.c
+++ b/media/libstagefright/codecs/aacenc/src/aac_rom.c
@@ -2360,4 +2360,4 @@ const unsigned char bitrevTab[17 + 129] =
0x4d, 0x59, 0x4f, 0x79, 0x53, 0x65, 0x57, 0x75, 0x5b, 0x6d, 0x5f, 0x7d, 0x67, 0x73, 0x6f, 0x7b,
0x00, 0x08, 0x14, 0x1c, 0x22, 0x2a, 0x36, 0x3e, 0x41, 0x49, 0x55, 0x5d, 0x63, 0x6b, 0x77, 0x7f,
0x00,
-}; \ No newline at end of file
+};
diff --git a/media/libstagefright/codecs/aacenc/src/aacenc.c b/media/libstagefright/codecs/aacenc/src/aacenc.c
index b5e8a9c5ba8a..ad2f29a55a1f 100644
--- a/media/libstagefright/codecs/aacenc/src/aacenc.c
+++ b/media/libstagefright/codecs/aacenc/src/aacenc.c
@@ -492,4 +492,4 @@ VO_S32 VO_API voGetAACEncAPI(VO_AUDIO_CODECAPI * pDecHandle)
pDecHandle->Uninit = voAACEncUninit;
return VO_ERR_NONE;
-} \ No newline at end of file
+}
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index c656f65b8a5b..a8ab809f3f60 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -1039,7 +1039,7 @@ void AdjThrInit(ADJ_THR_STATE *hAdjThr,
/* minSnr adaptation */
/* maximum reduction of minSnr goes down to minSnr^maxRed */
- msaParam->maxRed = 0x20000000; /* *0.25f /
+ msaParam->maxRed = 0x20000000; /* *0.25f */
/* start adaptation of minSnr for avgEn/sfbEn > startRatio */
msaParam->startRatio = 0x0ccccccd; /* 10 */
/* maximum minSnr reduction to minSnr^maxRed is reached for
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s
index 103cc91814ad..da21d5faf0c2 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/PrePostMDCT_v5.s
@@ -128,4 +128,4 @@ PostMDCT_LOOP:
PostMDCT_END:
ldmia sp!, {r4 - r11, pc}
@ENDP @ |PostMDCT|
- .end \ No newline at end of file
+ .end
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s
index 72cb9a3ca907..4ca4f31108cf 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/R4R8First_v5.s
@@ -249,4 +249,4 @@ DATATab:
.word 0x5a82799a
@ENDP @ |Radix8First|
- .end \ No newline at end of file
+ .end
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s
index e81c82eaf790..b59b967ad9fa 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV5E/Radix4FFT_v5.s
@@ -166,4 +166,4 @@ Radix4FFT_END:
ldmia sp!, {r4 - r11, pc}
@ENDP @ |Radix4FFT|
- .end \ No newline at end of file
+ .end
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s
index 64d767a5c3e6..7f6b8813456e 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/PrePostMDCT_v7.s
@@ -23,9 +23,13 @@
.section .text
.global PreMDCT
+ .fnstart
PreMDCT:
stmdb sp!, {r4 - r11, lr}
+ .save {r4 - r11, lr}
+ fstmfdd sp!, {d8 - d15}
+ .vsave {d8 - d15}
add r9, r0, r1, lsl #2
sub r3, r9, #32
@@ -74,14 +78,20 @@ PreMDCT_LOOP:
bne PreMDCT_LOOP
PreMDCT_END:
+ fldmfdd sp!, {d8 - d15}
ldmia sp!, {r4 - r11, pc}
@ENDP @ |PreMDCT|
+ .fnend
.section .text
.global PostMDCT
+ .fnstart
PostMDCT:
stmdb sp!, {r4 - r11, lr}
+ .save {r4 - r11, lr}
+ fstmfdd sp!, {d8 - d15}
+ .vsave {d8 - d15}
add r9, r0, r1, lsl #2
sub r3, r9, #32
@@ -129,7 +139,8 @@ PostMDCT_LOOP:
bne PostMDCT_LOOP
PostMDCT_END:
+ fldmfdd sp!, {d8 - d15}
ldmia sp!, {r4 - r11, pc}
@ENDP @ |PostMDCT|
- .end \ No newline at end of file
+ .fnend
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s
index 7fc55203978d..03fa6a987f6c 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/R4R8First_v7.s
@@ -23,9 +23,13 @@
.section .text
.global Radix8First
+ .fnstart
Radix8First:
stmdb sp!, {r4 - r11, lr}
+ .save {r4 - r11, lr}
+ fstmfdd sp!, {d8 - d15}
+ .vsave {d8 - d15}
ldr r3, SQRT1_2
cmp r1, #0
@@ -103,17 +107,23 @@ Radix8First_LOOP:
bne Radix8First_LOOP
Radix8First_END:
+ fldmfdd sp!, {d8 - d15}
ldmia sp!, {r4 - r11, pc}
SQRT1_2:
.word 0x2d413ccd
@ENDP @ |Radix8First|
+ .fnend
.section .text
.global Radix4First
+ .fnstart
Radix4First:
stmdb sp!, {r4 - r11, lr}
+ .save {r4 - r11, lr}
+ fstmfdd sp!, {d8 - d15}
+ .vsave {d8 - d15}
cmp r1, #0
beq Radix4First_END
@@ -140,7 +150,8 @@ Radix4First_LOOP:
bne Radix4First_LOOP
Radix4First_END:
+ fldmfdd sp!, {d8 - d15}
ldmia sp!, {r4 - r11, pc}
@ENDP @ |Radix4First|
- .end \ No newline at end of file
+ .fnend
diff --git a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s
index b8655aee2096..431bc30c9312 100644
--- a/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s
+++ b/media/libstagefright/codecs/aacenc/src/asm/ARMV7/Radix4FFT_v7.s
@@ -23,9 +23,13 @@
.section .text
.global Radix4FFT
+ .fnstart
Radix4FFT:
stmdb sp!, {r4 - r11, lr}
+ .save {r4 - r11, lr}
+ fstmfdd sp!, {d8 - d15}
+ .vsave {d8 - d15}
mov r1, r1, asr #2
cmp r1, #0
@@ -137,7 +141,8 @@ Radix4FFT_LOOP1_END:
bne Radix4FFT_LOOP1
Radix4FFT_END:
+ fldmfdd sp!, {d8 - d15}
ldmia sp!, {r4 - r11, pc}
@ENDP @ |Radix4FFT|
- .end \ No newline at end of file
+ .fnend
diff --git a/media/libstagefright/codecs/aacenc/src/band_nrg.c b/media/libstagefright/codecs/aacenc/src/band_nrg.c
index 7501af121927..e4034b8a4efd 100644
--- a/media/libstagefright/codecs/aacenc/src/band_nrg.c
+++ b/media/libstagefright/codecs/aacenc/src/band_nrg.c
@@ -99,4 +99,4 @@ void CalcBandEnergyMS(const Word32 *mdctSpectrumLeft,
*bandEnergySideSum = accuSideSum;
}
-#endif \ No newline at end of file
+#endif
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.mk b/media/libstagefright/codecs/amrnb/enc/Android.mk
index b6aed81f5263..94e87269b6d9 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.mk
+++ b/media/libstagefright/codecs/amrnb/enc/Android.mk
@@ -74,3 +74,30 @@ LOCAL_CFLAGS := \
LOCAL_MODULE := libstagefright_amrnbenc
include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftAMRNBEncoder.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+ $(LOCAL_PATH)/src \
+ $(LOCAL_PATH)/include \
+ $(LOCAL_PATH)/../common/include \
+ $(LOCAL_PATH)/../common
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrnbenc
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_omx libstagefright_foundation libutils \
+ libstagefright_amrnb_common
+
+LOCAL_MODULE := libstagefright_soft_amrnbenc
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
new file mode 100644
index 000000000000..07f8b4f8b93d
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -0,0 +1,404 @@
+/*
+ * 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 "SoftAMRNBEncoder"
+#include <utils/Log.h>
+
+#include "SoftAMRNBEncoder.h"
+
+#include "gsmamr_enc.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+namespace android {
+
+static const int32_t kSampleRate = 8000;
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftAMRNBEncoder::SoftAMRNBEncoder(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mEncState(NULL),
+ mSidState(NULL),
+ mBitRate(0),
+ mMode(MR475),
+ mInputSize(0),
+ mInputTimeUs(-1ll),
+ mSawInputEOS(false),
+ mSignalledError(false) {
+ initPorts();
+ CHECK_EQ(initEncoder(), (status_t)OK);
+}
+
+SoftAMRNBEncoder::~SoftAMRNBEncoder() {
+ if (mEncState != NULL) {
+ AMREncodeExit(&mEncState, &mSidState);
+ mEncState = mSidState = NULL;
+ }
+}
+
+void SoftAMRNBEncoder::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t);
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/3gpp");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAMR;
+
+ addPort(def);
+}
+
+status_t SoftAMRNBEncoder::initEncoder() {
+ if (AMREncodeInit(&mEncState, &mSidState, false /* dtx_enable */) != 0) {
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+OMX_ERRORTYPE SoftAMRNBEncoder::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAMR;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAmr:
+ {
+ OMX_AUDIO_PARAM_AMRTYPE *amrParams =
+ (OMX_AUDIO_PARAM_AMRTYPE *)params;
+
+ if (amrParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ amrParams->nChannels = 1;
+ amrParams->nBitRate = mBitRate;
+ amrParams->eAMRBandMode = (OMX_AUDIO_AMRBANDMODETYPE)(mMode + 1);
+ amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
+ amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelCF;
+
+ pcmParams->nChannels = 1;
+ pcmParams->nSamplingRate = kSampleRate;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_encoder.amrnb",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingAMR)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAmr:
+ {
+ OMX_AUDIO_PARAM_AMRTYPE *amrParams =
+ (OMX_AUDIO_PARAM_AMRTYPE *)params;
+
+ if (amrParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (amrParams->nChannels != 1
+ || amrParams->eAMRDTXMode != OMX_AUDIO_AMRDTXModeOff
+ || amrParams->eAMRFrameFormat
+ != OMX_AUDIO_AMRFrameFormatFSF
+ || amrParams->eAMRBandMode < OMX_AUDIO_AMRBandModeNB0
+ || amrParams->eAMRBandMode > OMX_AUDIO_AMRBandModeNB7) {
+ return OMX_ErrorUndefined;
+ }
+
+ mBitRate = amrParams->nBitRate;
+ mMode = amrParams->eAMRBandMode - 1;
+
+ amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
+ amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (pcmParams->nChannels != 1
+ || pcmParams->nSamplingRate != kSampleRate) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+void SoftAMRNBEncoder::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ size_t numBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
+
+ for (;;) {
+ // We do the following until we run out of buffers.
+
+ while (mInputSize < numBytesPerInputFrame) {
+ // As long as there's still input data to be read we
+ // will drain "kNumSamplesPerFrame" samples
+ // into the "mInputFrame" buffer and then encode those
+ // as a unit into an output buffer.
+
+ if (mSawInputEOS || inQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ const void *inData = inHeader->pBuffer + inHeader->nOffset;
+
+ size_t copy = numBytesPerInputFrame - mInputSize;
+ if (copy > inHeader->nFilledLen) {
+ copy = inHeader->nFilledLen;
+ }
+
+ if (mInputSize == 0) {
+ mInputTimeUs = inHeader->nTimeStamp;
+ }
+
+ memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy);
+ mInputSize += copy;
+
+ inHeader->nOffset += copy;
+ inHeader->nFilledLen -= copy;
+
+ // "Time" on the input buffer has in effect advanced by the
+ // number of audio frames we just advanced nOffset by.
+ inHeader->nTimeStamp +=
+ (copy * 1000000ll / kSampleRate) / sizeof(int16_t);
+
+ if (inHeader->nFilledLen == 0) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ ALOGV("saw input EOS");
+ mSawInputEOS = true;
+
+ // Pad any remaining data with zeroes.
+ memset((uint8_t *)mInputFrame + mInputSize,
+ 0,
+ numBytesPerInputFrame - mInputSize);
+
+ mInputSize = numBytesPerInputFrame;
+ }
+
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ inData = NULL;
+ inHeader = NULL;
+ inInfo = NULL;
+ }
+ }
+
+ // At this point we have all the input data necessary to encode
+ // a single frame, all we need is an output buffer to store the result
+ // in.
+
+ if (outQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ uint8_t *outPtr = outHeader->pBuffer + outHeader->nOffset;
+ size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset;
+
+ Frame_Type_3GPP frameType;
+ int res = AMREncode(
+ mEncState, mSidState, (Mode)mMode,
+ mInputFrame, outPtr, &frameType, AMR_TX_WMF);
+
+ CHECK_GE(res, 0);
+ CHECK_LE((size_t)res, outAvailable);
+
+ // Convert header byte from WMF to IETF format.
+ outPtr[0] = ((outPtr[0] << 3) | 4) & 0x7c;
+
+ outHeader->nFilledLen = res;
+ outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
+
+ if (mSawInputEOS) {
+ // We also tag this output buffer with EOS if it corresponds
+ // to the final input buffer.
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ }
+
+ outHeader->nTimeStamp = mInputTimeUs;
+
+#if 0
+ ALOGI("sending %d bytes of data (time = %lld us, flags = 0x%08lx)",
+ nOutputBytes, mInputTimeUs, outHeader->nFlags);
+
+ hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen);
+#endif
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+
+ outHeader = NULL;
+ outInfo = NULL;
+
+ mInputSize = 0;
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftAMRNBEncoder(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h
new file mode 100644
index 000000000000..50178c412976
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.h
@@ -0,0 +1,72 @@
+/*
+ * 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 SOFT_AMRNB_ENCODER_H_
+
+#define SOFT_AMRNB_ENCODER_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+namespace android {
+
+struct SoftAMRNBEncoder : public SimpleSoftOMXComponent {
+ SoftAMRNBEncoder(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftAMRNBEncoder();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kNumSamplesPerFrame = 160,
+ };
+
+ void *mEncState;
+ void *mSidState;
+
+ OMX_U32 mBitRate;
+ int mMode;
+
+ size_t mInputSize;
+ int16_t mInputFrame[kNumSamplesPerFrame];
+ int64_t mInputTimeUs;
+
+ bool mSawInputEOS;
+ bool mSignalledError;
+
+ void initPorts();
+ status_t initEncoder();
+
+ status_t setAudioParams();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftAMRNBEncoder);
+};
+
+} // namespace android
+
+#endif // SOFT_AMRNB_ENCODER_H_
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index ae43870b5461..6ce61713d6df 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -117,4 +117,26 @@ endif
include $(BUILD_STATIC_LIBRARY)
+################################################################################
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ SoftAMRWBEncoder.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libstagefright/include \
+ frameworks/base/include/media/stagefright/openmax \
+ frameworks/base/media/libstagefright/codecs/common/include \
+
+LOCAL_STATIC_LIBRARIES := \
+ libstagefright_amrwbenc
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright_omx libstagefright_foundation libutils \
+ libstagefright_enc_common
+
+LOCAL_MODULE := libstagefright_soft_amrwbenc
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
new file mode 100644
index 000000000000..9ccb49c6b8b8
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -0,0 +1,459 @@
+/*
+ * 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 "SoftAMRWBEncoder"
+#include <utils/Log.h>
+
+#include "SoftAMRWBEncoder.h"
+
+#include "cmnMemory.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
+
+namespace android {
+
+static const int32_t kSampleRate = 16000;
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+SoftAMRWBEncoder::SoftAMRWBEncoder(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleSoftOMXComponent(name, callbacks, appData, component),
+ mEncoderHandle(NULL),
+ mApiHandle(NULL),
+ mMemOperator(NULL),
+ mBitRate(0),
+ mMode(VOAMRWB_MD66),
+ mInputSize(0),
+ mInputTimeUs(-1ll),
+ mSawInputEOS(false),
+ mSignalledError(false) {
+ initPorts();
+ CHECK_EQ(initEncoder(), (status_t)OK);
+}
+
+SoftAMRWBEncoder::~SoftAMRWBEncoder() {
+ if (mEncoderHandle != NULL) {
+ CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
+ mEncoderHandle = NULL;
+ }
+
+ delete mApiHandle;
+ mApiHandle = NULL;
+
+ delete mMemOperator;
+ mMemOperator = NULL;
+}
+
+void SoftAMRWBEncoder::initPorts() {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = 0;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = kNumSamplesPerFrame * sizeof(int16_t);
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/raw");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+
+ addPort(def);
+
+ def.nPortIndex = 1;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = kNumBuffers;
+ def.nBufferCountActual = def.nBufferCountMin;
+ def.nBufferSize = 8192;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainAudio;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.audio.cMIMEType = const_cast<char *>("audio/amr-wb");
+ def.format.audio.pNativeRender = NULL;
+ def.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ def.format.audio.eEncoding = OMX_AUDIO_CodingAMR;
+
+ addPort(def);
+}
+
+status_t SoftAMRWBEncoder::initEncoder() {
+ mApiHandle = new VO_AUDIO_CODECAPI;
+
+ if (VO_ERR_NONE != voGetAMRWBEncAPI(mApiHandle)) {
+ ALOGE("Failed to get api handle");
+ return UNKNOWN_ERROR;
+ }
+
+ mMemOperator = new VO_MEM_OPERATOR;
+ mMemOperator->Alloc = cmnMemAlloc;
+ mMemOperator->Copy = cmnMemCopy;
+ mMemOperator->Free = cmnMemFree;
+ mMemOperator->Set = cmnMemSet;
+ mMemOperator->Check = cmnMemCheck;
+
+ VO_CODEC_INIT_USERDATA userData;
+ memset(&userData, 0, sizeof(userData));
+ userData.memflag = VO_IMF_USERMEMOPERATOR;
+ userData.memData = (VO_PTR) mMemOperator;
+
+ if (VO_ERR_NONE != mApiHandle->Init(
+ &mEncoderHandle, VO_AUDIO_CodingAMRWB, &userData)) {
+ ALOGE("Failed to init AMRWB encoder");
+ return UNKNOWN_ERROR;
+ }
+
+ VOAMRWBFRAMETYPE type = VOAMRWB_RFC3267;
+ if (VO_ERR_NONE != mApiHandle->SetParam(
+ mEncoderHandle, VO_PID_AMRWB_FRAMETYPE, &type)) {
+ ALOGE("Failed to set AMRWB encoder frame type to %d", type);
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+OMX_ERRORTYPE SoftAMRWBEncoder::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ formatParams->eEncoding =
+ (formatParams->nPortIndex == 0)
+ ? OMX_AUDIO_CodingPCM : OMX_AUDIO_CodingAMR;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAmr:
+ {
+ OMX_AUDIO_PARAM_AMRTYPE *amrParams =
+ (OMX_AUDIO_PARAM_AMRTYPE *)params;
+
+ if (amrParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ amrParams->nChannels = 1;
+ amrParams->nBitRate = mBitRate;
+
+ amrParams->eAMRBandMode =
+ (OMX_AUDIO_AMRBANDMODETYPE)(mMode + OMX_AUDIO_AMRBandModeWB0);
+
+ amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
+ amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eEndian = OMX_EndianBig;
+ pcmParams->bInterleaved = OMX_TRUE;
+ pcmParams->nBitPerSample = 16;
+ pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelCF;
+
+ pcmParams->nChannels = 1;
+ pcmParams->nSamplingRate = kSampleRate;
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleSoftOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (strncmp((const char *)roleParams->cRole,
+ "audio_encoder.amrwb",
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPortFormat:
+ {
+ const OMX_AUDIO_PARAM_PORTFORMATTYPE *formatParams =
+ (const OMX_AUDIO_PARAM_PORTFORMATTYPE *)params;
+
+ if (formatParams->nPortIndex > 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (formatParams->nIndex > 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if ((formatParams->nPortIndex == 0
+ && formatParams->eEncoding != OMX_AUDIO_CodingPCM)
+ || (formatParams->nPortIndex == 1
+ && formatParams->eEncoding != OMX_AUDIO_CodingAMR)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioAmr:
+ {
+ OMX_AUDIO_PARAM_AMRTYPE *amrParams =
+ (OMX_AUDIO_PARAM_AMRTYPE *)params;
+
+ if (amrParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (amrParams->nChannels != 1
+ || amrParams->eAMRDTXMode != OMX_AUDIO_AMRDTXModeOff
+ || amrParams->eAMRFrameFormat
+ != OMX_AUDIO_AMRFrameFormatFSF
+ || amrParams->eAMRBandMode < OMX_AUDIO_AMRBandModeWB0
+ || amrParams->eAMRBandMode > OMX_AUDIO_AMRBandModeWB8) {
+ return OMX_ErrorUndefined;
+ }
+
+ mBitRate = amrParams->nBitRate;
+
+ mMode = (VOAMRWBMODE)(
+ amrParams->eAMRBandMode - OMX_AUDIO_AMRBandModeWB0);
+
+ amrParams->eAMRDTXMode = OMX_AUDIO_AMRDTXModeOff;
+ amrParams->eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+
+ if (VO_ERR_NONE !=
+ mApiHandle->SetParam(
+ mEncoderHandle, VO_PID_AMRWB_MODE, &mMode)) {
+ ALOGE("Failed to set AMRWB encoder mode to %d", mMode);
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmParams =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *)params;
+
+ if (pcmParams->nPortIndex != 0) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (pcmParams->nChannels != 1
+ || pcmParams->nSamplingRate != (OMX_U32)kSampleRate) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+
+ default:
+ return SimpleSoftOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+void SoftAMRWBEncoder::onQueueFilled(OMX_U32 portIndex) {
+ if (mSignalledError) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+
+ size_t numBytesPerInputFrame = kNumSamplesPerFrame * sizeof(int16_t);
+
+ for (;;) {
+ // We do the following until we run out of buffers.
+
+ while (mInputSize < numBytesPerInputFrame) {
+ // As long as there's still input data to be read we
+ // will drain "kNumSamplesPerFrame" samples
+ // into the "mInputFrame" buffer and then encode those
+ // as a unit into an output buffer.
+
+ if (mSawInputEOS || inQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ const void *inData = inHeader->pBuffer + inHeader->nOffset;
+
+ size_t copy = numBytesPerInputFrame - mInputSize;
+ if (copy > inHeader->nFilledLen) {
+ copy = inHeader->nFilledLen;
+ }
+
+ if (mInputSize == 0) {
+ mInputTimeUs = inHeader->nTimeStamp;
+ }
+
+ memcpy((uint8_t *)mInputFrame + mInputSize, inData, copy);
+ mInputSize += copy;
+
+ inHeader->nOffset += copy;
+ inHeader->nFilledLen -= copy;
+
+ // "Time" on the input buffer has in effect advanced by the
+ // number of audio frames we just advanced nOffset by.
+ inHeader->nTimeStamp +=
+ (copy * 1000000ll / kSampleRate) / sizeof(int16_t);
+
+ if (inHeader->nFilledLen == 0) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ ALOGV("saw input EOS");
+ mSawInputEOS = true;
+
+ // Pad any remaining data with zeroes.
+ memset((uint8_t *)mInputFrame + mInputSize,
+ 0,
+ numBytesPerInputFrame - mInputSize);
+
+ mInputSize = numBytesPerInputFrame;
+ }
+
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ inData = NULL;
+ inHeader = NULL;
+ inInfo = NULL;
+ }
+ }
+
+ // At this point we have all the input data necessary to encode
+ // a single frame, all we need is an output buffer to store the result
+ // in.
+
+ if (outQueue.empty()) {
+ return;
+ }
+
+ BufferInfo *outInfo = *outQueue.begin();
+ OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ uint8_t *outPtr = outHeader->pBuffer + outHeader->nOffset;
+ size_t outAvailable = outHeader->nAllocLen - outHeader->nOffset;
+
+ VO_CODECBUFFER inputData;
+ memset(&inputData, 0, sizeof(inputData));
+ inputData.Buffer = (unsigned char *) mInputFrame;
+ inputData.Length = mInputSize;
+
+ CHECK_EQ(VO_ERR_NONE,
+ mApiHandle->SetInputData(mEncoderHandle, &inputData));
+
+ VO_CODECBUFFER outputData;
+ memset(&outputData, 0, sizeof(outputData));
+ VO_AUDIO_OUTPUTINFO outputInfo;
+ memset(&outputInfo, 0, sizeof(outputInfo));
+
+ outputData.Buffer = outPtr;
+ outputData.Length = outAvailable;
+ VO_U32 ret = mApiHandle->GetOutputData(
+ mEncoderHandle, &outputData, &outputInfo);
+ CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL);
+
+ outHeader->nFilledLen = outputData.Length;
+ outHeader->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
+
+ if (mSawInputEOS) {
+ // We also tag this output buffer with EOS if it corresponds
+ // to the final input buffer.
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ }
+
+ outHeader->nTimeStamp = mInputTimeUs;
+
+#if 0
+ ALOGI("sending %ld bytes of data (time = %lld us, flags = 0x%08lx)",
+ outHeader->nFilledLen, mInputTimeUs, outHeader->nFlags);
+
+ hexdump(outHeader->pBuffer + outHeader->nOffset, outHeader->nFilledLen);
+#endif
+
+ outQueue.erase(outQueue.begin());
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+
+ outHeader = NULL;
+ outInfo = NULL;
+
+ mInputSize = 0;
+ }
+}
+
+} // namespace android
+
+android::SoftOMXComponent *createSoftOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ return new android::SoftAMRWBEncoder(name, callbacks, appData, component);
+}
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h
new file mode 100644
index 000000000000..d0c1dabf9313
--- /dev/null
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.h
@@ -0,0 +1,76 @@
+/*
+ * 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 SOFT_AMRWB_ENCODER_H_
+
+#define SOFT_AMRWB_ENCODER_H_
+
+#include "SimpleSoftOMXComponent.h"
+
+#include "voAMRWB.h"
+
+struct VO_AUDIO_CODECAPI;
+struct VO_MEM_OPERATOR;
+
+namespace android {
+
+struct SoftAMRWBEncoder : public SimpleSoftOMXComponent {
+ SoftAMRWBEncoder(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~SoftAMRWBEncoder();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+
+private:
+ enum {
+ kNumBuffers = 4,
+ kNumSamplesPerFrame = 320,
+ };
+
+ void *mEncoderHandle;
+ VO_AUDIO_CODECAPI *mApiHandle;
+ VO_MEM_OPERATOR *mMemOperator;
+
+ OMX_U32 mBitRate;
+ VOAMRWBMODE mMode;
+
+ size_t mInputSize;
+ int16_t mInputFrame[kNumSamplesPerFrame];
+ int64_t mInputTimeUs;
+
+ bool mSawInputEOS;
+ bool mSignalledError;
+
+ void initPorts();
+ status_t initEncoder();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SoftAMRWBEncoder);
+};
+
+} // namespace android
+
+#endif // SOFT_AMRWB_ENCODER_H_
diff --git a/media/libstagefright/codecs/amrwbenc/src/mem_align.c b/media/libstagefright/codecs/amrwbenc/src/mem_align.c
index a29baf3830b3..3b7853f19854 100644
--- a/media/libstagefright/codecs/amrwbenc/src/mem_align.c
+++ b/media/libstagefright/codecs/amrwbenc/src/mem_align.c
@@ -23,6 +23,11 @@
#include "mem_align.h"
+#ifdef _MSC_VER
+#include <stddef.h>
+#else
+#include <stdint.h>
+#endif
/*****************************************************************************
*
@@ -66,8 +71,8 @@ mem_malloc(VO_MEM_OPERATOR *pMemop, unsigned int size, unsigned char alignment,
pMemop->Set(CodecID, tmp, 0, size + alignment);
mem_ptr =
- (unsigned char *) ((unsigned int) (tmp + alignment - 1) &
- (~((unsigned int) (alignment - 1))));
+ (unsigned char *) ((intptr_t) (tmp + alignment - 1) &
+ (~((intptr_t) (alignment - 1))));
if (mem_ptr == tmp)
mem_ptr += alignment;
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 82c647623e5b..a7a3d4781633 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -41,7 +41,7 @@ struct ISurfaceTexture;
class DrmManagerClinet;
class DecryptHandle;
-class TimedTextPlayer;
+class TimedTextDriver;
struct WVMExtractor;
struct AwesomeRenderer : public RefBase {
@@ -232,7 +232,7 @@ private:
sp<DecryptHandle> mDecryptHandle;
int64_t mLastVideoTimeUs;
- TimedTextPlayer *mTextPlayer;
+ TimedTextDriver *mTextDriver;
mutable Mutex mTimedTextLock;
sp<WVMExtractor> mWVMExtractor;
@@ -326,4 +326,3 @@ private:
} // namespace android
#endif // AWESOME_PLAYER_H_
-
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 53e764fd504b..2c87b34e42a8 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -31,7 +31,7 @@ class OMX : public BnOMX,
public:
OMX();
- virtual bool livesLocally(pid_t pid);
+ virtual bool livesLocally(node_id node, pid_t pid);
virtual status_t listNodes(List<ComponentInfo> *list);
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 694b12d8279b..ace883c7f6b5 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -185,7 +185,7 @@ void OMX::binderDied(const wp<IBinder> &the_late_who) {
instance->onObserverDied(mMaster);
}
-bool OMX::livesLocally(pid_t pid) {
+bool OMX::livesLocally(node_id node, pid_t pid) {
return pid == getpid();
}
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index da3ae42426db..99ffe7d65814 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -35,8 +35,11 @@ static const struct {
} kComponents[] = {
{ "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" },
+ { "OMX.google.aac.encoder", "aacenc", "audio_encoder.aac" },
{ "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" },
+ { "OMX.google.amrnb.encoder", "amrnbenc", "audio_encoder.amrnb" },
{ "OMX.google.amrwb.decoder", "amrdec", "audio_decoder.amrwb" },
+ { "OMX.google.amrwb.encoder", "amrwbenc", "audio_encoder.amrwb" },
{ "OMX.google.h264.decoder", "h264dec", "video_decoder.avc" },
{ "OMX.google.g711.alaw.decoder", "g711dec", "audio_decoder.g711alaw" },
{ "OMX.google.g711.mlaw.decoder", "g711dec", "audio_decoder.g711mlaw" },
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index bf694285afcc..41c08be74275 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -7,11 +7,13 @@ LOCAL_SRC_FILES = \
LOCAL_SHARED_LIBRARIES := \
libstagefright libbinder libmedia libutils
-LOCAL_C_INCLUDES:= \
+LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/base/include/media/stagefright/openmax
-LOCAL_MODULE:= omx_tests
+LOCAL_MODULE := omx_tests
+
+LOCAL_MODULE_TAGS := tests
include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index 59d0e154c597..8b23dee0c0c7 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -3,7 +3,10 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
TextDescriptions.cpp \
- TimedTextParser.cpp \
+ TimedTextDriver.cpp \
+ TimedTextInBandSource.cpp \
+ TimedTextSource.cpp \
+ TimedTextSRTSource.cpp \
TimedTextPlayer.cpp
LOCAL_CFLAGS += -Wno-multichar
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
new file mode 100644
index 000000000000..9ec94153fc89
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -0,0 +1,223 @@
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TimedTextDriver"
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/Utils.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+
+#include "TimedTextDriver.h"
+
+#include "TextDescriptions.h"
+#include "TimedTextPlayer.h"
+#include "TimedTextSource.h"
+
+namespace android {
+
+TimedTextDriver::TimedTextDriver(
+ const wp<MediaPlayerBase> &listener)
+ : mLooper(new ALooper),
+ mListener(listener),
+ mState(UNINITIALIZED) {
+ mLooper->setName("TimedTextDriver");
+ mLooper->start();
+ mPlayer = new TimedTextPlayer(listener);
+ mLooper->registerHandler(mPlayer);
+}
+
+TimedTextDriver::~TimedTextDriver() {
+ mTextInBandVector.clear();
+ mTextOutOfBandVector.clear();
+ mLooper->stop();
+}
+
+status_t TimedTextDriver::setTimedTextTrackIndex_l(int32_t index) {
+ if (index >=
+ (int)(mTextInBandVector.size() + mTextOutOfBandVector.size())) {
+ return BAD_VALUE;
+ }
+
+ sp<TimedTextSource> source;
+ if (index < mTextInBandVector.size()) {
+ source = mTextInBandVector.itemAt(index);
+ } else {
+ source = mTextOutOfBandVector.itemAt(index - mTextInBandVector.size());
+ }
+ mPlayer->setDataSource(source);
+ return OK;
+}
+
+status_t TimedTextDriver::start() {
+ Mutex::Autolock autoLock(mLock);
+ switch (mState) {
+ case UNINITIALIZED:
+ return INVALID_OPERATION;
+ case STOPPED:
+ mPlayer->start();
+ break;
+ case PLAYING:
+ return OK;
+ case PAUSED:
+ mPlayer->resume();
+ break;
+ default:
+ TRESPASS();
+ }
+ mState = PLAYING;
+ return OK;
+}
+
+status_t TimedTextDriver::stop() {
+ return pause();
+}
+
+// TODO: Test if pause() works properly.
+// Scenario 1: start - pause - resume
+// Scenario 2: start - seek
+// Scenario 3: start - pause - seek - resume
+status_t TimedTextDriver::pause() {
+ Mutex::Autolock autoLock(mLock);
+ switch (mState) {
+ case UNINITIALIZED:
+ return INVALID_OPERATION;
+ case STOPPED:
+ return OK;
+ case PLAYING:
+ mPlayer->pause();
+ break;
+ case PAUSED:
+ return OK;
+ default:
+ TRESPASS();
+ }
+ mState = PAUSED;
+ return OK;
+}
+
+status_t TimedTextDriver::resume() {
+ return start();
+}
+
+status_t TimedTextDriver::seekToAsync(int64_t timeUs) {
+ mPlayer->seekToAsync(timeUs);
+ return OK;
+}
+
+status_t TimedTextDriver::setTimedTextTrackIndex(int32_t index) {
+ // TODO: This is current implementation for MediaPlayer::disableTimedText().
+ // Find better way for readability.
+ if (index < 0) {
+ mPlayer->pause();
+ return OK;
+ }
+
+ status_t ret = OK;
+ Mutex::Autolock autoLock(mLock);
+ switch (mState) {
+ case UNINITIALIZED:
+ ret = INVALID_OPERATION;
+ break;
+ case PAUSED:
+ ret = setTimedTextTrackIndex_l(index);
+ break;
+ case PLAYING:
+ mPlayer->pause();
+ ret = setTimedTextTrackIndex_l(index);
+ if (ret != OK) {
+ break;
+ }
+ mPlayer->start();
+ break;
+ case STOPPED:
+ // TODO: The only difference between STOPPED and PAUSED is this
+ // part. Revise the flow from "MediaPlayer::enableTimedText()" and
+ // remove one of the status, PAUSED and STOPPED, if possible.
+ ret = setTimedTextTrackIndex_l(index);
+ if (ret != OK) {
+ break;
+ }
+ mPlayer->start();
+ break;
+ defaut:
+ TRESPASS();
+ }
+ return ret;
+}
+
+status_t TimedTextDriver::addInBandTextSource(
+ const sp<MediaSource>& mediaSource) {
+ sp<TimedTextSource> source =
+ TimedTextSource::CreateTimedTextSource(mediaSource);
+ if (source == NULL) {
+ return ERROR_UNSUPPORTED;
+ }
+ Mutex::Autolock autoLock(mLock);
+ mTextInBandVector.add(source);
+ if (mState == UNINITIALIZED) {
+ mState = STOPPED;
+ }
+ return OK;
+}
+
+status_t TimedTextDriver::addOutOfBandTextSource(
+ const Parcel &request) {
+ // TODO: Define "TimedTextSource::CreateFromURI(uri)"
+ // and move below lines there..?
+
+ // String values written in Parcel are UTF-16 values.
+ const String16 uri16 = request.readString16();
+ String8 uri = String8(request.readString16());
+
+ uri.toLower();
+ // To support local subtitle file only for now
+ if (strncasecmp("file://", uri.string(), 7)) {
+ return ERROR_UNSUPPORTED;
+ }
+ sp<DataSource> dataSource =
+ DataSource::CreateFromURI(uri);
+ if (dataSource == NULL) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ sp<TimedTextSource> source;
+ if (uri.getPathExtension() == String8(".srt")) {
+ source = TimedTextSource::CreateTimedTextSource(
+ dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT);
+ }
+
+ if (source == NULL) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+
+ mTextOutOfBandVector.add(source);
+ if (mState == UNINITIALIZED) {
+ mState = STOPPED;
+ }
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextDriver.h b/media/libstagefright/timedtext/TimedTextDriver.h
new file mode 100644
index 000000000000..efedb6e9028e
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextDriver.h
@@ -0,0 +1,81 @@
+/*
+ * 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 TIMED_TEXT_DRIVER_H_
+#define TIMED_TEXT_DRIVER_H_
+
+#include <media/stagefright/foundation/ABase.h> // for DISALLOW_* macro
+#include <utils/Errors.h> // for status_t
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class ALooper;
+class MediaPlayerBase;
+class MediaSource;
+class Parcel;
+class TimedTextPlayer;
+class TimedTextSource;
+
+class TimedTextDriver {
+public:
+ TimedTextDriver(const wp<MediaPlayerBase> &listener);
+
+ ~TimedTextDriver();
+
+ // TODO: pause-resume pair seems equivalent to stop-start pair.
+ // Check if it is replaceable with stop-start.
+ status_t start();
+ status_t stop();
+ status_t pause();
+ status_t resume();
+
+ status_t seekToAsync(int64_t timeUs);
+
+ status_t addInBandTextSource(const sp<MediaSource>& source);
+ status_t addOutOfBandTextSource(const Parcel &request);
+
+ status_t setTimedTextTrackIndex(int32_t index);
+
+private:
+ Mutex mLock;
+
+ enum State {
+ UNINITIALIZED,
+ STOPPED,
+ PLAYING,
+ PAUSED,
+ };
+
+ sp<ALooper> mLooper;
+ sp<TimedTextPlayer> mPlayer;
+ wp<MediaPlayerBase> mListener;
+
+ // Variables to be guarded by mLock.
+ State mState;
+ Vector<sp<TimedTextSource> > mTextInBandVector;
+ Vector<sp<TimedTextSource> > mTextOutOfBandVector;
+ // -- End of variables to be guarded by mLock
+
+ status_t setTimedTextTrackIndex_l(int32_t index);
+
+ DISALLOW_EVIL_CONSTRUCTORS(TimedTextDriver);
+};
+
+} // namespace android
+
+#endif // TIMED_TEXT_DRIVER_H_
diff --git a/media/libstagefright/timedtext/TimedTextInBandSource.cpp b/media/libstagefright/timedtext/TimedTextInBandSource.cpp
new file mode 100644
index 000000000000..f2c4d54c4773
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextInBandSource.cpp
@@ -0,0 +1,118 @@
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TimedTextInBandSource"
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDebug.h> // CHECK_XX macro
+#include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+
+#include "TimedTextInBandSource.h"
+#include "TextDescriptions.h"
+
+namespace android {
+
+TimedTextInBandSource::TimedTextInBandSource(const sp<MediaSource>& mediaSource)
+ : mSource(mediaSource) {
+}
+
+TimedTextInBandSource::~TimedTextInBandSource() {
+}
+
+status_t TimedTextInBandSource::read(
+ int64_t *timeUs, Parcel *parcel, const MediaSource::ReadOptions *options) {
+ MediaBuffer *textBuffer = NULL;
+ status_t err = mSource->read(&textBuffer, options);
+ if (err != OK) {
+ return err;
+ }
+ CHECK(textBuffer != NULL);
+ textBuffer->meta_data()->findInt64(kKeyTime, timeUs);
+ // TODO: this is legacy code. when 'timeUs' can be <= 0?
+ if (*timeUs > 0) {
+ extractAndAppendLocalDescriptions(*timeUs, textBuffer, parcel);
+ }
+ textBuffer->release();
+ return OK;
+}
+
+// Each text sample consists of a string of text, optionally with sample
+// modifier description. The modifier description could specify a new
+// 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(
+ int64_t timeUs, const MediaBuffer *textBuffer, Parcel *parcel) {
+ const void *data;
+ size_t size = 0;
+ int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
+
+ const char *mime;
+ CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+
+ 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;
+ }
+ return ERROR_UNSUPPORTED;
+}
+
+// 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) {
+ const void *data;
+ size_t size = 0;
+ int32_t flag = TextDescriptions::GLOBAL_DESCRIPTIONS;
+
+ const char *mime;
+ CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+
+ // 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;
+ }
+ return ERROR_UNSUPPORTED;
+}
+
+} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextInBandSource.h b/media/libstagefright/timedtext/TimedTextInBandSource.h
new file mode 100644
index 000000000000..26e5737f06ee
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextInBandSource.h
@@ -0,0 +1,55 @@
+/*
+ * 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 TIMED_TEXT_IN_BAND_SOURCE_H_
+#define TIMED_TEXT_IN_BAND_SOURCE_H_
+
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+
+#include "TimedTextSource.h"
+
+namespace android {
+
+class MediaBuffer;
+class Parcel;
+
+class TimedTextInBandSource : public TimedTextSource {
+ public:
+ TimedTextInBandSource(const sp<MediaSource>& mediaSource);
+ virtual status_t start() { return mSource->start(); }
+ virtual status_t stop() { return mSource->stop(); }
+ virtual status_t read(
+ int64_t *timeUs,
+ Parcel *parcel,
+ const MediaSource::ReadOptions *options = NULL);
+ virtual status_t extractGlobalDescriptions(Parcel *parcel);
+
+ protected:
+ virtual ~TimedTextInBandSource();
+
+ private:
+ sp<MediaSource> mSource;
+
+ status_t extractAndAppendLocalDescriptions(
+ int64_t timeUs, const MediaBuffer *textBuffer, Parcel *parcel);
+
+ DISALLOW_EVIL_CONSTRUCTORS(TimedTextInBandSource);
+};
+
+} // namespace android
+
+#endif // TIMED_TEXT_IN_BAND_SOURCE_H_
diff --git a/media/libstagefright/timedtext/TimedTextParser.h b/media/libstagefright/timedtext/TimedTextParser.h
deleted file mode 100644
index 44774c296932..000000000000
--- a/media/libstagefright/timedtext/TimedTextParser.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef TIMED_TEXT_PARSER_H_
-
-#define TIMED_TEXT_PARSER_H_
-
-#include <media/MediaPlayerInterface.h>
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/MediaSource.h>
-
-namespace android {
-
-class DataSource;
-
-class TimedTextParser : public RefBase {
-public:
- TimedTextParser();
- virtual ~TimedTextParser();
-
- enum FileType {
- OUT_OF_BAND_FILE_SRT = 1,
- };
-
- status_t getText(AString *text, int64_t *startTimeUs, int64_t *endTimeUs,
- const MediaSource::ReadOptions *options = NULL);
- status_t init(const sp<DataSource> &dataSource, FileType fileType);
- void reset();
-
-private:
- Mutex mLock;
-
- sp<DataSource> mDataSource;
- off64_t mOffset;
-
- struct TextInfo {
- int64_t endTimeUs;
- // the offset of the text in the original file
- off64_t offset;
- int textLen;
- };
-
- int mIndex;
- FileType mFileType;
-
- // the key indicated the start time of the text
- KeyedVector<int64_t, TextInfo> mTextVector;
-
- status_t getNextInSrtFileFormat(
- off64_t *offset, int64_t *startTimeUs, TextInfo *info);
- status_t readNextLine(off64_t *offset, AString *data);
-
- status_t scanFile();
-
- DISALLOW_EVIL_CONSTRUCTORS(TimedTextParser);
-};
-
-} // namespace android
-
-#endif // TIMED_TEXT_PARSER_H_
-
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index 3014b0bc0548..8c2df88f4253 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,399 +18,164 @@
#define LOG_TAG "TimedTextPlayer"
#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-
+#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaDebug.h>
-#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MediaSource.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/FileSource.h>
-#include <media/stagefright/Utils.h>
+#include <media/MediaPlayerInterface.h>
-#include "include/AwesomePlayer.h"
#include "TimedTextPlayer.h"
-#include "TimedTextParser.h"
-#include "TextDescriptions.h"
-
-namespace android {
-struct TimedTextEvent : public TimedEventQueue::Event {
- TimedTextEvent(
- TimedTextPlayer *player,
- void (TimedTextPlayer::*method)())
- : mPlayer(player),
- mMethod(method) {
- }
-
-protected:
- virtual ~TimedTextEvent() {}
-
- virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
- (mPlayer->*mMethod)();
- }
+#include "TimedTextDriver.h"
+#include "TimedTextSource.h"
-private:
- TimedTextPlayer *mPlayer;
- void (TimedTextPlayer::*mMethod)();
+namespace android {
- TimedTextEvent(const TimedTextEvent &);
- TimedTextEvent &operator=(const TimedTextEvent &);
-};
+static const int64_t kAdjustmentProcessingTimeUs = 100000ll;
-TimedTextPlayer::TimedTextPlayer(
- AwesomePlayer *observer,
- const wp<MediaPlayerBase> &listener,
- TimedEventQueue *queue)
- : mSource(NULL),
- mOutOfBandSource(NULL),
- mSeekTimeUs(0),
- mStarted(false),
- mTextEventPending(false),
- mQueue(queue),
- mListener(listener),
- mObserver(observer),
- mTextBuffer(NULL),
- mTextParser(NULL),
- mTextType(kNoText) {
- mTextEvent = new TimedTextEvent(this, &TimedTextPlayer::onTextEvent);
+TimedTextPlayer::TimedTextPlayer(const wp<MediaPlayerBase> &listener)
+ : mListener(listener),
+ mSource(NULL),
+ mSendSubtitleGeneration(0) {
}
TimedTextPlayer::~TimedTextPlayer() {
- if (mStarted) {
- reset();
+ if (mSource != NULL) {
+ mSource->stop();
+ mSource.clear();
+ mSource = NULL;
}
-
- mTextTrackVector.clear();
- mTextOutOfBandVector.clear();
}
-status_t TimedTextPlayer::start(uint8_t index) {
- CHECK(!mStarted);
-
- if (index >=
- mTextTrackVector.size() + mTextOutOfBandVector.size()) {
- ALOGE("Incorrect text track index: %d", index);
- return BAD_VALUE;
- }
-
- status_t err;
- if (index < mTextTrackVector.size()) { // start an in-band text
- mSource = mTextTrackVector.itemAt(index);
-
- err = mSource->start();
-
- if (err != OK) {
- return err;
- }
- mTextType = kInBandText;
- } else { // start an out-of-band text
- OutOfBandText text =
- mTextOutOfBandVector.itemAt(index - mTextTrackVector.size());
-
- mOutOfBandSource = text.source;
- TimedTextParser::FileType fileType = text.type;
-
- if (mTextParser == NULL) {
- mTextParser = new TimedTextParser();
- }
-
- if ((err = mTextParser->init(mOutOfBandSource, fileType)) != OK) {
- return err;
- }
- mTextType = kOutOfBandText;
- }
-
- // send sample description format
- if ((err = extractAndSendGlobalDescriptions()) != OK) {
- return err;
- }
-
- int64_t positionUs;
- mObserver->getPosition(&positionUs);
- seekTo(positionUs);
-
- postTextEvent();
-
- mStarted = true;
-
- return OK;
+void TimedTextPlayer::start() {
+ sp<AMessage> msg = new AMessage(kWhatSeek, id());
+ msg->setInt64("seekTimeUs", -1);
+ msg->post();
}
void TimedTextPlayer::pause() {
- CHECK(mStarted);
-
- cancelTextEvent();
+ (new AMessage(kWhatPause, id()))->post();
}
void TimedTextPlayer::resume() {
- CHECK(mStarted);
-
- postTextEvent();
-}
-
-void TimedTextPlayer::reset() {
- CHECK(mStarted);
-
- // send an empty text to clear the screen
- notifyListener(MEDIA_TIMED_TEXT);
-
- cancelTextEvent();
-
- mSeeking = false;
- mStarted = false;
-
- if (mTextType == kInBandText) {
- if (mTextBuffer != NULL) {
- mTextBuffer->release();
- mTextBuffer = NULL;
- }
-
- if (mSource != NULL) {
- mSource->stop();
- mSource.clear();
- mSource = NULL;
- }
- } else {
- if (mTextParser != NULL) {
- mTextParser.clear();
- mTextParser = NULL;
- }
- if (mOutOfBandSource != NULL) {
- mOutOfBandSource.clear();
- mOutOfBandSource = NULL;
- }
- }
+ start();
}
-status_t TimedTextPlayer::seekTo(int64_t time_us) {
- Mutex::Autolock autoLock(mLock);
-
- mSeeking = true;
- mSeekTimeUs = time_us;
-
- postTextEvent();
-
- return OK;
+void TimedTextPlayer::seekToAsync(int64_t timeUs) {
+ sp<AMessage> msg = new AMessage(kWhatSeek, id());
+ msg->setInt64("seekTimeUs", timeUs);
+ msg->post();
}
-status_t TimedTextPlayer::setTimedTextTrackIndex(int32_t index) {
- if (index >=
- (int)(mTextTrackVector.size() + mTextOutOfBandVector.size())) {
- return BAD_VALUE;
- }
-
- if (mStarted) {
- reset();
- }
-
- if (index >= 0) {
- return start(index);
- }
- return OK;
+void TimedTextPlayer::setDataSource(sp<TimedTextSource> source) {
+ sp<AMessage> msg = new AMessage(kWhatSetSource, id());
+ msg->setObject("source", source);
+ msg->post();
}
-void TimedTextPlayer::onTextEvent() {
- Mutex::Autolock autoLock(mLock);
-
- if (!mTextEventPending) {
- return;
- }
- mTextEventPending = false;
-
- if (mData.dataSize() > 0) {
- notifyListener(MEDIA_TIMED_TEXT, &mData);
- mData.freeData();
- }
-
- MediaSource::ReadOptions options;
- if (mSeeking) {
- options.setSeekTo(mSeekTimeUs,
- MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
- mSeeking = false;
-
- notifyListener(MEDIA_TIMED_TEXT); //empty text to clear the screen
- }
-
- int64_t positionUs, timeUs;
- mObserver->getPosition(&positionUs);
-
- if (mTextType == kInBandText) {
- if (mSource->read(&mTextBuffer, &options) != OK) {
- return;
+void TimedTextPlayer::onMessageReceived(const sp<AMessage> &msg) {
+ switch (msg->what()) {
+ case kWhatPause: {
+ mSendSubtitleGeneration++;
+ break;
}
-
- mTextBuffer->meta_data()->findInt64(kKeyTime, &timeUs);
- } else {
- int64_t endTimeUs;
- if (mTextParser->getText(
- &mText, &timeUs, &endTimeUs, &options) != OK) {
- return;
- }
- }
-
- if (timeUs > 0) {
- extractAndAppendLocalDescriptions(timeUs);
- }
-
- if (mTextType == kInBandText) {
- if (mTextBuffer != NULL) {
- mTextBuffer->release();
- mTextBuffer = NULL;
+ case kWhatSeek: {
+ int64_t seekTimeUs = 0;
+ msg->findInt64("seekTimeUs", &seekTimeUs);
+ if (seekTimeUs < 0) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL) {
+ int32_t positionMs = 0;
+ listener->getCurrentPosition(&positionMs);
+ seekTimeUs = positionMs * 1000ll;
+ }
+ }
+ doSeekAndRead(seekTimeUs);
+ break;
+ }
+ case kWhatSendSubtitle: {
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+ if (generation != mSendSubtitleGeneration) {
+ // Drop obsolete msg.
+ break;
+ }
+ sp<RefBase> obj;
+ msg->findObject("subtitle", &obj);
+ if (obj != NULL) {
+ sp<ParcelEvent> parcelEvent;
+ parcelEvent = static_cast<ParcelEvent*>(obj.get());
+ notifyListener(MEDIA_TIMED_TEXT, &(parcelEvent->parcel));
+ } else {
+ notifyListener(MEDIA_TIMED_TEXT);
+ }
+ doRead();
+ break;
+ }
+ case kWhatSetSource: {
+ sp<RefBase> obj;
+ msg->findObject("source", &obj);
+ if (obj == NULL) break;
+ if (mSource != NULL) {
+ mSource->stop();
+ }
+ mSource = static_cast<TimedTextSource*>(obj.get());
+ mSource->start();
+ Parcel parcel;
+ if (mSource->extractGlobalDescriptions(&parcel) == OK &&
+ parcel.dataSize() > 0) {
+ notifyListener(MEDIA_TIMED_TEXT, &parcel);
+ } else {
+ notifyListener(MEDIA_TIMED_TEXT);
+ }
+ break;
}
- } else {
- mText.clear();
- }
-
- //send the text now
- if (timeUs <= positionUs + 100000ll) {
- postTextEvent();
- } else {
- postTextEvent(timeUs - positionUs - 100000ll);
}
}
-void TimedTextPlayer::postTextEvent(int64_t delayUs) {
- if (mTextEventPending) {
- return;
- }
-
- mTextEventPending = true;
- mQueue->postEventWithDelay(mTextEvent, delayUs < 0 ? 10000 : delayUs);
-}
-
-void TimedTextPlayer::cancelTextEvent() {
- mQueue->cancelEvent(mTextEvent->eventID());
- mTextEventPending = false;
+void TimedTextPlayer::doSeekAndRead(int64_t seekTimeUs) {
+ MediaSource::ReadOptions options;
+ options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+ doRead(&options);
}
-void TimedTextPlayer::addTextSource(sp<MediaSource> source) {
- Mutex::Autolock autoLock(mLock);
- mTextTrackVector.add(source);
+void TimedTextPlayer::doRead(MediaSource::ReadOptions* options) {
+ int64_t timeUs = 0;
+ sp<ParcelEvent> parcelEvent = new ParcelEvent();
+ mSource->read(&timeUs, &(parcelEvent->parcel), options);
+ postTextEvent(parcelEvent, timeUs);
}
-status_t TimedTextPlayer::setParameter(int key, const Parcel &request) {
- Mutex::Autolock autoLock(mLock);
-
- if (key == KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE) {
- const String16 uri16 = request.readString16();
- String8 uri = String8(uri16);
- KeyedVector<String8, String8> headers;
-
- // To support local subtitle file only for now
- if (strncasecmp("file://", uri.string(), 7)) {
- return INVALID_OPERATION;
- }
- sp<DataSource> dataSource =
- DataSource::CreateFromURI(uri, &headers);
- status_t err = dataSource->initCheck();
+void TimedTextPlayer::postTextEvent(const sp<ParcelEvent>& parcel, int64_t timeUs) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL) {
+ int64_t positionUs, delayUs;
+ int32_t positionMs = 0;
+ listener->getCurrentPosition(&positionMs);
+ positionUs = positionMs * 1000;
- if (err != OK) {
- return err;
- }
-
- OutOfBandText text;
- text.source = dataSource;
- if (uri.getPathExtension() == String8(".srt")) {
- text.type = TimedTextParser::OUT_OF_BAND_FILE_SRT;
+ if (timeUs <= positionUs + kAdjustmentProcessingTimeUs) {
+ delayUs = 0;
} else {
- return ERROR_UNSUPPORTED;
+ delayUs = timeUs - positionUs - kAdjustmentProcessingTimeUs;
}
-
- mTextOutOfBandVector.add(text);
-
- return OK;
- }
- return INVALID_OPERATION;
-}
-
-void TimedTextPlayer::notifyListener(int msg, const Parcel *parcel) {
- if (mListener != NULL) {
- sp<MediaPlayerBase> listener = mListener.promote();
-
- if (listener != NULL) {
- if (parcel && (parcel->dataSize() > 0)) {
- listener->sendEvent(msg, 0, 0, parcel);
- } else { // send an empty timed text to clear the screen
- listener->sendEvent(msg);
- }
+ sp<AMessage> msg = new AMessage(kWhatSendSubtitle, id());
+ msg->setInt32("generation", mSendSubtitleGeneration);
+ if (parcel != NULL) {
+ msg->setObject("subtitle", parcel);
}
+ msg->post(delayUs);
}
}
-// Each text sample consists of a string of text, optionally with sample
-// modifier description. The modifier description could specify a new
-// 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 TimedTextPlayer::extractAndAppendLocalDescriptions(int64_t timeUs) {
- const void *data;
- size_t size = 0;
- int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS;
-
- if (mTextType == kInBandText) {
- const char *mime;
- CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
-
- if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
- flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
- data = mTextBuffer->data();
- size = mTextBuffer->size();
- } else {
- // support 3GPP only for now
- return ERROR_UNSUPPORTED;
+void TimedTextPlayer::notifyListener(int msg, const Parcel *parcel) {
+ sp<MediaPlayerBase> listener = mListener.promote();
+ if (listener != NULL) {
+ if (parcel != NULL && (parcel->dataSize() > 0)) {
+ listener->sendEvent(msg, 0, 0, parcel);
+ } else { // send an empty timed text to clear the screen
+ listener->sendEvent(msg);
}
- } else {
- data = mText.c_str();
- size = mText.size();
- flag |= TextDescriptions::OUT_OF_BAND_TEXT_SRT;
}
-
- if ((size > 0) && (flag != TextDescriptions::LOCAL_DESCRIPTIONS)) {
- mData.freeData();
- return TextDescriptions::getParcelOfDescriptions(
- (const uint8_t *)data, size, flag, timeUs / 1000, &mData);
- }
-
- return OK;
}
-// To extract and send the global text descriptions for all the text samples
-// in the text track or text file.
-status_t TimedTextPlayer::extractAndSendGlobalDescriptions() {
- const void *data;
- size_t size = 0;
- int32_t flag = TextDescriptions::GLOBAL_DESCRIPTIONS;
-
- if (mTextType == kInBandText) {
- const char *mime;
- CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
-
- // support 3GPP only for now
- if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
- 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;
- }
-
- flag |= TextDescriptions::IN_BAND_TEXT_3GPP;
- }
- }
-
- if ((size > 0) && (flag != TextDescriptions::GLOBAL_DESCRIPTIONS)) {
- Parcel parcel;
- if (TextDescriptions::getParcelOfDescriptions(
- (const uint8_t *)data, size, flag, 0, &parcel) == OK) {
- if (parcel.dataSize() > 0) {
- notifyListener(MEDIA_TIMED_TEXT, &parcel);
- }
- }
- }
-
- return OK;
-}
-}
+} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.h b/media/libstagefright/timedtext/TimedTextPlayer.h
index a744db59417b..837beeb0ee3e 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.h
+++ b/media/libstagefright/timedtext/TimedTextPlayer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,99 +15,61 @@
*/
#ifndef TIMEDTEXT_PLAYER_H_
-
#define TIMEDTEXT_PLAYER_H_
-#include <media/MediaPlayerInterface.h>
+#include <binder/Parcel.h>
#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/MediaSource.h>
+#include <utils/RefBase.h>
-#include "include/TimedEventQueue.h"
-#include "TimedTextParser.h"
+#include "TimedTextSource.h"
namespace android {
-class MediaSource;
-class AwesomePlayer;
-class MediaBuffer;
+class AMessage;
+class MediaPlayerBase;
+class TimedTextDriver;
+class TimedTextSource;
-class TimedTextPlayer {
+class TimedTextPlayer : public AHandler {
public:
- TimedTextPlayer(AwesomePlayer *observer,
- const wp<MediaPlayerBase> &listener,
- TimedEventQueue *queue);
+ TimedTextPlayer(const wp<MediaPlayerBase> &listener);
virtual ~TimedTextPlayer();
- // index: the index of the text track which will
- // be turned on
- status_t start(uint8_t index);
-
+ void start();
void pause();
-
void resume();
+ void seekToAsync(int64_t timeUs);
+ void setDataSource(sp<TimedTextSource> source);
- status_t seekTo(int64_t time_us);
-
- void addTextSource(sp<MediaSource> source);
-
- status_t setTimedTextTrackIndex(int32_t index);
- status_t setParameter(int key, const Parcel &request);
+protected:
+ virtual void onMessageReceived(const sp<AMessage> &msg);
private:
- enum TextType {
- kNoText = 0,
- kInBandText = 1,
- kOutOfBandText = 2,
+ enum {
+ kWhatPause = 'paus',
+ kWhatSeek = 'seek',
+ kWhatSendSubtitle = 'send',
+ kWhatSetSource = 'ssrc',
};
- Mutex mLock;
-
- sp<MediaSource> mSource;
- sp<DataSource> mOutOfBandSource;
-
- bool mSeeking;
- int64_t mSeekTimeUs;
-
- bool mStarted;
-
- sp<TimedEventQueue::Event> mTextEvent;
- bool mTextEventPending;
-
- TimedEventQueue *mQueue;
-
- wp<MediaPlayerBase> mListener;
- AwesomePlayer *mObserver;
-
- MediaBuffer *mTextBuffer;
- Parcel mData;
-
- // for in-band timed text
- Vector<sp<MediaSource> > mTextTrackVector;
-
- // for out-of-band timed text
- struct OutOfBandText {
- TimedTextParser::FileType type;
- sp<DataSource> source;
+ // To add Parcel into an AMessage as an object, it should be 'RefBase'.
+ struct ParcelEvent : public RefBase {
+ Parcel parcel;
};
- Vector<OutOfBandText > mTextOutOfBandVector;
- sp<TimedTextParser> mTextParser;
- AString mText;
-
- TextType mTextType;
-
- void reset();
+ wp<MediaPlayerBase> mListener;
+ sp<TimedTextSource> mSource;
+ int32_t mSendSubtitleGeneration;
+ void doSeekAndRead(int64_t seekTimeUs);
+ void doRead(MediaSource::ReadOptions* options = NULL);
void onTextEvent();
- void postTextEvent(int64_t delayUs = -1);
- void cancelTextEvent();
-
+ void postTextEvent(const sp<ParcelEvent>& parcel = NULL, int64_t timeUs = -1);
void notifyListener(int msg, const Parcel *parcel = NULL);
- status_t extractAndAppendLocalDescriptions(int64_t timeUs);
- status_t extractAndSendGlobalDescriptions();
-
DISALLOW_EVIL_CONSTRUCTORS(TimedTextPlayer);
};
diff --git a/media/libstagefright/timedtext/TimedTextParser.cpp b/media/libstagefright/timedtext/TimedTextSRTSource.cpp
index caea0a4cc6ed..3752d34469a5 100644
--- a/media/libstagefright/timedtext/TimedTextParser.cpp
+++ b/media/libstagefright/timedtext/TimedTextSRTSource.cpp
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
+ /*
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,133 +14,106 @@
* limitations under the License.
*/
-#include "TimedTextParser.h"
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TimedTextSRTSource"
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+#include <media/stagefright/foundation/AString.h>
#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+
+#include "TimedTextSRTSource.h"
+#include "TextDescriptions.h"
namespace android {
-TimedTextParser::TimedTextParser()
- : mDataSource(NULL),
- mOffset(0),
- mIndex(0) {
+TimedTextSRTSource::TimedTextSRTSource(const sp<DataSource>& dataSource)
+ : mSource(dataSource),
+ mIndex(0) {
}
-TimedTextParser::~TimedTextParser() {
- reset();
+TimedTextSRTSource::~TimedTextSRTSource() {
}
-status_t TimedTextParser::init(
- const sp<DataSource> &dataSource, FileType fileType) {
- mDataSource = dataSource;
- mFileType = fileType;
-
- status_t err;
- if ((err = scanFile()) != OK) {
+status_t TimedTextSRTSource::start() {
+ status_t err = scanFile();
+ if (err != OK) {
reset();
- return err;
}
-
- return OK;
+ return err;
}
-void TimedTextParser::reset() {
- mDataSource.clear();
+void TimedTextSRTSource::reset() {
mTextVector.clear();
- mOffset = 0;
mIndex = 0;
}
-// scan the text file to get start/stop time and the
-// offset of each piece of text content
-status_t TimedTextParser::scanFile() {
- if (mFileType != OUT_OF_BAND_FILE_SRT) {
- return ERROR_UNSUPPORTED;
+status_t TimedTextSRTSource::stop() {
+ reset();
+ return OK;
+}
+
+status_t TimedTextSRTSource::read(
+ int64_t *timeUs,
+ Parcel *parcel,
+ const MediaSource::ReadOptions *options) {
+ int64_t endTimeUs;
+ AString text;
+ status_t err = getText(options, &text, timeUs, &endTimeUs);
+ if (err != OK) {
+ return err;
+ }
+
+ if (*timeUs > 0) {
+ extractAndAppendLocalDescriptions(*timeUs, text, parcel);
}
+ return OK;
+}
+status_t TimedTextSRTSource::scanFile() {
off64_t offset = 0;
int64_t startTimeUs;
bool endOfFile = false;
while (!endOfFile) {
TextInfo info;
- status_t err = getNextInSrtFileFormat(&offset, &startTimeUs, &info);
-
- if (err != OK) {
- if (err == ERROR_END_OF_STREAM) {
+ status_t err = getNextSubtitleInfo(&offset, &startTimeUs, &info);
+ switch (err) {
+ case OK:
+ mTextVector.add(startTimeUs, info);
+ break;
+ case ERROR_END_OF_STREAM:
endOfFile = true;
- } else {
+ break;
+ default:
return err;
- }
- } else {
- mTextVector.add(startTimeUs, info);
}
}
-
if (mTextVector.isEmpty()) {
return ERROR_MALFORMED;
}
return OK;
}
-// read one line started from *offset and store it into data.
-status_t TimedTextParser::readNextLine(off64_t *offset, AString *data) {
- char character;
-
- data->clear();
-
- while (true) {
- ssize_t err;
- if ((err = mDataSource->readAt(*offset, &character, 1)) < 1) {
- if (err == 0) {
- return ERROR_END_OF_STREAM;
- }
- return ERROR_IO;
- }
-
- (*offset) ++;
-
- // a line could end with CR, LF or CR + LF
- if (character == 10) {
- break;
- } else if (character == 13) {
- if ((err = mDataSource->readAt(*offset, &character, 1)) < 1) {
- if (err == 0) { // end of the stream
- return OK;
- }
- return ERROR_IO;
- }
-
- (*offset) ++;
-
- if (character != 10) {
- (*offset) --;
- }
- break;
- }
-
- data->append(character);
- }
-
- return OK;
-}
-
/* SRT format:
- * Subtitle number
- * Start time --> End time
- * Text of subtitle (one or more lines)
- * Blank lines
+ * Subtitle number
+ * Start time --> End time
+ * Text of subtitle (one or more lines)
+ * Blank lines
*
* .srt file example:
- * 1
- * 00:00:20,000 --> 00:00:24,400
- * Altocumulus clouds occur between six thousand
+ * 1
+ * 00:00:20,000 --> 00:00:24,400
+ * Altocumulus clouds occr between six thousand
*
- * 2
- * 00:00:24,600 --> 00:00:27,800
- * and twenty thousand feet above ground level.
+ * 2
+ * 00:00:24,600 --> 00:00:27,800
+ * and twenty thousand feet above ground level.
*/
-status_t TimedTextParser::getNextInSrtFileFormat(
- off64_t *offset, int64_t *startTimeUs, TextInfo *info) {
+status_t TimedTextSRTSource::getNextSubtitleInfo(
+ off64_t *offset, int64_t *startTimeUs, TextInfo *info) {
AString data;
status_t err;
@@ -150,10 +123,9 @@ status_t TimedTextParser::getNextInSrtFileFormat(
return err;
}
data.trim();
- } while(data.empty());
+ } while (data.empty());
// Just ignore the first non-blank line which is subtitle sequence number.
-
if ((err = readNextLine(offset, &data)) != OK) {
return err;
}
@@ -161,7 +133,7 @@ status_t TimedTextParser::getNextInSrtFileFormat(
// the start time format is: hours:minutes:seconds,milliseconds
// 00:00:24,600 --> 00:00:27,800
if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d",
- &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) {
+ &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) {
return ERROR_MALFORMED;
}
@@ -172,7 +144,6 @@ status_t TimedTextParser::getNextInSrtFileFormat(
}
info->offset = *offset;
-
bool needMoreData = true;
while (needMoreData) {
if ((err = readNextLine(offset, &data)) != OK) {
@@ -191,25 +162,56 @@ status_t TimedTextParser::getNextInSrtFileFormat(
}
}
}
-
info->textLen = *offset - info->offset;
-
return OK;
}
-status_t TimedTextParser::getText(
- AString *text, int64_t *startTimeUs, int64_t *endTimeUs,
- const MediaSource::ReadOptions *options) {
- Mutex::Autolock autoLock(mLock);
+status_t TimedTextSRTSource::readNextLine(off64_t *offset, AString *data) {
+ data->clear();
+ while (true) {
+ ssize_t readSize;
+ char character;
+ if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) {
+ if (readSize == 0) {
+ return ERROR_END_OF_STREAM;
+ }
+ return ERROR_IO;
+ }
- text->clear();
+ (*offset)++;
+ // a line could end with CR, LF or CR + LF
+ if (character == 10) {
+ break;
+ } else if (character == 13) {
+ if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) {
+ if (readSize == 0) { // end of the stream
+ return OK;
+ }
+ return ERROR_IO;
+ }
+
+ (*offset)++;
+ if (character != 10) {
+ (*offset)--;
+ }
+ break;
+ }
+ data->append(character);
+ }
+ return OK;
+}
+
+status_t TimedTextSRTSource::getText(
+ const MediaSource::ReadOptions *options,
+ AString *text, int64_t *startTimeUs, int64_t *endTimeUs) {
+ text->clear();
int64_t seekTimeUs;
MediaSource::ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- int64_t lastEndTimeUs = mTextVector.valueAt(mTextVector.size() - 1).endTimeUs;
+ if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
+ int64_t lastEndTimeUs =
+ mTextVector.valueAt(mTextVector.size() - 1).endTimeUs;
int64_t firstStartTimeUs = mTextVector.keyAt(0);
-
if (seekTimeUs < 0 || seekTimeUs > lastEndTimeUs) {
return ERROR_OUT_OF_RANGE;
} else if (seekTimeUs < firstStartTimeUs) {
@@ -232,31 +234,42 @@ status_t TimedTextParser::getText(
low = mid + 1;
} else {
if ((high == mid + 1)
- && (seekTimeUs < mTextVector.keyAt(high))) {
+ && (seekTimeUs < mTextVector.keyAt(high))) {
break;
}
high = mid - 1;
}
}
-
mIndex = mid;
}
}
-
- TextInfo info = mTextVector.valueAt(mIndex);
+ const TextInfo &info = mTextVector.valueAt(mIndex);
*startTimeUs = mTextVector.keyAt(mIndex);
*endTimeUs = info.endTimeUs;
- mIndex ++;
+ mIndex++;
char *str = new char[info.textLen];
- if (mDataSource->readAt(info.offset, str, info.textLen) < info.textLen) {
+ if (mSource->readAt(info.offset, str, info.textLen) < info.textLen) {
delete[] str;
return ERROR_IO;
}
-
text->append(str, info.textLen);
delete[] str;
return OK;
}
+status_t TimedTextSRTSource::extractAndAppendLocalDescriptions(
+ int64_t timeUs, const AString &text, Parcel *parcel) {
+ const void *data = text.c_str();
+ size_t size = text.size();
+ int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS |
+ TextDescriptions::OUT_OF_BAND_TEXT_SRT;
+
+ if (size > 0) {
+ return TextDescriptions::getParcelOfDescriptions(
+ (const uint8_t *)data, size, flag, timeUs / 1000, parcel);
+ }
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextSRTSource.h b/media/libstagefright/timedtext/TimedTextSRTSource.h
new file mode 100644
index 000000000000..a0734d9b21b7
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextSRTSource.h
@@ -0,0 +1,75 @@
+/*
+ * 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 TIMED_TEXT_SRT_SOURCE_H_
+#define TIMED_TEXT_SRT_SOURCE_H_
+
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h>
+#include <utils/Compat.h> // off64_t
+
+#include "TimedTextSource.h"
+
+namespace android {
+
+class AString;
+class DataSource;
+class MediaBuffer;
+class Parcel;
+
+class TimedTextSRTSource : public TimedTextSource {
+ public:
+ TimedTextSRTSource(const sp<DataSource>& dataSource);
+ virtual status_t start();
+ virtual status_t stop();
+ virtual status_t read(
+ int64_t *timeUs,
+ Parcel *parcel,
+ const MediaSource::ReadOptions *options = NULL);
+
+ protected:
+ virtual ~TimedTextSRTSource();
+
+ private:
+ sp<DataSource> mSource;
+
+ struct TextInfo {
+ int64_t endTimeUs;
+ // The offset of the text in the original file.
+ off64_t offset;
+ int textLen;
+ };
+
+ int mIndex;
+ KeyedVector<int64_t, TextInfo> mTextVector;
+
+ void reset();
+ status_t scanFile();
+ status_t getNextSubtitleInfo(
+ off64_t *offset, int64_t *startTimeUs, TextInfo *info);
+ status_t readNextLine(off64_t *offset, AString *data);
+ status_t getText(
+ const MediaSource::ReadOptions *options,
+ AString *text, int64_t *startTimeUs, int64_t *endTimeUs);
+ status_t extractAndAppendLocalDescriptions(
+ int64_t timeUs, const AString &text, Parcel *parcel);
+
+ DISALLOW_EVIL_CONSTRUCTORS(TimedTextSRTSource);
+};
+
+} // namespace android
+
+#endif // TIMED_TEXT_SRT_SOURCE_H_
diff --git a/media/libstagefright/timedtext/TimedTextSource.cpp b/media/libstagefright/timedtext/TimedTextSource.cpp
new file mode 100644
index 000000000000..9efe67c45af0
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextSource.cpp
@@ -0,0 +1,53 @@
+ /*
+ * 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 "TimedTextSource"
+#include <utils/Log.h>
+
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaSource.h>
+
+#include "TimedTextSource.h"
+
+#include "TimedTextInBandSource.h"
+#include "TimedTextSRTSource.h"
+
+namespace android {
+
+// static
+sp<TimedTextSource> TimedTextSource::CreateTimedTextSource(
+ const sp<MediaSource>& mediaSource) {
+ return new TimedTextInBandSource(mediaSource);
+}
+
+// static
+sp<TimedTextSource> TimedTextSource::CreateTimedTextSource(
+ const sp<DataSource>& dataSource, FileType filetype) {
+ switch(filetype) {
+ case OUT_OF_BAND_FILE_SRT:
+ return new TimedTextSRTSource(dataSource);
+ case OUT_OF_BAND_FILE_SMI:
+ // TODO: Implement for SMI.
+ ALOGE("Supporting SMI is not implemented yet");
+ break;
+ default:
+ ALOGE("Undefined subtitle format. : %d", filetype);
+ }
+ return NULL;
+}
+
+} // namespace android
diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h
new file mode 100644
index 000000000000..06bae7150db4
--- /dev/null
+++ b/media/libstagefright/timedtext/TimedTextSource.h
@@ -0,0 +1,61 @@
+/*
+ * 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 TIMED_TEXT_SOURCE_H_
+#define TIMED_TEXT_SOURCE_H_
+
+#include <media/stagefright/foundation/ABase.h> // for DISALLOW_XXX macro.
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MediaSource.h> // for MediaSource::ReadOptions
+#include <utils/RefBase.h>
+
+namespace android {
+
+class DataSource;
+class Parcel;
+
+class TimedTextSource : public RefBase {
+ public:
+ enum FileType {
+ OUT_OF_BAND_FILE_SRT = 1,
+ OUT_OF_BAND_FILE_SMI = 2,
+ };
+ static sp<TimedTextSource> CreateTimedTextSource(
+ const sp<MediaSource>& source);
+ static sp<TimedTextSource> CreateTimedTextSource(
+ const sp<DataSource>& source, FileType filetype);
+ TimedTextSource() {}
+ virtual status_t start() = 0;
+ virtual status_t stop() = 0;
+ // Returns subtitle parcel and its start time.
+ virtual status_t read(
+ int64_t *timeUs,
+ Parcel *parcel,
+ const MediaSource::ReadOptions *options = NULL) = 0;
+ virtual status_t extractGlobalDescriptions(Parcel *parcel) {
+ return INVALID_OPERATION;
+ }
+
+ protected:
+ virtual ~TimedTextSource() { }
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(TimedTextSource);
+};
+
+} // namespace android
+
+#endif // TIMED_TEXT_SOURCE_H_
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java
index c9087d14665f..7967ce78208d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaAudioManagerTest.java
@@ -19,8 +19,13 @@ package com.android.mediaframeworktest.functional.audio;
import com.android.mediaframeworktest.MediaFrameworkTest;
import android.content.Context;
import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.os.Looper;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
/**
* Junit / Instrumentation test case for the media AudioManager api
@@ -28,8 +33,13 @@ import android.test.suitebuilder.annotation.MediumTest;
public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
- private String TAG = "MediaAudioManagerTest";
+ private final static String TAG = "MediaAudioManagerTest";
+ // the AudioManager used throughout the test
private AudioManager mAudioManager;
+ // keep track of looper for AudioManager so we can terminate it
+ private Looper mAudioManagerLooper;
+ private final Object mLooperLock = new Object();
+ private final static int WAIT_FOR_LOOPER_TO_INITIALIZE_MS = 60000; // 60s
private int[] ringtoneMode = {AudioManager.RINGER_MODE_NORMAL,
AudioManager.RINGER_MODE_SILENT, AudioManager.RINGER_MODE_VIBRATE};
@@ -37,17 +47,48 @@ public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<Medi
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
}
+ private void initializeAudioManagerWithLooper() {
+ new Thread() {
+ @Override
+ public void run() {
+ Looper.prepare();
+ mAudioManagerLooper = Looper.myLooper();
+ mAudioManager = (AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE);
+ synchronized (mLooperLock) {
+ mLooperLock.notify();
+ }
+ Looper.loop();
+ }
+ }.start();
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
- mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+ synchronized(mLooperLock) {
+ initializeAudioManagerWithLooper();
+ try {
+ mLooperLock.wait(WAIT_FOR_LOOPER_TO_INITIALIZE_MS);
+ } catch (Exception e) {
+ assertTrue("initializeAudioManagerWithLooper() failed to complete in time", false);
+ }
+ }
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
+ synchronized(mLooperLock) {
+ if (mAudioManagerLooper != null) {
+ mAudioManagerLooper.quit();
+ }
+ }
}
+ //-----------------------------------------------------------------
+ // Ringer Mode
+ //----------------------------------
+
public boolean validateSetRingTone(int i) {
int getRingtone = mAudioManager.getRingerMode();
if (i != getRingtone)
@@ -67,4 +108,136 @@ public class MediaAudioManagerTest extends ActivityInstrumentationTestCase2<Medi
assertTrue("SetRingtoneMode : " + ringtoneMode[i], result);
}
}
+
+ //-----------------------------------------------------------------
+ // AudioFocus
+ //----------------------------------
+
+ private static AudioFocusListener mAudioFocusListener;
+ private final static int INVALID_FOCUS = -80; // initialized to magic invalid focus change type
+ private final static int WAIT_FOR_AUDIOFOCUS_LOSS_MS = 10;
+
+ private static class AudioFocusListener implements OnAudioFocusChangeListener {
+ public int mLastFocusChange = INVALID_FOCUS;
+ public int mFocusChangeCounter = 0;
+ public AudioFocusListener() {
+ }
+ public void onAudioFocusChange(int focusChange) {
+ mLastFocusChange = focusChange;
+ mFocusChangeCounter++;
+ }
+ }
+
+ /**
+ * Fails the test if expectedFocusLossMode != mAudioFocusListener.mLastFocusChange
+ */
+ private void verifyAudioFocusLoss(int focusGainMode, int expectedFocusLossMode)
+ throws Exception {
+ // request AudioFocus so we can test that mAudioFocusListener loses it when another
+ // request comes in
+ int result = mAudioManager.requestAudioFocus(mAudioFocusListener,
+ AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN);
+ assertTrue("requestAudioFocus returned " + result,
+ result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
+ // cause mAudioFocusListener to lose AudioFocus
+ result = mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
+ focusGainMode);
+ assertTrue("requestAudioFocus returned " + result,
+ result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
+ // the audio focus request is async, so wait a bit to verify it had the expected effect
+ java.lang.Thread.sleep(WAIT_FOR_AUDIOFOCUS_LOSS_MS);
+ // test successful if the expected focus loss was recorded
+ assertEquals("listener lost focus",
+ mAudioFocusListener.mLastFocusChange, expectedFocusLossMode);
+ }
+
+ private void setupAudioFocusListener() {
+ mAudioFocusListener = new AudioFocusListener();
+ mAudioManager.registerAudioFocusListener(mAudioFocusListener);
+ }
+
+ private void cleanupAudioFocusListener() {
+ // clean up
+ mAudioManager.abandonAudioFocus(mAudioFocusListener);
+ mAudioManager.unregisterAudioFocusListener(mAudioFocusListener);
+ }
+
+ //----------------------------------
+
+ //Test case 1: test audio focus listener loses audio focus:
+ // AUDIOFOCUS_GAIN causes AUDIOFOCUS_LOSS
+ @MediumTest
+ public void testAudioFocusLoss() throws Exception {
+ setupAudioFocusListener();
+
+ verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_LOSS);
+
+ cleanupAudioFocusListener();
+ }
+
+ //Test case 2: test audio focus listener loses audio focus:
+ // AUDIOFOCUS_GAIN_TRANSIENT causes AUDIOFOCUS_LOSS_TRANSIENT
+ @MediumTest
+ public void testAudioFocusLossTransient() throws Exception {
+ setupAudioFocusListener();
+
+ verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
+ AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
+
+ cleanupAudioFocusListener();
+ }
+
+ //Test case 3: test audio focus listener loses audio focus:
+ // AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK causes AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
+ @MediumTest
+ public void testAudioFocusLossTransientDuck() throws Exception {
+ setupAudioFocusListener();
+
+ verifyAudioFocusLoss(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
+ AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
+
+ cleanupAudioFocusListener();
+ }
+
+ //Test case 4: test audio focus registering and use over 3000 iterations
+ @LargeTest
+ public void testAudioFocusStressListenerRequestAbandon() throws Exception {
+ final int ITERATIONS = 3000;
+ // here we only test the life cycle of a focus listener, and make sure we don't crash
+ // when doing it many times without waiting
+ for (int i = 0 ; i < ITERATIONS ; i++) {
+ setupAudioFocusListener();
+ int result = mAudioManager.requestAudioFocus(mAudioFocusListener,
+ AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
+ assertTrue("audio focus request was not granted",
+ result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
+ cleanupAudioFocusListener();
+ }
+ assertTrue("testAudioFocusListenerLifeCycle : tested" + ITERATIONS +" iterations", true);
+ }
+
+ //Test case 5: test audio focus use without listener
+ @LargeTest
+ public void testAudioFocusStressNoListenerRequestAbandon() throws Exception {
+ final int ITERATIONS = 1000;
+ // make sure we have a listener in the stack
+ setupAudioFocusListener();
+ mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN);
+ // keep making the current owner lose and gain audio focus repeatedly
+ for (int i = 0 ; i < ITERATIONS ; i++) {
+ mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+ mAudioManager.abandonAudioFocus(null);
+ // the audio focus request is async, so wait a bit to verify it had the expected effect
+ java.lang.Thread.sleep(WAIT_FOR_AUDIOFOCUS_LOSS_MS);
+ }
+ // verify there were 2 audio focus changes per iteration (one loss + one gain)
+ assertTrue("testAudioFocusListenerLifeCycle : observed " +
+ mAudioFocusListener.mFocusChangeCounter + " AudioFocus changes",
+ mAudioFocusListener.mFocusChangeCounter == ITERATIONS * 2);
+ mAudioManager.abandonAudioFocus(mAudioFocusListener);
+ mAudioManager.unregisterAudioFocusListener(mAudioFocusListener);
+ }
}
diff --git a/native/include/android/configuration.h b/native/include/android/configuration.h
index 4d683fbe1db6..06cd3da1a685 100644
--- a/native/include/android/configuration.h
+++ b/native/include/android/configuration.h
@@ -42,6 +42,8 @@ enum {
ACONFIGURATION_DENSITY_MEDIUM = 160,
ACONFIGURATION_DENSITY_TV = 213,
ACONFIGURATION_DENSITY_HIGH = 240,
+ ACONFIGURATION_DENSITY_XHIGH = 320,
+ ACONFIGURATION_DENSITY_XXHIGH = 480,
ACONFIGURATION_DENSITY_NONE = 0xffff,
ACONFIGURATION_KEYBOARD_ANY = 0x0000,
diff --git a/opengl/include/GLES/glext.h b/opengl/include/GLES/glext.h
index 65ab5e40bfa8..54afaab7e18e 100644
--- a/opengl/include/GLES/glext.h
+++ b/opengl/include/GLES/glext.h
@@ -1,7 +1,7 @@
#ifndef __glext_h_
#define __glext_h_
-/* $Revision: 10965 $ on $Date:: 2010-04-09 02:11:29 -0700 #$ */
+/* $Revision: 16481 $ on $Date:: 2012-01-04 10:43:56 -0800 #$ */
#ifdef __cplusplus
extern "C" {
@@ -68,6 +68,14 @@ extern "C" {
typedef void* GLeglImageOES;
#endif
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+/* GLeglImageOES defined in GL_OES_EGL_image already. */
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#endif
+
/* GL_OES_element_index_uint */
#ifndef GL_OES_element_index_uint
#define GL_UNSIGNED_INT 0x1405
@@ -211,14 +219,6 @@ typedef void* GLeglImageOES;
#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5
#endif
-/* GL_OES_EGL_image_external */
-#ifndef GL_OES_EGL_image_external
-#define GL_TEXTURE_EXTERNAL_OES 0x8D65
-#define GL_SAMPLER_EXTERNAL_OES 0x8D66
-#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
-#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
-#endif
-
/*------------------------------------------------------------------------*
* AMD extension tokens
*------------------------------------------------------------------------*/
@@ -243,6 +243,34 @@ typedef void* GLeglImageOES;
/* GL_APPLE_texture_2D_limited_npot */
/* No new tokens introduced by this extension. */
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_rgba8 */
+/* No new tokens introduced by this extension. */
+
/*------------------------------------------------------------------------*
* EXT extension tokens
*------------------------------------------------------------------------*/
@@ -260,6 +288,14 @@ typedef void* GLeglImageOES;
#define GL_STENCIL_EXT 0x1802
#endif
+/* GL_EXT_multisampled_render_to_texture */
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x9134
+#define GL_MAX_SAMPLES_EXT 0x9135
+#endif
+
/* GL_EXT_multi_draw_arrays */
/* No new tokens introduced by this extension. */
@@ -270,6 +306,32 @@ typedef void* GLeglImageOES;
#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
#endif
+/* GL_EXT_robustness */
+#ifndef GL_EXT_robustness
+/* reuse GL_NO_ERROR */
+#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
+#endif
+
+/* GL_EXT_sRGB */
+#ifndef GL_EXT_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif
+
/* GL_EXT_texture_filter_anisotropic */
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@@ -288,6 +350,27 @@ typedef void* GLeglImageOES;
#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
#endif
+/* GL_EXT_texture_storage */
+#ifndef GL_EXT_texture_storage
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+/* reuse GL_RGBA16F_EXT */
+#define GL_RGB16F_EXT 0x881B
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGB10_EXT 0x8052
+#define GL_BGRA8_EXT 0x93A1
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension tokens
*------------------------------------------------------------------------*/
@@ -507,6 +590,12 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target,
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
#endif
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */
+#endif
+
/* GL_OES_element_index_uint */
#ifndef GL_OES_element_index_uint
#define GL_OES_element_index_uint 1
@@ -785,11 +874,6 @@ typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arra
typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
#endif
-/* GL_OES_EGL_image_external */
-#ifndef GL_OES_EGL_image_external
-#define GL_OES_EGL_image_external 1
-#endif
-
/*------------------------------------------------------------------------*
* AMD extension functions
*------------------------------------------------------------------------*/
@@ -813,6 +897,36 @@ typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
#define GL_APPLE_texture_2D_limited_npot 1
#endif
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_rgba8 */
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif
+
/*------------------------------------------------------------------------*
* EXT extension functions
*------------------------------------------------------------------------*/
@@ -831,6 +945,17 @@ GL_API void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttac
typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
#endif
+/* GL_EXT_multisampled_render_to_texture */
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
/* GL_EXT_multi_draw_arrays */
#ifndef GL_EXT_multi_draw_arrays
#define GL_EXT_multi_draw_arrays 1
@@ -847,6 +972,31 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
#define GL_EXT_read_format_bgra 1
#endif
+/* GL_EXT_robustness */
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
+GL_API void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_API void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, float *params);
+GL_API void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, float *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+
+/* GL_EXT_sRGB */
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#endif
+
/* GL_EXT_texture_filter_anisotropic */
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_EXT_texture_filter_anisotropic 1
@@ -862,6 +1012,25 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
#define GL_EXT_texture_lod_bias 1
#endif
+/* GL_EXT_texture_storage */
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_API void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_API void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_API void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension functions
*------------------------------------------------------------------------*/
diff --git a/opengl/include/GLES2/gl2ext.h b/opengl/include/GLES2/gl2ext.h
index 9db4e252c559..8f8d80a1f997 100644
--- a/opengl/include/GLES2/gl2ext.h
+++ b/opengl/include/GLES2/gl2ext.h
@@ -1,7 +1,7 @@
#ifndef __gl2ext_h_
#define __gl2ext_h_
-/* $Revision: 10969 $ on $Date:: 2010-04-09 02:27:15 -0700 #$ */
+/* $Revision: 16619 $ on $Date:: 2012-01-18 10:00:14 -0800 #$ */
#ifdef __cplusplus
extern "C" {
@@ -57,6 +57,15 @@ extern "C" {
typedef void* GLeglImageOES;
#endif
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+/* GLeglImageOES defined in GL_OES_EGL_image already. */
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_SAMPLER_EXTERNAL_OES 0x8D66
+#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
+#endif
+
/* GL_OES_element_index_uint */
#ifndef GL_OES_element_index_uint
#define GL_UNSIGNED_INT 0x1405
@@ -146,14 +155,6 @@ typedef void* GLeglImageOES;
#define GL_INT_10_10_10_2_OES 0x8DF7
#endif
-/* GL_OES_EGL_image_external */
-#ifndef GL_OES_EGL_image_external
-#define GL_TEXTURE_EXTERNAL_OES 0x8D65
-#define GL_SAMPLER_EXTERNAL_OES 0x8D66
-#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67
-#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68
-#endif
-
/*------------------------------------------------------------------------*
* AMD extension tokens
*------------------------------------------------------------------------*/
@@ -188,6 +189,69 @@ typedef void* GLeglImageOES;
#endif
/*------------------------------------------------------------------------*
+ * ANGLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+#endif
+
+/*------------------------------------------------------------------------*
+ * APPLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_rgb_422 */
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE 0x8A1F
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#endif
+
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56
+#define GL_MAX_SAMPLES_APPLE 0x8D57
+#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6
+#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_mali_shader_binary */
+#ifndef GL_ARM_mali_shader_binary
+#define GL_MALI_SHADER_BINARY_ARM 0x8F60
+#endif
+
+/* GL_ARM_rgba8 */
+/* No new tokens introduced by this extension. */
+
+/*------------------------------------------------------------------------*
* EXT extension tokens
*------------------------------------------------------------------------*/
@@ -197,6 +261,29 @@ typedef void* GLeglImageOES;
#define GL_MAX_EXT 0x8008
#endif
+/* GL_EXT_color_buffer_half_float */
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_RG16F_EXT 0x822F
+#define GL_R16F_EXT 0x822D
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211
+#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17
+#endif
+
+/* GL_EXT_debug_label */
+#ifndef GL_EXT_debug_label
+#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F
+#define GL_PROGRAM_OBJECT_EXT 0x8B40
+#define GL_SHADER_OBJECT_EXT 0x8B48
+#define GL_BUFFER_OBJECT_EXT 0x9151
+#define GL_QUERY_OBJECT_EXT 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154
+#endif
+
+/* GL_EXT_debug_marker */
+/* No new tokens introduced by this extension. */
+
/* GL_EXT_discard_framebuffer */
#ifndef GL_EXT_discard_framebuffer
#define GL_COLOR_EXT 0x1800
@@ -204,9 +291,26 @@ typedef void* GLeglImageOES;
#define GL_STENCIL_EXT 0x1802
#endif
+/* GL_EXT_multisampled_render_to_texture */
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x9134
+#define GL_MAX_SAMPLES_EXT 0x9135
+#endif
+
/* GL_EXT_multi_draw_arrays */
/* No new tokens introduced by this extension. */
+/* GL_EXT_occlusion_query_boolean */
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A
+#define GL_CURRENT_QUERY_EXT 0x8865
+#define GL_QUERY_RESULT_EXT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867
+#endif
+
/* GL_EXT_read_format_bgra */
#ifndef GL_EXT_read_format_bgra
#define GL_BGRA_EXT 0x80E1
@@ -214,6 +318,53 @@ typedef void* GLeglImageOES;
#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366
#endif
+/* GL_EXT_robustness */
+#ifndef GL_EXT_robustness
+/* reuse GL_NO_ERROR */
+#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
+#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
+#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
+#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
+#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
+#endif
+
+/* GL_EXT_separate_shader_objects */
+#ifndef GL_EXT_separate_shader_objects
+#define GL_VERTEX_SHADER_BIT_EXT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002
+#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE_EXT 0x8258
+#define GL_ACTIVE_PROGRAM_EXT 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A
+#endif
+
+/* GL_EXT_shader_texture_lod */
+/* No new tokens introduced by this extension. */
+
+/* GL_EXT_shadow_samplers */
+#ifndef GL_EXT_shadow_samplers
+#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D
+#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E
+#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62
+#endif
+
+/* GL_EXT_sRGB */
+#ifndef GL_EXT_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif
+
/* GL_EXT_texture_filter_anisotropic */
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@@ -225,15 +376,54 @@ typedef void* GLeglImageOES;
#define GL_BGRA_EXT 0x80E1
#endif
+/* GL_EXT_texture_rg */
+#ifndef GL_EXT_texture_rg
+#define GL_RED_EXT 0x1903
+#define GL_RG_EXT 0x8227
+#define GL_R8_EXT 0x8229
+#define GL_RG8_EXT 0x822B
+#endif
+
+/* GL_EXT_texture_storage */
+#ifndef GL_EXT_texture_storage
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+/* reuse GL_RGBA16F_EXT */
+#define GL_RGB16F_EXT 0x881B
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGB10_EXT 0x8052
+#define GL_BGRA8_EXT 0x93A1
+#endif
+
/* GL_EXT_texture_type_2_10_10_10_REV */
#ifndef GL_EXT_texture_type_2_10_10_10_REV
#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
#endif
-/* GL_EXT_texture_compression_dxt1 */
-#ifndef GL_EXT_texture_compression_dxt1
-#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
-#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+/* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_unpack_subimage
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#endif
+
+/*------------------------------------------------------------------------*
+ * DMP extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_DMP_shader_binary */
+#ifndef GL_DMP_shader_binary
+#define GL_SHADER_BINARY_DMP 0x9250
#endif
/*------------------------------------------------------------------------*
@@ -276,13 +466,6 @@ typedef void* GLeglImageOES;
* NV extension tokens
*------------------------------------------------------------------------*/
-/* GL_NV_fence */
-#ifndef GL_NV_fence
-#define GL_ALL_COMPLETED_NV 0x84F2
-#define GL_FENCE_STATUS_NV 0x84F3
-#define GL_FENCE_CONDITION_NV 0x84F4
-#endif
-
/* GL_NV_coverage_sample */
#ifndef GL_NV_coverage_sample
#define GL_COVERAGE_COMPONENT_NV 0x8ED0
@@ -301,10 +484,90 @@ typedef void* GLeglImageOES;
#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C
#endif
+/* GL_NV_draw_buffers */
+#ifndef GL_NV_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_NV 0x8824
+#define GL_DRAW_BUFFER0_NV 0x8825
+#define GL_DRAW_BUFFER1_NV 0x8826
+#define GL_DRAW_BUFFER2_NV 0x8827
+#define GL_DRAW_BUFFER3_NV 0x8828
+#define GL_DRAW_BUFFER4_NV 0x8829
+#define GL_DRAW_BUFFER5_NV 0x882A
+#define GL_DRAW_BUFFER6_NV 0x882B
+#define GL_DRAW_BUFFER7_NV 0x882C
+#define GL_DRAW_BUFFER8_NV 0x882D
+#define GL_DRAW_BUFFER9_NV 0x882E
+#define GL_DRAW_BUFFER10_NV 0x882F
+#define GL_DRAW_BUFFER11_NV 0x8830
+#define GL_DRAW_BUFFER12_NV 0x8831
+#define GL_DRAW_BUFFER13_NV 0x8832
+#define GL_DRAW_BUFFER14_NV 0x8833
+#define GL_DRAW_BUFFER15_NV 0x8834
+#define GL_COLOR_ATTACHMENT0_NV 0x8CE0
+#define GL_COLOR_ATTACHMENT1_NV 0x8CE1
+#define GL_COLOR_ATTACHMENT2_NV 0x8CE2
+#define GL_COLOR_ATTACHMENT3_NV 0x8CE3
+#define GL_COLOR_ATTACHMENT4_NV 0x8CE4
+#define GL_COLOR_ATTACHMENT5_NV 0x8CE5
+#define GL_COLOR_ATTACHMENT6_NV 0x8CE6
+#define GL_COLOR_ATTACHMENT7_NV 0x8CE7
+#define GL_COLOR_ATTACHMENT8_NV 0x8CE8
+#define GL_COLOR_ATTACHMENT9_NV 0x8CE9
+#define GL_COLOR_ATTACHMENT10_NV 0x8CEA
+#define GL_COLOR_ATTACHMENT11_NV 0x8CEB
+#define GL_COLOR_ATTACHMENT12_NV 0x8CEC
+#define GL_COLOR_ATTACHMENT13_NV 0x8CED
+#define GL_COLOR_ATTACHMENT14_NV 0x8CEE
+#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
+#endif
+
+/* GL_NV_fbo_color_attachments */
+#ifndef GL_NV_fbo_color_attachments
+#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
+/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */
+#endif
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+#endif
+
+/* GL_NV_read_buffer */
+#ifndef GL_NV_read_buffer
+#define GL_READ_BUFFER_NV 0x0C02
+#endif
+
+/* GL_NV_read_buffer_front */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_depth */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_depth_stencil */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_read_stencil */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_texture_compression_s3tc_update */
+/* No new tokens introduced by this extension. */
+
+/* GL_NV_texture_npot_2D_mipmap */
+/* No new tokens introduced by this extension. */
+
/*------------------------------------------------------------------------*
* QCOM extension tokens
*------------------------------------------------------------------------*/
+/* GL_QCOM_alpha_test */
+#ifndef GL_QCOM_alpha_test
+#define GL_ALPHA_TEST_QCOM 0x0BC0
+#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1
+#define GL_ALPHA_TEST_REF_QCOM 0x0BC2
+#endif
+
/* GL_QCOM_driver_control */
/* No new tokens introduced by this extension. */
@@ -373,6 +636,15 @@ typedef void* GLeglImageOES;
#endif
/*------------------------------------------------------------------------*
+ * VIV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_VIV_shader_binary */
+#ifndef GL_VIV_shader_binary
+#define GL_SHADER_BINARY_VIV 0x8FC4
+#endif
+
+/*------------------------------------------------------------------------*
* End of extension tokens, start of corresponding extension functions
*------------------------------------------------------------------------*/
@@ -416,6 +688,12 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target,
typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
#endif
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */
+#endif
+
/* GL_OES_element_index_uint */
#ifndef GL_OES_element_index_uint
#define GL_OES_element_index_uint 1
@@ -549,11 +827,6 @@ typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
#define GL_OES_vertex_type_10_10_10_2 1
#endif
-/* GL_OES_EGL_image_external */
-#ifndef GL_OES_EGL_image_external
-#define GL_OES_EGL_image_external 1
-#endif
-
/*------------------------------------------------------------------------*
* AMD extension functions
*------------------------------------------------------------------------*/
@@ -603,6 +876,72 @@ typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monito
#endif
/*------------------------------------------------------------------------*
+ * ANGLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+/*------------------------------------------------------------------------*
+ * APPLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_rgb_422 */
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+/* GL_APPLE_framebuffer_multisample */
+#ifndef GL_APPLE_framebuffer_multisample
+#define GL_APPLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void);
+#endif
+
+/* GL_APPLE_texture_format_BGRA8888 */
+#ifndef GL_APPLE_texture_format_BGRA8888
+#define GL_APPLE_texture_format_BGRA8888 1
+#endif
+
+/* GL_APPLE_texture_max_level */
+#ifndef GL_APPLE_texture_max_level
+#define GL_APPLE_texture_max_level 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * ARM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ARM_mali_shader_binary */
+#ifndef GL_ARM_mali_shader_binary
+#define GL_ARM_mali_shader_binary 1
+#endif
+
+/* GL_ARM_rgba8 */
+#ifndef GL_ARM_rgba8
+#define GL_ARM_rgba8 1
+#endif
+
+/*------------------------------------------------------------------------*
* EXT extension functions
*------------------------------------------------------------------------*/
@@ -611,6 +950,35 @@ typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monito
#define GL_EXT_blend_minmax 1
#endif
+/* GL_EXT_color_buffer_half_float */
+#ifndef GL_EXT_color_buffer_half_float
+#define GL_EXT_color_buffer_half_float 1
+#endif
+
+/* GL_EXT_debug_label */
+#ifndef GL_EXT_debug_label
+#define GL_EXT_debug_label 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label);
+typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+
+/* GL_EXT_debug_marker */
+#ifndef GL_EXT_debug_marker
+#define GL_EXT_debug_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker);
+GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void);
+#endif
+typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker);
+typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void);
+#endif
+
/* GL_EXT_discard_framebuffer */
#ifndef GL_EXT_discard_framebuffer
#define GL_EXT_discard_framebuffer 1
@@ -620,6 +988,17 @@ GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numA
typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
#endif
+/* GL_EXT_multisampled_render_to_texture */
+#ifndef GL_EXT_multisampled_render_to_texture
+#define GL_EXT_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
#ifndef GL_EXT_multi_draw_arrays
#define GL_EXT_multi_draw_arrays 1
#ifdef GL_GLEXT_PROTOTYPES
@@ -630,11 +1009,134 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *fir
typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
#endif
+/* GL_EXT_occlusion_query_boolean */
+#ifndef GL_EXT_occlusion_query_boolean
+#define GL_EXT_occlusion_query_boolean 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids);
+GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids);
+GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id);
+GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id);
+GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target);
+GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params);
+#endif
+typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids);
+typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id);
+typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id);
+typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
/* GL_EXT_read_format_bgra */
#ifndef GL_EXT_read_format_bgra
#define GL_EXT_read_format_bgra 1
#endif
+/* GL_EXT_robustness */
+#ifndef GL_EXT_robustness
+#define GL_EXT_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void);
+GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, float *params);
+GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void);
+typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, float *params);
+typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+#endif
+
+/* GL_EXT_separate_shader_objects */
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program);
+GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program);
+GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings);
+GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines);
+GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines);
+GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x);
+GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y);
+GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z);
+GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x);
+GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y);
+GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline);
+GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings);
+typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+
+/* GL_EXT_shader_texture_lod */
+#ifndef GL_EXT_shader_texture_lod
+#define GL_EXT_shader_texture_lod 1
+#endif
+
+/* GL_EXT_shadow_samplers */
+#ifndef GL_EXT_shadow_samplers
+#define GL_EXT_shadow_samplers 1
+#endif
+
+/* GL_EXT_sRGB */
+#ifndef GL_EXT_sRGB
+#define GL_EXT_sRGB 1
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#endif
+
/* GL_EXT_texture_filter_anisotropic */
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_EXT_texture_filter_anisotropic 1
@@ -645,14 +1147,47 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
#define GL_EXT_texture_format_BGRA8888 1
#endif
+/* GL_EXT_texture_rg */
+#ifndef GL_EXT_texture_rg
+#define GL_EXT_texture_rg 1
+#endif
+
+/* GL_EXT_texture_storage */
+#ifndef GL_EXT_texture_storage
+#define GL_EXT_texture_storage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
/* GL_EXT_texture_type_2_10_10_10_REV */
#ifndef GL_EXT_texture_type_2_10_10_10_REV
#define GL_EXT_texture_type_2_10_10_10_REV 1
#endif
-/* GL_EXT_texture_compression_dxt1 */
-#ifndef GL_EXT_texture_compression_dxt1
-#define GL_EXT_texture_compression_dxt1 1
+/* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_unpack_subimage
+#define GL_EXT_unpack_subimage 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * DMP extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_DMP_shader_binary */
+#ifndef GL_DMP_shader_binary
+#define GL_DMP_shader_binary 1
#endif
/*------------------------------------------------------------------------*
@@ -694,6 +1229,36 @@ typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum targ
* NV extension functions
*------------------------------------------------------------------------*/
+/* GL_NV_coverage_sample */
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
+GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+#endif
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+#endif
+
+/* GL_NV_depth_nonlinear */
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#endif
+
+/* GL_NV_draw_buffers */
+#ifndef GL_NV_draw_buffers
+#define GL_NV_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+/* GL_NV_fbo_color_attachments */
+#ifndef GL_NV_fbo_color_attachments
+#define GL_NV_fbo_color_attachments 1
+#endif
+
/* GL_NV_fence */
#ifndef GL_NV_fence
#define GL_NV_fence 1
@@ -715,26 +1280,58 @@ typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
#endif
-/* GL_NV_coverage_sample */
-#ifndef GL_NV_coverage_sample
-#define GL_NV_coverage_sample 1
+/* GL_NV_read_buffer */
+#ifndef GL_NV_read_buffer
+#define GL_NV_read_buffer 1
#ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
-GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode);
#endif
-typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
-typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode);
#endif
-/* GL_NV_depth_nonlinear */
-#ifndef GL_NV_depth_nonlinear
-#define GL_NV_depth_nonlinear 1
+/* GL_NV_read_buffer_front */
+#ifndef GL_NV_read_buffer_front
+#define GL_NV_read_buffer_front 1
+#endif
+
+/* GL_NV_read_depth */
+#ifndef GL_NV_read_depth
+#define GL_NV_read_depth 1
+#endif
+
+/* GL_NV_read_depth_stencil */
+#ifndef GL_NV_read_depth_stencil
+#define GL_NV_read_depth_stencil 1
+#endif
+
+/* GL_NV_read_stencil */
+#ifndef GL_NV_read_stencil
+#define GL_NV_read_stencil 1
+#endif
+
+/* GL_NV_texture_compression_s3tc_update */
+#ifndef GL_NV_texture_compression_s3tc_update
+#define GL_NV_texture_compression_s3tc_update 1
+#endif
+
+/* GL_NV_texture_npot_2D_mipmap */
+#ifndef GL_NV_texture_npot_2D_mipmap
+#define GL_NV_texture_npot_2D_mipmap 1
#endif
/*------------------------------------------------------------------------*
* QCOM extension functions
*------------------------------------------------------------------------*/
+/* GL_QCOM_alpha_test */
+#ifndef GL_QCOM_alpha_test
+#define GL_QCOM_alpha_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref);
+#endif
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref);
+#endif
+
/* GL_QCOM_driver_control */
#ifndef GL_QCOM_driver_control
#define GL_QCOM_driver_control 1
@@ -809,6 +1406,15 @@ typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint
typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
#endif
+/*------------------------------------------------------------------------*
+ * VIV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_VIV_shader_binary */
+#ifndef GL_VIV_shader_binary
+#define GL_VIV_shader_binary 1
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 2fc612522f7a..06be2ef1147f 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -253,6 +253,19 @@ void Loader::init_api(void* dso,
if (f == NULL) {
//ALOGD("%s", name);
f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
+
+ /*
+ * GL_EXT_debug_label is special, we always report it as
+ * supported, it's handled by GLES_trace. If GLES_trace is not
+ * enabled, then these are no-ops.
+ */
+ if (!strcmp(name, "glInsertEventMarkerEXT")) {
+ f = (__eglMustCastToProperFunctionPointerType)gl_noop;
+ } else if (!strcmp(name, "glPushGroupMarkerEXT")) {
+ f = (__eglMustCastToProperFunctionPointerType)gl_noop;
+ } else if (!strcmp(name, "glPopGroupMarkerEXT")) {
+ f = (__eglMustCastToProperFunctionPointerType)gl_noop;
+ }
}
*curr++ = f;
api++;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index e053589a878b..83933e525211 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -233,6 +233,26 @@ EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
// ----------------------------------------------------------------------------
+const GLubyte * egl_get_string_for_current_context(GLenum name) {
+ // NOTE: returning NULL here will fall-back to the default
+ // implementation.
+
+ EGLContext context = egl_tls_t::getContext();
+ if (context == EGL_NO_CONTEXT)
+ return NULL;
+
+ egl_context_t const * const c = get_context(context);
+ if (c == NULL) // this should never happen, by construction
+ return NULL;
+
+ if (name != GL_EXTENSIONS)
+ return NULL;
+
+ return (const GLubyte *)c->gl_extensions.string();
+}
+
+// ----------------------------------------------------------------------------
+
// this mutex protects:
// d->disp[]
// egl_init_drivers_locked()
@@ -290,6 +310,9 @@ void gl_unimplemented() {
ALOGE("called unimplemented OpenGL ES API");
}
+void gl_noop() {
+}
+
// ----------------------------------------------------------------------------
#if USE_FAST_TLS_KEY
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 664f2582d255..73aab26cc76c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -477,6 +477,26 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
return result;
}
+void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
+ clearError();
+
+ egl_display_t const * const dp = validate_display(dpy);
+ if (!dp) {
+ return;
+ }
+
+ SurfaceRef _s(dp, surface);
+ if (!_s.get()) {
+ setError(EGL_BAD_SURFACE, EGL_FALSE);
+ return;
+ }
+
+ int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ egl_surface_t const * const s = get_surface(surface);
+ native_window_set_buffers_timestamp(s->win.get(), timestamp);
+}
+
// ----------------------------------------------------------------------------
// Contexts
// ----------------------------------------------------------------------------
@@ -546,27 +566,6 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
return result;
}
-static void loseCurrent(egl_context_t * cur_c)
-{
- if (cur_c) {
- egl_surface_t * cur_r = get_surface(cur_c->read);
- egl_surface_t * cur_d = get_surface(cur_c->draw);
-
- // by construction, these are either 0 or valid (possibly terminated)
- // it should be impossible for these to be invalid
- ContextRef _cur_c(cur_c);
- SurfaceRef _cur_r(cur_r);
- SurfaceRef _cur_d(cur_d);
-
- cur_c->read = NULL;
- cur_c->draw = NULL;
-
- _cur_c.release();
- _cur_r.release();
- _cur_d.release();
- }
-}
-
EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
EGLSurface read, EGLContext ctx)
{
@@ -643,21 +642,13 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
impl_read = r->surface;
}
- EGLBoolean result;
- if (c) {
- result = c->cnx->egl.eglMakeCurrent(
- dp->disp[c->impl].dpy, impl_draw, impl_read, impl_ctx);
- } else {
- result = cur_c->cnx->egl.eglMakeCurrent(
- dp->disp[cur_c->impl].dpy, impl_draw, impl_read, impl_ctx);
- }
+ EGLBoolean result = const_cast<egl_display_t*>(dp)->makeCurrent(c, cur_c,
+ draw, read, ctx,
+ impl_draw, impl_read, impl_ctx);
if (result == EGL_TRUE) {
-
- loseCurrent(cur_c);
-
- if (ctx != EGL_NO_CONTEXT) {
+ if (c) {
setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
egl_tls_t::setContext(ctx);
#if EGL_TRACE
@@ -667,8 +658,6 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
_c.acquire();
_r.acquire();
_d.acquire();
- c->read = read;
- c->draw = draw;
} else {
setGLHooksThreadSpecific(&gHooksNoContext);
egl_tls_t::setContext(EGL_NO_CONTEXT);
@@ -904,7 +893,8 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
#if EGL_TRACE
- debugHooks->ext.extensions[slot] = gHooksTrace.ext.extensions[slot] =
+ debugHooks->ext.extensions[slot] =
+ gHooksTrace.ext.extensions[slot] =
#endif
cnx->egl.eglGetProcAddress(procname);
}
@@ -1160,7 +1150,7 @@ EGLBoolean eglReleaseThread(void)
clearError();
// If there is context bound to the thread, release it
- loseCurrent(get_context(getContext()));
+ egl_display_t::loseCurrent(get_context(getContext()));
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 53eaf9a1366a..5cf5236b9009 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -342,6 +342,47 @@ EGLBoolean egl_display_t::terminate() {
return res;
}
+void egl_display_t::loseCurrent(egl_context_t * cur_c)
+{
+ if (cur_c) {
+ egl_surface_t * cur_r = get_surface(cur_c->read);
+ egl_surface_t * cur_d = get_surface(cur_c->draw);
+
+ // by construction, these are either 0 or valid (possibly terminated)
+ // it should be impossible for these to be invalid
+ ContextRef _cur_c(cur_c);
+ SurfaceRef _cur_r(cur_r);
+ SurfaceRef _cur_d(cur_d);
+
+ cur_c->onLooseCurrent();
+
+ _cur_c.release();
+ _cur_r.release();
+ _cur_d.release();
+ }
+}
+
+EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
+ EGLSurface draw, EGLSurface read, EGLContext ctx,
+ EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
+{
+ Mutex::Autolock _l(lock);
+ EGLBoolean result;
+ if (c) {
+ result = c->cnx->egl.eglMakeCurrent(
+ disp[c->impl].dpy, impl_draw, impl_read, impl_ctx);
+ } else {
+ result = cur_c->cnx->egl.eglMakeCurrent(
+ disp[cur_c->impl].dpy, impl_draw, impl_read, impl_ctx);
+ }
+ if (result == EGL_TRUE) {
+ loseCurrent(cur_c);
+ if (c) {
+ c->onMakeCurrent(draw, read);
+ }
+ }
+ return result;
+}
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 042ae07a91f6..4479e00ede26 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -39,6 +39,7 @@ namespace android {
// ----------------------------------------------------------------------------
class egl_object_t;
+class egl_context_t;
class egl_connection_t;
// ----------------------------------------------------------------------------
@@ -84,10 +85,14 @@ public:
// add reference to this object. returns true if this is a valid object.
bool getObject(egl_object_t* object) const;
-
static egl_display_t* get(EGLDisplay dpy);
static EGLDisplay getFromNativeDisplay(EGLNativeDisplayType disp);
+ EGLBoolean makeCurrent(egl_context_t* c, egl_context_t* cur_c,
+ EGLSurface draw, EGLSurface read, EGLContext ctx,
+ EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx);
+ static void loseCurrent(egl_context_t * cur_c);
+
inline bool isReady() const { return (refs > 0); }
inline bool isValid() const { return magic == '_dpy'; }
inline bool isAlive() const { return isValid(); }
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 26e8c3eb10c4..b660c53142ac 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -62,5 +62,41 @@ bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
}
// ----------------------------------------------------------------------------
+
+egl_context_t::egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
+ int impl, egl_connection_t const* cnx, int version) :
+ egl_object_t(get_display(dpy)), dpy(dpy), context(context),
+ config(config), read(0), draw(0), impl(impl), cnx(cnx),
+ version(version)
+{
+}
+
+void egl_context_t::onLooseCurrent() {
+ read = NULL;
+ draw = NULL;
+}
+
+void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) {
+ this->read = read;
+ this->draw = draw;
+
+ /*
+ * Here we cache the GL_EXTENSIONS string for this context and we
+ * add the extensions always handled by the wrapper
+ */
+
+ if (gl_extensions.isEmpty()) {
+ // call the implementation's glGetString(GL_EXTENSIONS)
+ const char* exts = (const char *)gEGLImpl[impl].hooks[version]->gl.glGetString(GL_EXTENSIONS);
+ gl_extensions.setTo(exts);
+ if (gl_extensions.find("GL_EXT_debug_marker") < 0) {
+ String8 temp("GL_EXT_debug_marker ");
+ temp.append(gl_extensions);
+ gl_extensions.setTo(temp);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 7106fa5ebf56..abd4cbb962a6 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -28,6 +28,7 @@
#include <GLES/glext.h>
#include <utils/threads.h>
+#include <utils/String8.h>
#include <system/window.h>
@@ -158,11 +159,11 @@ public:
typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
- int impl, egl_connection_t const* cnx, int version) :
- egl_object_t(get_display(dpy)), dpy(dpy), context(context),
- config(config), read(0), draw(0), impl(impl), cnx(cnx),
- version(version) {
- }
+ int impl, egl_connection_t const* cnx, int version);
+
+ void onLooseCurrent();
+ void onMakeCurrent(EGLSurface draw, EGLSurface read);
+
EGLDisplay dpy;
EGLContext context;
EGLConfig config;
@@ -171,6 +172,7 @@ public:
int impl;
egl_connection_t const* cnx;
int version;
+ String8 gl_extensions;
};
class egl_image_t: public egl_object_t {
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 107acd9b12b1..ff20957f3e41 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -58,6 +58,7 @@ extern gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
extern gl_hooks_t gHooksNoContext;
extern pthread_key_t gGLWrapperKey;
extern "C" void gl_unimplemented();
+extern "C" void gl_noop();
extern char const * const gl_names[];
extern char const * const egl_names[];
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index f89c865761a4..8dcf38dbeccb 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -82,23 +82,41 @@ namespace android {
#endif
+
#define GL_EXTENSION_LIST(name) \
- name(0) name(1) name(2) name(3) \
- name(4) name(5) name(6) name(7) \
- name(8) name(9) name(10) name(11) \
- name(12) name(13) name(14) name(15) \
- name(16) name(17) name(18) name(19) \
- name(20) name(21) name(22) name(23) \
- name(24) name(25) name(26) name(27) \
- name(28) name(29) name(30) name(31) \
- name(32) name(33) name(34) name(35) \
- name(36) name(37) name(38) name(39) \
- name(40) name(41) name(42) name(43) \
- name(44) name(45) name(46) name(47) \
- name(48) name(49) name(50) name(51) \
- name(52) name(53) name(54) name(55) \
- name(56) name(57) name(58) name(59) \
- name(60) name(61) name(62) name(63)
+ name(0) name(1) name(2) name(3) name(4) name(5) name(6) name(7) \
+ name(8) name(9) name(10) name(11) name(12) name(13) name(14) name(15) \
+ name(16) name(17) name(18) name(19) name(20) name(21) name(22) name(23) \
+ name(24) name(25) name(26) name(27) name(28) name(29) name(30) name(31) \
+ name(32) name(33) name(34) name(35) name(36) name(37) name(38) name(39) \
+ name(40) name(41) name(42) name(43) name(44) name(45) name(46) name(47) \
+ name(48) name(49) name(50) name(51) name(52) name(53) name(54) name(55) \
+ name(56) name(57) name(58) name(59) name(60) name(61) name(62) name(63) \
+ name(64) name(65) name(66) name(67) name(68) name(69) name(70) name(71) \
+ name(72) name(73) name(74) name(75) name(76) name(77) name(78) name(79) \
+ name(80) name(81) name(82) name(83) name(84) name(85) name(86) name(87) \
+ name(88) name(89) name(90) name(91) name(92) name(93) name(94) name(95) \
+ name(96) name(97) name(98) name(99) \
+ name(100) name(101) name(102) name(103) name(104) name(105) name(106) name(107) \
+ name(108) name(109) name(110) name(111) name(112) name(113) name(114) name(115) \
+ name(116) name(117) name(118) name(119) name(120) name(121) name(122) name(123) \
+ name(124) name(125) name(126) name(127) name(128) name(129) name(130) name(131) \
+ name(132) name(133) name(134) name(135) name(136) name(137) name(138) name(139) \
+ name(140) name(141) name(142) name(143) name(144) name(145) name(146) name(147) \
+ name(148) name(149) name(150) name(151) name(152) name(153) name(154) name(155) \
+ name(156) name(157) name(158) name(159) name(160) name(161) name(162) name(163) \
+ name(164) name(165) name(166) name(167) name(168) name(169) name(170) name(171) \
+ name(172) name(173) name(174) name(175) name(176) name(177) name(178) name(179) \
+ name(180) name(181) name(182) name(183) name(184) name(185) name(186) name(187) \
+ name(188) name(189) name(190) name(191) name(192) name(193) name(194) name(195) \
+ name(196) name(197) name(198) name(199) \
+ name(200) name(201) name(202) name(203) name(204) name(205) name(206) name(207) \
+ name(208) name(209) name(210) name(211) name(212) name(213) name(214) name(215) \
+ name(216) name(217) name(218) name(219) name(220) name(221) name(222) name(223) \
+ name(224) name(225) name(226) name(227) name(228) name(229) name(230) name(231) \
+ name(232) name(233) name(234) name(235) name(236) name(237) name(238) name(239) \
+ name(240) name(241) name(242) name(243) name(244) name(245) name(246) name(247) \
+ name(248) name(249) name(250) name(251) name(252) name(253) name(254) name(255)
GL_EXTENSION_LIST( GL_EXTENSION )
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index df22b968a1b7..79aa3cd59eeb 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -110,6 +110,20 @@ extern "C" {
#undef CALL_GL_API
#undef CALL_GL_API_RETURN
+/*
+ * glGetString() is special because we expose some extensions in the wrapper
+ */
+
+extern "C" const GLubyte * __glGetString(GLenum name);
+
+const GLubyte * glGetString(GLenum name)
+{
+ const GLubyte * ret = egl_get_string_for_current_context(name);
+ if (ret == NULL) {
+ ret = __glGetString(name);
+ }
+ return ret;
+}
/*
* These GL calls are special because they need to EGL to retrieve some
diff --git a/opengl/libs/GLES2/gl2_api.in b/opengl/libs/GLES2/gl2_api.in
index 5164450ba99f..9a89a52ca1ad 100644
--- a/opengl/libs/GLES2/gl2_api.in
+++ b/opengl/libs/GLES2/gl2_api.in
@@ -211,7 +211,7 @@ void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisionty
void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) {
CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
}
-const GLubyte* API_ENTRY(glGetString)(GLenum name) {
+const GLubyte* API_ENTRY(__glGetString)(GLenum name) {
CALL_GL_API_RETURN(glGetString, name);
}
void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params) {
diff --git a/opengl/libs/GLES2/gl2ext_api.in b/opengl/libs/GLES2/gl2ext_api.in
index e965625178ee..a8907fd40bbe 100644
--- a/opengl/libs/GLES2/gl2ext_api.in
+++ b/opengl/libs/GLES2/gl2ext_api.in
@@ -82,21 +82,204 @@ void API_ENTRY(glEndPerfMonitorAMD)(GLuint monitor) {
void API_ENTRY(glGetPerfMonitorCounterDataAMD)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) {
CALL_GL_API(glGetPerfMonitorCounterDataAMD, monitor, pname, dataSize, data, bytesWritten);
}
+void API_ENTRY(glBlitFramebufferANGLE)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ CALL_GL_API(glBlitFramebufferANGLE, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+void API_ENTRY(glRenderbufferStorageMultisampleANGLE)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorageMultisampleANGLE, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glRenderbufferStorageMultisampleAPPLE)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorageMultisampleAPPLE, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glResolveMultisampleFramebufferAPPLE)(void) {
+ CALL_GL_API(glResolveMultisampleFramebufferAPPLE);
+}
+void API_ENTRY(glLabelObjectEXT)(GLenum type, GLuint object, GLsizei length, const GLchar *label) {
+ CALL_GL_API(glLabelObjectEXT, type, object, length, label);
+}
+void API_ENTRY(glGetObjectLabelEXT)(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label) {
+ CALL_GL_API(glGetObjectLabelEXT, type, object, bufSize, length, label);
+}
+void API_ENTRY(glInsertEventMarkerEXT)(GLsizei length, const GLchar *marker) {
+ CALL_GL_API(glInsertEventMarkerEXT, length, marker);
+}
+void API_ENTRY(glPushGroupMarkerEXT)(GLsizei length, const GLchar *marker) {
+ CALL_GL_API(glPushGroupMarkerEXT, length, marker);
+}
+void API_ENTRY(glPopGroupMarkerEXT)(void) {
+ CALL_GL_API(glPopGroupMarkerEXT);
+}
void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
}
+void API_ENTRY(glRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorageMultisampleEXT, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glFramebufferTexture2DMultisampleEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+ CALL_GL_API(glFramebufferTexture2DMultisampleEXT, target, attachment, textarget, texture, level, samples);
+}
void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
}
void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
}
+void API_ENTRY(glGenQueriesEXT)(GLsizei n, GLuint *ids) {
+ CALL_GL_API(glGenQueriesEXT, n, ids);
+}
+void API_ENTRY(glDeleteQueriesEXT)(GLsizei n, const GLuint *ids) {
+ CALL_GL_API(glDeleteQueriesEXT, n, ids);
+}
+GLboolean API_ENTRY(glIsQueryEXT)(GLuint id) {
+ CALL_GL_API_RETURN(glIsQueryEXT, id);
+}
+void API_ENTRY(glBeginQueryEXT)(GLenum target, GLuint id) {
+ CALL_GL_API(glBeginQueryEXT, target, id);
+}
+void API_ENTRY(glEndQueryEXT)(GLenum target) {
+ CALL_GL_API(glEndQueryEXT, target);
+}
+void API_ENTRY(glGetQueryivEXT)(GLenum target, GLenum pname, GLint *params) {
+ CALL_GL_API(glGetQueryivEXT, target, pname, params);
+}
+void API_ENTRY(glGetQueryObjectuivEXT)(GLuint id, GLenum pname, GLuint *params) {
+ CALL_GL_API(glGetQueryObjectuivEXT, id, pname, params);
+}
+GLenum API_ENTRY(glGetGraphicsResetStatusEXT)(void) {
+ CALL_GL_API_RETURN(glGetGraphicsResetStatusEXT);
+}
+void API_ENTRY(glReadnPixelsEXT)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) {
+ CALL_GL_API(glReadnPixelsEXT, x, y, width, height, format, type, bufSize, data);
+}
+void API_ENTRY(glGetnUniformfvEXT)(GLuint program, GLint location, GLsizei bufSize, float *params) {
+ CALL_GL_API(glGetnUniformfvEXT, program, location, bufSize, params);
+}
+void API_ENTRY(glGetnUniformivEXT)(GLuint program, GLint location, GLsizei bufSize, GLint *params) {
+ CALL_GL_API(glGetnUniformivEXT, program, location, bufSize, params);
+}
+void API_ENTRY(glUseProgramStagesEXT)(GLuint pipeline, GLbitfield stages, GLuint program) {
+ CALL_GL_API(glUseProgramStagesEXT, pipeline, stages, program);
+}
+void API_ENTRY(glActiveShaderProgramEXT)(GLuint pipeline, GLuint program) {
+ CALL_GL_API(glActiveShaderProgramEXT, pipeline, program);
+}
+GLuint API_ENTRY(glCreateShaderProgramvEXT)(GLenum type, GLsizei count, const GLchar **strings) {
+ CALL_GL_API_RETURN(glCreateShaderProgramvEXT, type, count, strings);
+}
+void API_ENTRY(glBindProgramPipelineEXT)(GLuint pipeline) {
+ CALL_GL_API(glBindProgramPipelineEXT, pipeline);
+}
+void API_ENTRY(glDeleteProgramPipelinesEXT)(GLsizei n, const GLuint *pipelines) {
+ CALL_GL_API(glDeleteProgramPipelinesEXT, n, pipelines);
+}
+void API_ENTRY(glGenProgramPipelinesEXT)(GLsizei n, GLuint *pipelines) {
+ CALL_GL_API(glGenProgramPipelinesEXT, n, pipelines);
+}
+GLboolean API_ENTRY(glIsProgramPipelineEXT)(GLuint pipeline) {
+ CALL_GL_API_RETURN(glIsProgramPipelineEXT, pipeline);
+}
+void API_ENTRY(glProgramParameteriEXT)(GLuint program, GLenum pname, GLint value) {
+ CALL_GL_API(glProgramParameteriEXT, program, pname, value);
+}
+void API_ENTRY(glGetProgramPipelineivEXT)(GLuint pipeline, GLenum pname, GLint *params) {
+ CALL_GL_API(glGetProgramPipelineivEXT, pipeline, pname, params);
+}
+void API_ENTRY(glProgramUniform1iEXT)(GLuint program, GLint location, GLint x) {
+ CALL_GL_API(glProgramUniform1iEXT, program, location, x);
+}
+void API_ENTRY(glProgramUniform2iEXT)(GLuint program, GLint location, GLint x, GLint y) {
+ CALL_GL_API(glProgramUniform2iEXT, program, location, x, y);
+}
+void API_ENTRY(glProgramUniform3iEXT)(GLuint program, GLint location, GLint x, GLint y, GLint z) {
+ CALL_GL_API(glProgramUniform3iEXT, program, location, x, y, z);
+}
+void API_ENTRY(glProgramUniform4iEXT)(GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w) {
+ CALL_GL_API(glProgramUniform4iEXT, program, location, x, y, z, w);
+}
+void API_ENTRY(glProgramUniform1fEXT)(GLuint program, GLint location, GLfloat x) {
+ CALL_GL_API(glProgramUniform1fEXT, program, location, x);
+}
+void API_ENTRY(glProgramUniform2fEXT)(GLuint program, GLint location, GLfloat x, GLfloat y) {
+ CALL_GL_API(glProgramUniform2fEXT, program, location, x, y);
+}
+void API_ENTRY(glProgramUniform3fEXT)(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z) {
+ CALL_GL_API(glProgramUniform3fEXT, program, location, x, y, z);
+}
+void API_ENTRY(glProgramUniform4fEXT)(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+ CALL_GL_API(glProgramUniform4fEXT, program, location, x, y, z, w);
+}
+void API_ENTRY(glProgramUniform1ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ CALL_GL_API(glProgramUniform1ivEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform2ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ CALL_GL_API(glProgramUniform2ivEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform3ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ CALL_GL_API(glProgramUniform3ivEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform4ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ CALL_GL_API(glProgramUniform4ivEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform1fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ CALL_GL_API(glProgramUniform1fvEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform2fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ CALL_GL_API(glProgramUniform2fvEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform3fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ CALL_GL_API(glProgramUniform3fvEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniform4fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ CALL_GL_API(glProgramUniform4fvEXT, program, location, count, value);
+}
+void API_ENTRY(glProgramUniformMatrix2fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
+ CALL_GL_API(glProgramUniformMatrix2fvEXT, program, location, count, transpose, value);
+}
+void API_ENTRY(glProgramUniformMatrix3fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
+ CALL_GL_API(glProgramUniformMatrix3fvEXT, program, location, count, transpose, value);
+}
+void API_ENTRY(glProgramUniformMatrix4fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
+ CALL_GL_API(glProgramUniformMatrix4fvEXT, program, location, count, transpose, value);
+}
+void API_ENTRY(glValidateProgramPipelineEXT)(GLuint pipeline) {
+ CALL_GL_API(glValidateProgramPipelineEXT, pipeline);
+}
+void API_ENTRY(glGetProgramPipelineInfoLogEXT)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
+ CALL_GL_API(glGetProgramPipelineInfoLogEXT, pipeline, bufSize, length, infoLog);
+}
+void API_ENTRY(glTexStorage1DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
+ CALL_GL_API(glTexStorage1DEXT, target, levels, internalformat, width);
+}
+void API_ENTRY(glTexStorage2DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glTexStorage2DEXT, target, levels, internalformat, width, height);
+}
+void API_ENTRY(glTexStorage3DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
+ CALL_GL_API(glTexStorage3DEXT, target, levels, internalformat, width, height, depth);
+}
+void API_ENTRY(glTextureStorage1DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
+ CALL_GL_API(glTextureStorage1DEXT, texture, target, levels, internalformat, width);
+}
+void API_ENTRY(glTextureStorage2DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glTextureStorage2DEXT, texture, target, levels, internalformat, width, height);
+}
+void API_ENTRY(glTextureStorage3DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
+ CALL_GL_API(glTextureStorage3DEXT, texture, target, levels, internalformat, width, height, depth);
+}
void API_ENTRY(glRenderbufferStorageMultisampleIMG)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
CALL_GL_API(glRenderbufferStorageMultisampleIMG, target, samples, internalformat, width, height);
}
void API_ENTRY(glFramebufferTexture2DMultisampleIMG)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
CALL_GL_API(glFramebufferTexture2DMultisampleIMG, target, attachment, textarget, texture, level, samples);
}
+void API_ENTRY(glCoverageMaskNV)(GLboolean mask) {
+ CALL_GL_API(glCoverageMaskNV, mask);
+}
+void API_ENTRY(glCoverageOperationNV)(GLenum operation) {
+ CALL_GL_API(glCoverageOperationNV, operation);
+}
+void API_ENTRY(glDrawBuffersNV)(GLsizei n, const GLenum *bufs) {
+ CALL_GL_API(glDrawBuffersNV, n, bufs);
+}
void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) {
CALL_GL_API(glDeleteFencesNV, n, fences);
}
@@ -118,11 +301,11 @@ void API_ENTRY(glFinishFenceNV)(GLuint fence) {
void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) {
CALL_GL_API(glSetFenceNV, fence, condition);
}
-void API_ENTRY(glCoverageMaskNV)(GLboolean mask) {
- CALL_GL_API(glCoverageMaskNV, mask);
+void API_ENTRY(glReadBufferNV)(GLenum mode) {
+ CALL_GL_API(glReadBufferNV, mode);
}
-void API_ENTRY(glCoverageOperationNV)(GLenum operation) {
- CALL_GL_API(glCoverageOperationNV, operation);
+void API_ENTRY(glAlphaFuncQCOM)(GLenum func, GLclampf ref) {
+ CALL_GL_API(glAlphaFuncQCOM, func, ref);
}
void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) {
CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls);
diff --git a/opengl/libs/GLES2_dbg/generate_api_cpp.py b/opengl/libs/GLES2_dbg/generate_api_cpp.py
deleted file mode 100755
index 96cde57bc185..000000000000
--- a/opengl/libs/GLES2_dbg/generate_api_cpp.py
+++ /dev/null
@@ -1,219 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-#
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import sys
-
-def RemoveAnnotation(line):
- if line.find(":") >= 0:
- annotation = line[line.find(":"): line.find(" ", line.find(":"))]
- return line.replace(annotation, "*")
- else:
- return line
-
-def generate_api(lines):
- externs = []
- i = 0
- # these have been hand written
- skipFunctions = ["glDrawArrays", "glDrawElements"]
-
- # these have an EXTEND_Debug_* macro for getting data
- extendFunctions = ["glCopyTexImage2D", "glCopyTexSubImage2D", "glReadPixels",
-"glShaderSource", "glTexImage2D", "glTexSubImage2D"]
-
- # these also needs to be forwarded to DbgContext
- contextFunctions = ["glUseProgram", "glEnableVertexAttribArray", "glDisableVertexAttribArray",
-"glVertexAttribPointer", "glBindBuffer", "glBufferData", "glBufferSubData", "glDeleteBuffers",]
-
- for line in lines:
- if line.find("API_ENTRY(") >= 0: # a function prototype
- returnType = line[0: line.find(" API_ENTRY(")]
- functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
- parameterList = line[line.find(")(") + 2: line.find(") {")]
-
- #if line.find("*") >= 0:
- # extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList)
- # externs.append(extern)
- # continue
-
- if functionName in skipFunctions:
- sys.stderr.write("!\n! skipping function '%s'\n!\n" % (functionName))
- continue
-
- parameters = parameterList.split(',')
- paramIndex = 0
- if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer
- if not functionName in extendFunctions:
- # add function to list of functions that should be hand written, but generate code anyways
- extern = "%s Debug_%s(%s);" % (returnType, functionName, RemoveAnnotation(parameterList))
- sys.stderr.write("%s should be hand written\n" % (extern))
- print "// FIXME: this function has pointers, it should be hand written"
- externs.append(extern)
-
- print "%s Debug_%s(%s)\n{" % (returnType, functionName, RemoveAnnotation(parameterList))
- print " glesv2debugger::Message msg;"
-
- if parameterList == "void":
- parameters = []
- arguments = ""
- paramNames = []
- inout = ""
- getData = ""
-
- callerMembers = ""
- setCallerMembers = ""
- setMsgParameters = ""
-
- for parameter in parameters:
- const = parameter.find("const")
- parameter = parameter.replace("const", "")
- parameter = parameter.strip()
- paramType = parameter.split(' ')[0]
- paramName = parameter.split(' ')[1]
- annotation = ""
- arguments += paramName
- if parameter.find(":") >= 0: # has annotation
- assert inout == "" # only one parameter should be annotated
- sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType))
- inout = paramType.split(":")[2]
- annotation = paramType.split(":")[1]
- paramType = paramType.split(":")[0]
- count = 1
- countArg = ""
- if annotation.find("*") >= 0: # [1,n] * param
- count = int(annotation.split("*")[0])
- countArg = annotation.split("*")[1]
- assert countArg in paramNames
- elif annotation in paramNames:
- count = 1
- countArg = annotation
- elif annotation == "GLstring":
- annotation = "strlen(%s)" % (paramName)
- else:
- count = int(annotation)
-
- setMsgParameters += " msg.set_arg%d(ToInt(%s));\n" % (paramIndex, paramName)
- if paramType.find("void") >= 0:
- getData += " msg.mutable_data()->assign(reinterpret_cast<const char *>(%s), %s * sizeof(char));" % (paramName, annotation)
- else:
- getData += " msg.mutable_data()->assign(reinterpret_cast<const char *>(%s), %s * sizeof(%s));" % (paramName, annotation, paramType)
- paramType += "*"
- else:
- if paramType == "GLfloat" or paramType == "GLclampf" or paramType.find("*") >= 0:
- setMsgParameters += " msg.set_arg%d(ToInt(%s));\n" % (paramIndex, paramName)
- else:
- setMsgParameters += " msg.set_arg%d(%s);\n" % (paramIndex, paramName)
- if paramIndex < len(parameters) - 1:
- arguments += ', '
- if const >= 0:
- paramType = "const " + paramType
- paramNames.append(paramName)
- paramIndex += 1
- callerMembers += " %s %s;\n" % (paramType, paramName)
- setCallerMembers += " caller.%s = %s;\n" % (paramName, paramName)
-
- print " struct : public FunctionCall {"
- print callerMembers
- print " const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {"
- if inout in ["out", "inout"]: # get timing excluding output data copy
- print " nsecs_t c0 = systemTime(timeMode);"
- if returnType == "void":
- print " _c->%s(%s);" % (functionName, arguments)
- else:
- print " const int * ret = reinterpret_cast<const int *>(_c->%s(%s));" % (functionName, arguments)
- print " msg.set_ret(ToInt(ret));"
- if inout in ["out", "inout"]:
- print " msg.set_time((systemTime(timeMode) - c0) * 1e-6f);"
- print " " + getData
- if functionName in extendFunctions:
- print "\
-#ifdef EXTEND_AFTER_CALL_Debug_%s\n\
- EXTEND_AFTER_CALL_Debug_%s;\n\
-#endif" % (functionName, functionName)
- if functionName in contextFunctions:
- print " getDbgContextThreadSpecific()->%s(%s);" % (functionName, arguments)
- if returnType == "void":
- print " return 0;"
- else:
- print " return ret;"
- print """ }
- } caller;"""
- print setCallerMembers
- print setMsgParameters
-
- if line.find("*") >= 0 or line.find(":") >= 0:
- print " // FIXME: check for pointer usage"
- if inout in ["in", "inout"]:
- print getData
- if functionName in extendFunctions:
- print "\
-#ifdef EXTEND_Debug_%s\n\
- EXTEND_Debug_%s;\n\
-#endif" % (functionName, functionName)
- print " int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_%s);"\
- % (functionName)
- if returnType != "void":
- if returnType == "GLboolean":
- print " return static_cast<GLboolean>(reinterpret_cast<int>(ret));"
- else:
- print " return reinterpret_cast<%s>(ret);" % (returnType)
- print "}\n"
-
-
- print "// FIXME: the following functions should be written by hand"
- for extern in externs:
- print extern
-
-if __name__ == "__main__":
- print """\
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-// auto generated by generate_api_cpp.py
-
-#include <utils/Debug.h>
-
-#include "src/header.h"
-#include "src/api.h"
-
-template<typename T> static int ToInt(const T & t)
-{
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(T) == sizeof(int));
- return (int &)t;
-}
-"""
- lines = open("gl2_api_annotated.in").readlines()
- generate_api(lines)
- #lines = open("gl2ext_api.in").readlines()
- #generate_api(lines)
-
-
diff --git a/opengl/libs/GLES2_dbg/generate_caller_cpp.py b/opengl/libs/GLES2_dbg/generate_caller_cpp.py
deleted file mode 100755
index ee4208dd3dbf..000000000000
--- a/opengl/libs/GLES2_dbg/generate_caller_cpp.py
+++ /dev/null
@@ -1,199 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-#
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import sys
-
-externs = []
-
-def generate_caller(lines):
- i = 0
- output = ""
- skipFunctions = []
-
- for line in lines:
- if line.find("API_ENTRY(") >= 0: # a function prototype
- returnType = line[0: line.find(" API_ENTRY(")]
- functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
- parameterList = line[line.find(")(") + 2: line.find(") {")]
-
- #if line.find("*") >= 0:
- # extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList)
- # externs.append(extern)
- # continue
-
- if functionName in skipFunctions:
- sys.stderr.write("!\n! skipping function '%s'\n!\n" % functionName)
- continue
- output += "\
- case glesv2debugger::Message_Function_%s:\n" % functionName
- parameters = parameterList.split(',')
- paramIndex = 0
- if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer
- # add function to list of functions that should be hand written, but generate code anyways
- externs.append(functionName)
- output += "\
- ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\
- break;\n" % (functionName)
- continue
- elif line.find(":out") >= 0 or line.find(":inout") >= 0:
- externs.append(functionName)
- output += "\
- ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\
- break; // annotated output pointers\n" % (functionName)
- continue
-
- if parameterList == "void":
- parameters = []
- arguments = ""
- paramNames = []
- inout = ""
- getData = ""
-
- callerMembers = ""
-
- for parameter in parameters:
- const = parameter.find("const")
- parameter = parameter.replace("const", "")
- parameter = parameter.strip()
- paramType = parameter.split(' ')[0]
- paramName = parameter.split(' ')[1]
- annotation = ""
- if parameter.find(":") >= 0: # has annotation
- assert inout == "" # only one parameter should be annotated
- sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType))
- inout = paramType.split(":")[2]
- annotation = paramType.split(":")[1]
- paramType = paramType.split(":")[0]
- count = 1
- countArg = ""
- if annotation.find("*") >= 0: # [1,n] * param
- count = int(annotation.split("*")[0])
- countArg = annotation.split("*")[1]
- assert countArg in paramNames
- elif annotation in paramNames:
- count = 1
- countArg = annotation
- elif annotation == "GLstring":
- annotation = "strlen(%s)" % (paramName)
- else:
- count = int(annotation)
-
- paramType += "*"
- arguments += "reinterpret_cast<%s>(const_cast<char *>(cmd.data().data()))" % (paramType)
- elif paramType == "GLboolean":
- arguments += "GLboolean(cmd.arg%d())" % (paramIndex)
- else:
- arguments += "static_cast<%s>(cmd.arg%d())" % (paramType, paramIndex)
-
- if paramIndex < len(parameters) - 1:
- arguments += ", "
- if len(arguments) - arguments.rfind("\n") > 60 :
- arguments += "\n\
- "
- if const >= 0:
- paramType = "const " + paramType
- paramNames.append(paramName)
- paramIndex += 1
-
- if returnType == "void":
- output += "\
- dbg->hooks->gl.%s(\n\
- %s);\n\
- break;\n" % (functionName, arguments)
- else:
- output += "\
- msg.set_ret(static_cast<int>(dbg->hooks->gl.%s(\n\
- %s)));\n\
- if (cmd.has_ret())\n\
- ret = reinterpret_cast<int *>(msg.ret());\n\
- break;\n" % (functionName, arguments)
- return output
-
-if __name__ == "__main__":
-
- lines = open("gl2_api_annotated.in").readlines()
- output = generate_caller(lines)
-
- out = open("src/caller.cpp", "w")
- out.write("""\
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-// auto generated by generate_caller_cpp.py
-// implement declarations in caller.h
-
-#include "header.h"
-
-namespace android {
-
-""")
-
- for extern in externs:
- out.write("\
-static const int * GenerateCall_%s(DbgContext * const dbg,\n\
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);\n" % (extern))
- print("\
-static const int * GenerateCall_%s(DbgContext * const dbg,\n\
- const glesv2debugger::Message & cmd,\n\
- glesv2debugger::Message & msg, const int * const prevRet)\n\
-{ assert(0); return prevRet; }\n" % (extern))
-
- out.write(
-"""
-#include "caller.h"
-
-const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- LOGD("GenerateCall function=%u", cmd.function());
- const int * ret = prevRet; // only some functions have return value
- nsecs_t c0 = systemTime(timeMode);
- switch (cmd.function()) {""")
-
- out.write(output)
-
- out.write("""\
- default:
- assert(0);
- }
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_function(cmd.function());
- msg.set_type(glesv2debugger::Message_Type_AfterCall);
- return ret;
-}
-
-}; // name space android {
-""")
-
-
diff --git a/opengl/libs/GLES2_dbg/generate_debug_in.py b/opengl/libs/GLES2_dbg/generate_debug_in.py
deleted file mode 100755
index 1280c6f4f74c..000000000000
--- a/opengl/libs/GLES2_dbg/generate_debug_in.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-#
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-import sys
-
-def append_functions(functions, lines):
- i = 0
- for line in lines:
- if line.find("API_ENTRY(") >= 0: # a function prototype
- returnType = line[0: line.find(" API_ENTRY(")]
- functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
- parameterList = line[line.find(")(") + 2: line.find(") {")]
-
- functions.append(functionName)
- #print functionName
- continue
-
- parameters = parameterList.split(',')
- paramIndex = 0
- if line.find("*") >= 0:
- print "// FIXME: this function has pointers, it should be hand written"
- externs.append("%s Tracing_%s(%s);" % (returnType, functionName, parameterList))
- print "%s Tracing_%s(%s)\n{" % (returnType, functionName, parameterList)
-
- if parameterList == "void":
- parameters = []
-
- arguments = ""
-
- for parameter in parameters:
- parameter = parameter.replace("const", "")
- parameter = parameter.strip()
- paramType = parameter.split(' ')[0]
- paramName = parameter.split(' ')[1]
-
- paramIndex += 1
-
- return functions
-
-
-
-if __name__ == "__main__":
- definedFunctions = []
- lines = open("gl2_api_annotated.in").readlines()
- definedFunctions = append_functions(definedFunctions, lines)
-
- output = open("../debug.in", "w")
- lines = open("../trace.in").readlines()
- output.write("// the following functions are not defined in GLESv2_dbg\n")
- for line in lines:
- functionName = ""
- if line.find("TRACE_GL(") >= 0: # a function prototype
- functionName = line.split(',')[1].strip()
- elif line.find("TRACE_GL_VOID(") >= 0: # a function prototype
- functionName = line[line.find("(") + 1: line.find(",")] #extract GL function name
- else:
- continue
- if functionName in definedFunctions:
- #print functionName
- continue
- else:
- output.write(line)
-
diff --git a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py b/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
deleted file mode 100755
index 535b13e185de..000000000000
--- a/opengl/libs/GLES2_dbg/generate_debugger_message_proto.py
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-#
-# Copyright 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import os
-
-def generate_egl_entries(output, lines, i):
- for line in lines:
- if line.find("EGL_ENTRY(") >= 0:
- line = line.split(",")[1].strip() #extract EGL function name
- output.write(" %s = %d;\n" % (line, i))
- i += 1
- return i
-
-
-def generate_gl_entries(output,lines,i):
- for line in lines:
- if line.find("API_ENTRY(") >= 0:
- line = line[line.find("(") + 1: line.find(")")] #extract GL function name
- output.write(" %s = %d;\n" % (line, i))
- i += 1
- return i
-
-
-if __name__ == "__main__":
- output = open("debugger_message.proto",'w')
- output.write("""\
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// do not edit; auto generated by generate_debugger_message_proto.py
-
-package com.android.glesv2debugger;
-
-option optimize_for = LITE_RUNTIME;
-
-message Message
-{
- required int32 context_id = 1; // GL context id
- enum Function
- {
-""")
-
- i = 0;
-
- lines = open("gl2_api_annotated.in").readlines()
- i = generate_gl_entries(output, lines, i)
- output.write(" // end of GL functions\n")
-
- #lines = open("gl2ext_api.in").readlines()
- #i = generate_gl_entries(output, lines, i)
- #output.write(" // end of GL EXT functions\n")
-
- lines = open("../EGL/egl_entries.in").readlines()
- i = generate_egl_entries(output, lines, i)
- output.write(" // end of GL EXT functions\n")
-
- output.write(" ACK = %d;\n" % (i))
- i += 1
-
- output.write(" NEG = %d;\n" % (i))
- i += 1
-
- output.write(" CONTINUE = %d;\n" % (i))
- i += 1
-
- output.write(" SKIP = %d;\n" % (i))
- i += 1
-
- output.write(" SETPROP = %d;\n" % (i))
- i += 1
-
- output.write(""" }
- required Function function = 2 [default = NEG]; // type/function of message
- enum Type
- {
- BeforeCall = 0;
- AfterCall = 1;
- AfterGeneratedCall = 2;
- Response = 3; // currently used for misc messages
- CompleteCall = 4; // BeforeCall and AfterCall merged
- }
- required Type type = 3;
- required bool expect_response = 4;
- optional int32 ret = 5; // return value from previous GL call
- optional int32 arg0 = 6; // args to GL call
- optional int32 arg1 = 7;
- optional int32 arg2 = 8;
- optional int32 arg3 = 9;
- optional int32 arg4 = 16;
- optional int32 arg5 = 17;
- optional int32 arg6 = 18;
- optional int32 arg7 = 19; // glDrawArrays/Elements sets this to active number of attributes
- optional int32 arg8 = 20;
-
- optional bytes data = 10; // variable length data used for GL call
- enum DataType
- {
- ReferencedImage = 0; // for image sourced from ReadPixels
- NonreferencedImage = 1; // for image sourced from ReadPixels
- };
- // most data types can be inferred from function
- optional DataType data_type = 23;
- // these are used for image data when they cannot be determined from args
- optional int32 pixel_format = 24;
- optional int32 pixel_type = 25;
- optional int32 image_width = 26;
- optional int32 image_height = 27;
-
- optional float time = 11; // duration of previous GL call (ms)
- enum Prop
- {
- CaptureDraw = 0; // arg0 = number of glDrawArrays/Elements to glReadPixels
- TimeMode = 1; // arg0 = SYSTEM_TIME_* in utils/Timers.h
- ExpectResponse = 2; // arg0 = enum Function, arg1 = true/false
- CaptureSwap = 3; // arg0 = number of eglSwapBuffers to glReadPixels
- GLConstant = 4; // arg0 = GLenum, arg1 = constant; send GL impl. constants
- };
- optional Prop prop = 21; // used with SETPROP, value in arg0
- optional float clock = 22; // wall clock in seconds
-}
-""")
-
- output.close()
-
- os.system("aprotoc --cpp_out=src --java_out=../../../../../development/tools/glesv2debugger/src debugger_message.proto")
- os.system('mv -f "src/debugger_message.pb.cc" "src/debugger_message.pb.cpp"')
diff --git a/opengl/libs/GLES2_dbg/gl2_api_annotated.in b/opengl/libs/GLES2_dbg/gl2_api_annotated.in
deleted file mode 100644
index 227e2ebbe3a7..000000000000
--- a/opengl/libs/GLES2_dbg/gl2_api_annotated.in
+++ /dev/null
@@ -1,426 +0,0 @@
-void API_ENTRY(glActiveTexture)(GLenum texture) {
- CALL_GL_API(glActiveTexture, texture);
-}
-void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
- CALL_GL_API(glAttachShader, program, shader);
-}
-void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const GLchar:GLstring:in name) {
- CALL_GL_API(glBindAttribLocation, program, index, name);
-}
-void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
- CALL_GL_API(glBindBuffer, target, buffer);
-}
-void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer) {
- CALL_GL_API(glBindFramebuffer, target, framebuffer);
-}
-void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) {
- CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
-}
-void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
- CALL_GL_API(glBindTexture, target, texture);
-}
-void API_ENTRY(glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
- CALL_GL_API(glBlendColor, red, green, blue, alpha);
-}
-void API_ENTRY(glBlendEquation)( GLenum mode ) {
- CALL_GL_API(glBlendEquation, mode);
-}
-void API_ENTRY(glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha) {
- CALL_GL_API(glBlendEquationSeparate, modeRGB, modeAlpha);
-}
-void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
- CALL_GL_API(glBlendFunc, sfactor, dfactor);
-}
-void API_ENTRY(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
- CALL_GL_API(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid:size:in data, GLenum usage) {
- CALL_GL_API(glBufferData, target, size, data, usage);
-}
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid:size:in data) {
- CALL_GL_API(glBufferSubData, target, offset, size, data);
-}
-GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) {
- CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
-}
-void API_ENTRY(glClear)(GLbitfield mask) {
- CALL_GL_API(glClear, mask);
-}
-void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
- CALL_GL_API(glClearColor, red, green, blue, alpha);
-}
-void API_ENTRY(glClearDepthf)(GLclampf depth) {
- CALL_GL_API(glClearDepthf, depth);
-}
-void API_ENTRY(glClearStencil)(GLint s) {
- CALL_GL_API(glClearStencil, s);
-}
-void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
- CALL_GL_API(glColorMask, red, green, blue, alpha);
-}
-void API_ENTRY(glCompileShader)(GLuint shader) {
- CALL_GL_API(glCompileShader, shader);
-}
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
- CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
-}
-void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
- CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
-}
-void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
- CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, width, height, border);
-}
-void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
-}
-GLuint API_ENTRY(glCreateProgram)(void) {
- CALL_GL_API_RETURN(glCreateProgram);
-}
-GLuint API_ENTRY(glCreateShader)(GLenum type) {
- CALL_GL_API_RETURN(glCreateShader, type);
-}
-void API_ENTRY(glCullFace)(GLenum mode) {
- CALL_GL_API(glCullFace, mode);
-}
-void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint:n:in buffers) {
- CALL_GL_API(glDeleteBuffers, n, buffers);
-}
-void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint:n:in framebuffers) {
- CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
-}
-void API_ENTRY(glDeleteProgram)(GLuint program) {
- CALL_GL_API(glDeleteProgram, program);
-}
-void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint:n:in renderbuffers) {
- CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
-}
-void API_ENTRY(glDeleteShader)(GLuint shader) {
- CALL_GL_API(glDeleteShader, shader);
-}
-void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint:n:in textures) {
- CALL_GL_API(glDeleteTextures, n, textures);
-}
-void API_ENTRY(glDepthFunc)(GLenum func) {
- CALL_GL_API(glDepthFunc, func);
-}
-void API_ENTRY(glDepthMask)(GLboolean flag) {
- CALL_GL_API(glDepthMask, flag);
-}
-void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
- CALL_GL_API(glDepthRangef, zNear, zFar);
-}
-void API_ENTRY(glDetachShader)(GLuint program, GLuint shader) {
- CALL_GL_API(glDetachShader, program, shader);
-}
-void API_ENTRY(glDisable)(GLenum cap) {
- CALL_GL_API(glDisable, cap);
-}
-void API_ENTRY(glDisableVertexAttribArray)(GLuint index) {
- CALL_GL_API(glDisableVertexAttribArray, index);
-}
-void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
- CALL_GL_API(glDrawArrays, mode, first, count);
-}
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
- CALL_GL_API(glDrawElements, mode, count, type, indices);
-}
-void API_ENTRY(glEnable)(GLenum cap) {
- CALL_GL_API(glEnable, cap);
-}
-void API_ENTRY(glEnableVertexAttribArray)(GLuint index) {
- CALL_GL_API(glEnableVertexAttribArray, index);
-}
-void API_ENTRY(glFinish)(void) {
- CALL_GL_API(glFinish);
-}
-void API_ENTRY(glFlush)(void) {
- CALL_GL_API(glFlush);
-}
-void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
- CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
-}
-void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
- CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
-}
-void API_ENTRY(glFrontFace)(GLenum mode) {
- CALL_GL_API(glFrontFace, mode);
-}
-void API_ENTRY(glGenBuffers)(GLsizei n, GLuint:n:out buffers) {
- CALL_GL_API(glGenBuffers, n, buffers);
-}
-void API_ENTRY(glGenerateMipmap)(GLenum target) {
- CALL_GL_API(glGenerateMipmap, target);
-}
-void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint:n:out framebuffers) {
- CALL_GL_API(glGenFramebuffers, n, framebuffers);
-}
-void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint:n:out renderbuffers) {
- CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
-}
-void API_ENTRY(glGenTextures)(GLsizei n, GLuint:n:out textures) {
- CALL_GL_API(glGenTextures, n, textures);
-}
-void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar:GLstring:in name) {
- CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
-}
-void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar:GLstring:in name) {
- CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
-}
-void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
- CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
-}
-int API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar:GLstring:in name) {
- CALL_GL_API_RETURN(glGetAttribLocation, program, name);
-}
-void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params) {
- CALL_GL_API(glGetBooleanv, pname, params);
-}
-void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
- CALL_GL_API(glGetBufferParameteriv, target, pname, params);
-}
-GLenum API_ENTRY(glGetError)(void) {
- CALL_GL_API_RETURN(glGetError);
-}
-void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params) {
- CALL_GL_API(glGetFloatv, pname, params);
-}
-void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
- CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
-}
-void API_ENTRY(glGetIntegerv)(GLenum pname, GLint* params) {
- CALL_GL_API(glGetIntegerv, pname, params);
-}
-void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint:1:out params) {
- CALL_GL_API(glGetProgramiv, program, pname, params);
-}
-void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, GLchar:GLstring:out infolog) {
- CALL_GL_API(glGetProgramInfoLog, program, bufsize, length, infolog);
-}
-void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
- CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint:1:out params) {
- CALL_GL_API(glGetShaderiv, shader, pname, params);
-}
-void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar:GLstring:out infolog) {
- CALL_GL_API(glGetShaderInfoLog, shader, bufsize, length, infolog);
-}
-void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
- CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
-}
-void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar:GLstring:out source) {
- CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
-}
-const GLubyte* API_ENTRY(glGetString)(GLenum name) {
- CALL_GL_API_RETURN(glGetString, name);
-}
-void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params) {
- CALL_GL_API(glGetTexParameterfv, target, pname, params);
-}
-void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params) {
- CALL_GL_API(glGetTexParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params) {
- CALL_GL_API(glGetUniformfv, program, location, params);
-}
-void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params) {
- CALL_GL_API(glGetUniformiv, program, location, params);
-}
-int API_ENTRY(glGetUniformLocation)(GLuint program, const GLchar:GLstring:in name) {
- CALL_GL_API_RETURN(glGetUniformLocation, program, name);
-}
-void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params) {
- CALL_GL_API(glGetVertexAttribfv, index, pname, params);
-}
-void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params) {
- CALL_GL_API(glGetVertexAttribiv, index, pname, params);
-}
-void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer) {
- CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
-}
-void API_ENTRY(glHint)(GLenum target, GLenum mode) {
- CALL_GL_API(glHint, target, mode);
-}
-GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
- CALL_GL_API_RETURN(glIsBuffer, buffer);
-}
-GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
- CALL_GL_API_RETURN(glIsEnabled, cap);
-}
-GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer) {
- CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
-}
-GLboolean API_ENTRY(glIsProgram)(GLuint program) {
- CALL_GL_API_RETURN(glIsProgram, program);
-}
-GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer) {
- CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
-}
-GLboolean API_ENTRY(glIsShader)(GLuint shader) {
- CALL_GL_API_RETURN(glIsShader, shader);
-}
-GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
- CALL_GL_API_RETURN(glIsTexture, texture);
-}
-void API_ENTRY(glLineWidth)(GLfloat width) {
- CALL_GL_API(glLineWidth, width);
-}
-void API_ENTRY(glLinkProgram)(GLuint program) {
- CALL_GL_API(glLinkProgram, program);
-}
-void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
- CALL_GL_API(glPixelStorei, pname, param);
-}
-void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
- CALL_GL_API(glPolygonOffset, factor, units);
-}
-void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
- CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
-}
-void API_ENTRY(glReleaseShaderCompiler)(void) {
- CALL_GL_API(glReleaseShaderCompiler);
-}
-void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
- CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
-}
-void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
- CALL_GL_API(glSampleCoverage, value, invert);
-}
-void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glScissor, x, y, width, height);
-}
-void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) {
- CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
-}
-void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
- CALL_GL_API(glShaderSource, shader, count, string, length);
-}
-void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
- CALL_GL_API(glStencilFunc, func, ref, mask);
-}
-void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask) {
- CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
-}
-void API_ENTRY(glStencilMask)(GLuint mask) {
- CALL_GL_API(glStencilMask, mask);
-}
-void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask) {
- CALL_GL_API(glStencilMaskSeparate, face, mask);
-}
-void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
- CALL_GL_API(glStencilOp, fail, zfail, zpass);
-}
-void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
- CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
-}
-void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
- CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
-}
-void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
- CALL_GL_API(glTexParameterf, target, pname, param);
-}
-void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params) {
- CALL_GL_API(glTexParameterfv, target, pname, params);
-}
-void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
- CALL_GL_API(glTexParameteri, target, pname, param);
-}
-void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params) {
- CALL_GL_API(glTexParameteriv, target, pname, params);
-}
-void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
- CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-void API_ENTRY(glUniform1f)(GLint location, GLfloat x) {
- CALL_GL_API(glUniform1f, location, x);
-}
-void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat:1*count:in v) {
- CALL_GL_API(glUniform1fv, location, count, v);
-}
-void API_ENTRY(glUniform1i)(GLint location, GLint x) {
- CALL_GL_API(glUniform1i, location, x);
-}
-void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint:1*count:in v) {
- CALL_GL_API(glUniform1iv, location, count, v);
-}
-void API_ENTRY(glUniform2f)(GLint location, GLfloat x, GLfloat y) {
- CALL_GL_API(glUniform2f, location, x, y);
-}
-void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat:2*count:in v) {
- CALL_GL_API(glUniform2fv, location, count, v);
-}
-void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y) {
- CALL_GL_API(glUniform2i, location, x, y);
-}
-void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint:2*count:in v) {
- CALL_GL_API(glUniform2iv, location, count, v);
-}
-void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glUniform3f, location, x, y, z);
-}
-void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat:3*count:in v) {
- CALL_GL_API(glUniform3fv, location, count, v);
-}
-void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z) {
- CALL_GL_API(glUniform3i, location, x, y, z);
-}
-void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint:3*count:in v) {
- CALL_GL_API(glUniform3iv, location, count, v);
-}
-void API_ENTRY(glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
- CALL_GL_API(glUniform4f, location, x, y, z, w);
-}
-void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat:4*count:in v) {
- CALL_GL_API(glUniform4fv, location, count, v);
-}
-void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w) {
- CALL_GL_API(glUniform4i, location, x, y, z, w);
-}
-void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint:4*count:in v) {
- CALL_GL_API(glUniform4iv, location, count, v);
-}
-void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat:4*count:in value) {
- CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat:9*count:in value) {
- CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat:16*count:in value) {
- CALL_GL_API(glUniformMatrix4fv, location, count, transpose, value);
-}
-void API_ENTRY(glUseProgram)(GLuint program) {
- CALL_GL_API(glUseProgram, program);
-}
-void API_ENTRY(glValidateProgram)(GLuint program) {
- CALL_GL_API(glValidateProgram, program);
-}
-void API_ENTRY(glVertexAttrib1f)(GLuint indx, GLfloat x) {
- CALL_GL_API(glVertexAttrib1f, indx, x);
-}
-void API_ENTRY(glVertexAttrib1fv)(GLuint indx, const GLfloat:1:in values) {
- CALL_GL_API(glVertexAttrib1fv, indx, values);
-}
-void API_ENTRY(glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y) {
- CALL_GL_API(glVertexAttrib2f, indx, x, y);
-}
-void API_ENTRY(glVertexAttrib2fv)(GLuint indx, const GLfloat:2:in values) {
- CALL_GL_API(glVertexAttrib2fv, indx, values);
-}
-void API_ENTRY(glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glVertexAttrib3f, indx, x, y, z);
-}
-void API_ENTRY(glVertexAttrib3fv)(GLuint indx, const GLfloat:3:in values) {
- CALL_GL_API(glVertexAttrib3fv, indx, values);
-}
-void API_ENTRY(glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
- CALL_GL_API(glVertexAttrib4f, indx, x, y, z, w);
-}
-void API_ENTRY(glVertexAttrib4fv)(GLuint indx, const GLfloat:4:in values) {
- CALL_GL_API(glVertexAttrib4fv, indx, values);
-}
-void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) {
- CALL_GL_API(glVertexAttribPointer, indx, size, type, normalized, stride, ptr);
-}
-void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glViewport, x, y, width, height);
-}
diff --git a/opengl/libs/GLES2_dbg/src/api.cpp b/opengl/libs/GLES2_dbg/src/api.cpp
deleted file mode 100644
index c4835478d2d7..000000000000
--- a/opengl/libs/GLES2_dbg/src/api.cpp
+++ /dev/null
@@ -1,3540 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-// auto generated by generate_api_cpp.py
-
-#include <utils/Debug.h>
-
-#include "src/header.h"
-#include "src/api.h"
-
-template<typename T> static int ToInt(const T & t)
-{
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(T) == sizeof(int));
- return (int &)t;
-}
-
-void Debug_glActiveTexture(GLenum texture)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum texture;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glActiveTexture(texture);
- return 0;
- }
- } caller;
- caller.texture = texture;
-
- msg.set_arg0(texture);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glActiveTexture);
-}
-
-void Debug_glAttachShader(GLuint program, GLuint shader)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLuint shader;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glAttachShader(program, shader);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.shader = shader;
-
- msg.set_arg0(program);
- msg.set_arg1(shader);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glAttachShader);
-}
-
-void Debug_glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLuint index;
- const GLchar* name;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBindAttribLocation(program, index, name);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.index = index;
- caller.name = name;
-
- msg.set_arg0(program);
- msg.set_arg1(index);
- msg.set_arg2(ToInt(name));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindAttribLocation);
-}
-
-void Debug_glBindBuffer(GLenum target, GLuint buffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLuint buffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBindBuffer(target, buffer);
- getDbgContextThreadSpecific()->glBindBuffer(target, buffer);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.buffer = buffer;
-
- msg.set_arg0(target);
- msg.set_arg1(buffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindBuffer);
-}
-
-void Debug_glBindFramebuffer(GLenum target, GLuint framebuffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLuint framebuffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBindFramebuffer(target, framebuffer);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.framebuffer = framebuffer;
-
- msg.set_arg0(target);
- msg.set_arg1(framebuffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindFramebuffer);
-}
-
-void Debug_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLuint renderbuffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBindRenderbuffer(target, renderbuffer);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.renderbuffer = renderbuffer;
-
- msg.set_arg0(target);
- msg.set_arg1(renderbuffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindRenderbuffer);
-}
-
-void Debug_glBindTexture(GLenum target, GLuint texture)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLuint texture;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBindTexture(target, texture);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.texture = texture;
-
- msg.set_arg0(target);
- msg.set_arg1(texture);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindTexture);
-}
-
-void Debug_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLclampf red;
- GLclampf green;
- GLclampf blue;
- GLclampf alpha;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBlendColor(red, green, blue, alpha);
- return 0;
- }
- } caller;
- caller.red = red;
- caller.green = green;
- caller.blue = blue;
- caller.alpha = alpha;
-
- msg.set_arg0(ToInt(red));
- msg.set_arg1(ToInt(green));
- msg.set_arg2(ToInt(blue));
- msg.set_arg3(ToInt(alpha));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendColor);
-}
-
-void Debug_glBlendEquation( GLenum mode )
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum mode;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBlendEquation(mode);
- return 0;
- }
- } caller;
- caller.mode = mode;
-
- msg.set_arg0(mode);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendEquation);
-}
-
-void Debug_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum modeRGB;
- GLenum modeAlpha;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBlendEquationSeparate(modeRGB, modeAlpha);
- return 0;
- }
- } caller;
- caller.modeRGB = modeRGB;
- caller.modeAlpha = modeAlpha;
-
- msg.set_arg0(modeRGB);
- msg.set_arg1(modeAlpha);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendEquationSeparate);
-}
-
-void Debug_glBlendFunc(GLenum sfactor, GLenum dfactor)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum sfactor;
- GLenum dfactor;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBlendFunc(sfactor, dfactor);
- return 0;
- }
- } caller;
- caller.sfactor = sfactor;
- caller.dfactor = dfactor;
-
- msg.set_arg0(sfactor);
- msg.set_arg1(dfactor);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendFunc);
-}
-
-void Debug_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum srcRGB;
- GLenum dstRGB;
- GLenum srcAlpha;
- GLenum dstAlpha;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
- return 0;
- }
- } caller;
- caller.srcRGB = srcRGB;
- caller.dstRGB = dstRGB;
- caller.srcAlpha = srcAlpha;
- caller.dstAlpha = dstAlpha;
-
- msg.set_arg0(srcRGB);
- msg.set_arg1(dstRGB);
- msg.set_arg2(srcAlpha);
- msg.set_arg3(dstAlpha);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendFuncSeparate);
-}
-
-void Debug_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLsizeiptr size;
- const GLvoid* data;
- GLenum usage;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBufferData(target, size, data, usage);
- getDbgContextThreadSpecific()->glBufferData(target, size, data, usage);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.size = size;
- caller.data = data;
- caller.usage = usage;
-
- msg.set_arg0(target);
- msg.set_arg1(size);
- msg.set_arg2(ToInt(data));
- msg.set_arg3(usage);
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBufferData);
-}
-
-void Debug_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLintptr offset;
- GLsizeiptr size;
- const GLvoid* data;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glBufferSubData(target, offset, size, data);
- getDbgContextThreadSpecific()->glBufferSubData(target, offset, size, data);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.offset = offset;
- caller.size = size;
- caller.data = data;
-
- msg.set_arg0(target);
- msg.set_arg1(offset);
- msg.set_arg2(size);
- msg.set_arg3(ToInt(data));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBufferSubData);
-}
-
-GLenum Debug_glCheckFramebufferStatus(GLenum target)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glCheckFramebufferStatus(target));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.target = target;
-
- msg.set_arg0(target);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCheckFramebufferStatus);
- return reinterpret_cast<GLenum>(ret);
-}
-
-void Debug_glClear(GLbitfield mask)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLbitfield mask;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glClear(mask);
- return 0;
- }
- } caller;
- caller.mask = mask;
-
- msg.set_arg0(mask);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClear);
-}
-
-void Debug_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLclampf red;
- GLclampf green;
- GLclampf blue;
- GLclampf alpha;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glClearColor(red, green, blue, alpha);
- return 0;
- }
- } caller;
- caller.red = red;
- caller.green = green;
- caller.blue = blue;
- caller.alpha = alpha;
-
- msg.set_arg0(ToInt(red));
- msg.set_arg1(ToInt(green));
- msg.set_arg2(ToInt(blue));
- msg.set_arg3(ToInt(alpha));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearColor);
-}
-
-void Debug_glClearDepthf(GLclampf depth)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLclampf depth;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glClearDepthf(depth);
- return 0;
- }
- } caller;
- caller.depth = depth;
-
- msg.set_arg0(ToInt(depth));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearDepthf);
-}
-
-void Debug_glClearStencil(GLint s)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint s;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glClearStencil(s);
- return 0;
- }
- } caller;
- caller.s = s;
-
- msg.set_arg0(s);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearStencil);
-}
-
-void Debug_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLboolean red;
- GLboolean green;
- GLboolean blue;
- GLboolean alpha;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glColorMask(red, green, blue, alpha);
- return 0;
- }
- } caller;
- caller.red = red;
- caller.green = green;
- caller.blue = blue;
- caller.alpha = alpha;
-
- msg.set_arg0(red);
- msg.set_arg1(green);
- msg.set_arg2(blue);
- msg.set_arg3(alpha);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glColorMask);
-}
-
-void Debug_glCompileShader(GLuint shader)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glCompileShader(shader);
- return 0;
- }
- } caller;
- caller.shader = shader;
-
- msg.set_arg0(shader);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompileShader);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLint level;
- GLenum internalformat;
- GLsizei width;
- GLsizei height;
- GLint border;
- GLsizei imageSize;
- const GLvoid* data;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.level = level;
- caller.internalformat = internalformat;
- caller.width = width;
- caller.height = height;
- caller.border = border;
- caller.imageSize = imageSize;
- caller.data = data;
-
- msg.set_arg0(target);
- msg.set_arg1(level);
- msg.set_arg2(internalformat);
- msg.set_arg3(width);
- msg.set_arg4(height);
- msg.set_arg5(border);
- msg.set_arg6(imageSize);
- msg.set_arg7(ToInt(data));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompressedTexImage2D);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLint level;
- GLint xoffset;
- GLint yoffset;
- GLsizei width;
- GLsizei height;
- GLenum format;
- GLsizei imageSize;
- const GLvoid* data;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.level = level;
- caller.xoffset = xoffset;
- caller.yoffset = yoffset;
- caller.width = width;
- caller.height = height;
- caller.format = format;
- caller.imageSize = imageSize;
- caller.data = data;
-
- msg.set_arg0(target);
- msg.set_arg1(level);
- msg.set_arg2(xoffset);
- msg.set_arg3(yoffset);
- msg.set_arg4(width);
- msg.set_arg5(height);
- msg.set_arg6(format);
- msg.set_arg7(imageSize);
- msg.set_arg8(ToInt(data));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompressedTexSubImage2D);
-}
-
-void Debug_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLint level;
- GLenum internalformat;
- GLint x;
- GLint y;
- GLsizei width;
- GLsizei height;
- GLint border;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
-#ifdef EXTEND_AFTER_CALL_Debug_glCopyTexImage2D
- EXTEND_AFTER_CALL_Debug_glCopyTexImage2D;
-#endif
- return 0;
- }
- } caller;
- caller.target = target;
- caller.level = level;
- caller.internalformat = internalformat;
- caller.x = x;
- caller.y = y;
- caller.width = width;
- caller.height = height;
- caller.border = border;
-
- msg.set_arg0(target);
- msg.set_arg1(level);
- msg.set_arg2(internalformat);
- msg.set_arg3(x);
- msg.set_arg4(y);
- msg.set_arg5(width);
- msg.set_arg6(height);
- msg.set_arg7(border);
-
-#ifdef EXTEND_Debug_glCopyTexImage2D
- EXTEND_Debug_glCopyTexImage2D;
-#endif
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCopyTexImage2D);
-}
-
-void Debug_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLint level;
- GLint xoffset;
- GLint yoffset;
- GLint x;
- GLint y;
- GLsizei width;
- GLsizei height;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-#ifdef EXTEND_AFTER_CALL_Debug_glCopyTexSubImage2D
- EXTEND_AFTER_CALL_Debug_glCopyTexSubImage2D;
-#endif
- return 0;
- }
- } caller;
- caller.target = target;
- caller.level = level;
- caller.xoffset = xoffset;
- caller.yoffset = yoffset;
- caller.x = x;
- caller.y = y;
- caller.width = width;
- caller.height = height;
-
- msg.set_arg0(target);
- msg.set_arg1(level);
- msg.set_arg2(xoffset);
- msg.set_arg3(yoffset);
- msg.set_arg4(x);
- msg.set_arg5(y);
- msg.set_arg6(width);
- msg.set_arg7(height);
-
-#ifdef EXTEND_Debug_glCopyTexSubImage2D
- EXTEND_Debug_glCopyTexSubImage2D;
-#endif
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCopyTexSubImage2D);
-}
-
-GLuint Debug_glCreateProgram(void)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glCreateProgram());
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
-
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCreateProgram);
- return reinterpret_cast<GLuint>(ret);
-}
-
-GLuint Debug_glCreateShader(GLenum type)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum type;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glCreateShader(type));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.type = type;
-
- msg.set_arg0(type);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCreateShader);
- return reinterpret_cast<GLuint>(ret);
-}
-
-void Debug_glCullFace(GLenum mode)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum mode;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glCullFace(mode);
- return 0;
- }
- } caller;
- caller.mode = mode;
-
- msg.set_arg0(mode);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCullFace);
-}
-
-void Debug_glDeleteBuffers(GLsizei n, const GLuint* buffers)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- const GLuint* buffers;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDeleteBuffers(n, buffers);
- getDbgContextThreadSpecific()->glDeleteBuffers(n, buffers);
- return 0;
- }
- } caller;
- caller.n = n;
- caller.buffers = buffers;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(buffers));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteBuffers);
-}
-
-void Debug_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- const GLuint* framebuffers;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDeleteFramebuffers(n, framebuffers);
- return 0;
- }
- } caller;
- caller.n = n;
- caller.framebuffers = framebuffers;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(framebuffers));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteFramebuffers);
-}
-
-void Debug_glDeleteProgram(GLuint program)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDeleteProgram(program);
- return 0;
- }
- } caller;
- caller.program = program;
-
- msg.set_arg0(program);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteProgram);
-}
-
-void Debug_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- const GLuint* renderbuffers;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDeleteRenderbuffers(n, renderbuffers);
- return 0;
- }
- } caller;
- caller.n = n;
- caller.renderbuffers = renderbuffers;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(renderbuffers));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteRenderbuffers);
-}
-
-void Debug_glDeleteShader(GLuint shader)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDeleteShader(shader);
- return 0;
- }
- } caller;
- caller.shader = shader;
-
- msg.set_arg0(shader);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteShader);
-}
-
-void Debug_glDeleteTextures(GLsizei n, const GLuint* textures)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- const GLuint* textures;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDeleteTextures(n, textures);
- return 0;
- }
- } caller;
- caller.n = n;
- caller.textures = textures;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(textures));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteTextures);
-}
-
-void Debug_glDepthFunc(GLenum func)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum func;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDepthFunc(func);
- return 0;
- }
- } caller;
- caller.func = func;
-
- msg.set_arg0(func);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthFunc);
-}
-
-void Debug_glDepthMask(GLboolean flag)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLboolean flag;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDepthMask(flag);
- return 0;
- }
- } caller;
- caller.flag = flag;
-
- msg.set_arg0(flag);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthMask);
-}
-
-void Debug_glDepthRangef(GLclampf zNear, GLclampf zFar)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLclampf zNear;
- GLclampf zFar;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDepthRangef(zNear, zFar);
- return 0;
- }
- } caller;
- caller.zNear = zNear;
- caller.zFar = zFar;
-
- msg.set_arg0(ToInt(zNear));
- msg.set_arg1(ToInt(zFar));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthRangef);
-}
-
-void Debug_glDetachShader(GLuint program, GLuint shader)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLuint shader;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDetachShader(program, shader);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.shader = shader;
-
- msg.set_arg0(program);
- msg.set_arg1(shader);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDetachShader);
-}
-
-void Debug_glDisable(GLenum cap)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum cap;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDisable(cap);
- return 0;
- }
- } caller;
- caller.cap = cap;
-
- msg.set_arg0(cap);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDisable);
-}
-
-void Debug_glDisableVertexAttribArray(GLuint index)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint index;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glDisableVertexAttribArray(index);
- getDbgContextThreadSpecific()->glDisableVertexAttribArray(index);
- return 0;
- }
- } caller;
- caller.index = index;
-
- msg.set_arg0(index);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDisableVertexAttribArray);
-}
-
-void Debug_glEnable(GLenum cap)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum cap;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glEnable(cap);
- return 0;
- }
- } caller;
- caller.cap = cap;
-
- msg.set_arg0(cap);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glEnable);
-}
-
-void Debug_glEnableVertexAttribArray(GLuint index)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint index;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glEnableVertexAttribArray(index);
- getDbgContextThreadSpecific()->glEnableVertexAttribArray(index);
- return 0;
- }
- } caller;
- caller.index = index;
-
- msg.set_arg0(index);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glEnableVertexAttribArray);
-}
-
-void Debug_glFinish(void)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glFinish();
- return 0;
- }
- } caller;
-
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFinish);
-}
-
-void Debug_glFlush(void)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glFlush();
- return 0;
- }
- } caller;
-
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFlush);
-}
-
-void Debug_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum attachment;
- GLenum renderbuffertarget;
- GLuint renderbuffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.attachment = attachment;
- caller.renderbuffertarget = renderbuffertarget;
- caller.renderbuffer = renderbuffer;
-
- msg.set_arg0(target);
- msg.set_arg1(attachment);
- msg.set_arg2(renderbuffertarget);
- msg.set_arg3(renderbuffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFramebufferRenderbuffer);
-}
-
-void Debug_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum attachment;
- GLenum textarget;
- GLuint texture;
- GLint level;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glFramebufferTexture2D(target, attachment, textarget, texture, level);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.attachment = attachment;
- caller.textarget = textarget;
- caller.texture = texture;
- caller.level = level;
-
- msg.set_arg0(target);
- msg.set_arg1(attachment);
- msg.set_arg2(textarget);
- msg.set_arg3(texture);
- msg.set_arg4(level);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFramebufferTexture2D);
-}
-
-void Debug_glFrontFace(GLenum mode)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum mode;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glFrontFace(mode);
- return 0;
- }
- } caller;
- caller.mode = mode;
-
- msg.set_arg0(mode);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFrontFace);
-}
-
-void Debug_glGenBuffers(GLsizei n, GLuint* buffers)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- GLuint* buffers;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGenBuffers(n, buffers);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
- return 0;
- }
- } caller;
- caller.n = n;
- caller.buffers = buffers;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(buffers));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenBuffers);
-}
-
-void Debug_glGenerateMipmap(GLenum target)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGenerateMipmap(target);
- return 0;
- }
- } caller;
- caller.target = target;
-
- msg.set_arg0(target);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenerateMipmap);
-}
-
-void Debug_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- GLuint* framebuffers;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGenFramebuffers(n, framebuffers);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
- return 0;
- }
- } caller;
- caller.n = n;
- caller.framebuffers = framebuffers;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(framebuffers));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenFramebuffers);
-}
-
-void Debug_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- GLuint* renderbuffers;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGenRenderbuffers(n, renderbuffers);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
- return 0;
- }
- } caller;
- caller.n = n;
- caller.renderbuffers = renderbuffers;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(renderbuffers));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenRenderbuffers);
-}
-
-void Debug_glGenTextures(GLsizei n, GLuint* textures)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- GLuint* textures;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGenTextures(n, textures);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
- return 0;
- }
- } caller;
- caller.n = n;
- caller.textures = textures;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(textures));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenTextures);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLuint index;
- GLsizei bufsize;
- GLsizei* length;
- GLint* size;
- GLenum* type;
- GLchar* name;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetActiveAttrib(program, index, bufsize, length, size, type, name);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.index = index;
- caller.bufsize = bufsize;
- caller.length = length;
- caller.size = size;
- caller.type = type;
- caller.name = name;
-
- msg.set_arg0(program);
- msg.set_arg1(index);
- msg.set_arg2(bufsize);
- msg.set_arg3(ToInt(length));
- msg.set_arg4(ToInt(size));
- msg.set_arg5(ToInt(type));
- msg.set_arg6(ToInt(name));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetActiveAttrib);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLuint index;
- GLsizei bufsize;
- GLsizei* length;
- GLint* size;
- GLenum* type;
- GLchar* name;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetActiveUniform(program, index, bufsize, length, size, type, name);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.index = index;
- caller.bufsize = bufsize;
- caller.length = length;
- caller.size = size;
- caller.type = type;
- caller.name = name;
-
- msg.set_arg0(program);
- msg.set_arg1(index);
- msg.set_arg2(bufsize);
- msg.set_arg3(ToInt(length));
- msg.set_arg4(ToInt(size));
- msg.set_arg5(ToInt(type));
- msg.set_arg6(ToInt(name));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetActiveUniform);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLsizei maxcount;
- GLsizei* count;
- GLuint* shaders;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetAttachedShaders(program, maxcount, count, shaders);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.maxcount = maxcount;
- caller.count = count;
- caller.shaders = shaders;
-
- msg.set_arg0(program);
- msg.set_arg1(maxcount);
- msg.set_arg2(ToInt(count));
- msg.set_arg3(ToInt(shaders));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetAttachedShaders);
-}
-
-int Debug_glGetAttribLocation(GLuint program, const GLchar* name)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- const GLchar* name;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glGetAttribLocation(program, name));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.program = program;
- caller.name = name;
-
- msg.set_arg0(program);
- msg.set_arg1(ToInt(name));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetAttribLocation);
- return reinterpret_cast<int>(ret);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetBooleanv(GLenum pname, GLboolean* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum pname;
- GLboolean* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetBooleanv(pname, params);
- return 0;
- }
- } caller;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(pname);
- msg.set_arg1(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetBooleanv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetBufferParameteriv(target, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetBufferParameteriv);
-}
-
-GLenum Debug_glGetError(void)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glGetError());
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
-
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetError);
- return reinterpret_cast<GLenum>(ret);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetFloatv(GLenum pname, GLfloat* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum pname;
- GLfloat* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetFloatv(pname, params);
- return 0;
- }
- } caller;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(pname);
- msg.set_arg1(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetFloatv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum attachment;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.attachment = attachment;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(attachment);
- msg.set_arg2(pname);
- msg.set_arg3(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetIntegerv(GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetIntegerv(pname, params);
- return 0;
- }
- } caller;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(pname);
- msg.set_arg1(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetIntegerv);
-}
-
-void Debug_glGetProgramiv(GLuint program, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGetProgramiv(program, pname, params);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(params), 1 * sizeof(GLint));
- return 0;
- }
- } caller;
- caller.program = program;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(program);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetProgramiv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLsizei bufsize;
- GLsizei* length;
- GLchar* infolog;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGetProgramInfoLog(program, bufsize, length, infolog);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(infolog), strlen(infolog) * sizeof(GLchar));
- return 0;
- }
- } caller;
- caller.program = program;
- caller.bufsize = bufsize;
- caller.length = length;
- caller.infolog = infolog;
-
- msg.set_arg0(program);
- msg.set_arg1(bufsize);
- msg.set_arg2(ToInt(length));
- msg.set_arg3(ToInt(infolog));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetProgramInfoLog);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetRenderbufferParameteriv(target, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetRenderbufferParameteriv);
-}
-
-void Debug_glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGetShaderiv(shader, pname, params);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(params), 1 * sizeof(GLint));
- return 0;
- }
- } caller;
- caller.shader = shader;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(shader);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderiv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
- GLsizei bufsize;
- GLsizei* length;
- GLchar* infolog;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGetShaderInfoLog(shader, bufsize, length, infolog);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(infolog), strlen(infolog) * sizeof(GLchar));
- return 0;
- }
- } caller;
- caller.shader = shader;
- caller.bufsize = bufsize;
- caller.length = length;
- caller.infolog = infolog;
-
- msg.set_arg0(shader);
- msg.set_arg1(bufsize);
- msg.set_arg2(ToInt(length));
- msg.set_arg3(ToInt(infolog));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderInfoLog);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum shadertype;
- GLenum precisiontype;
- GLint* range;
- GLint* precision;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
- return 0;
- }
- } caller;
- caller.shadertype = shadertype;
- caller.precisiontype = precisiontype;
- caller.range = range;
- caller.precision = precision;
-
- msg.set_arg0(shadertype);
- msg.set_arg1(precisiontype);
- msg.set_arg2(ToInt(range));
- msg.set_arg3(ToInt(precision));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderPrecisionFormat);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
- GLsizei bufsize;
- GLsizei* length;
- GLchar* source;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- nsecs_t c0 = systemTime(timeMode);
- _c->glGetShaderSource(shader, bufsize, length, source);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.mutable_data()->assign(reinterpret_cast<const char *>(source), strlen(source) * sizeof(GLchar));
- return 0;
- }
- } caller;
- caller.shader = shader;
- caller.bufsize = bufsize;
- caller.length = length;
- caller.source = source;
-
- msg.set_arg0(shader);
- msg.set_arg1(bufsize);
- msg.set_arg2(ToInt(length));
- msg.set_arg3(ToInt(source));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderSource);
-}
-
-// FIXME: this function has pointers, it should be hand written
-const GLubyte* Debug_glGetString(GLenum name)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum name;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glGetString(name));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.name = name;
-
- msg.set_arg0(name);
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetString);
- return reinterpret_cast<const GLubyte*>(ret);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- GLfloat* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetTexParameterfv(target, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetTexParameterfv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetTexParameteriv(target, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetTexParameteriv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLint location;
- GLfloat* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetUniformfv(program, location, params);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.location = location;
- caller.params = params;
-
- msg.set_arg0(program);
- msg.set_arg1(location);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformfv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- GLint location;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetUniformiv(program, location, params);
- return 0;
- }
- } caller;
- caller.program = program;
- caller.location = location;
- caller.params = params;
-
- msg.set_arg0(program);
- msg.set_arg1(location);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformiv);
-}
-
-int Debug_glGetUniformLocation(GLuint program, const GLchar* name)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
- const GLchar* name;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glGetUniformLocation(program, name));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.program = program;
- caller.name = name;
-
- msg.set_arg0(program);
- msg.set_arg1(ToInt(name));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformLocation);
- return reinterpret_cast<int>(ret);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint index;
- GLenum pname;
- GLfloat* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetVertexAttribfv(index, pname, params);
- return 0;
- }
- } caller;
- caller.index = index;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(index);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribfv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint index;
- GLenum pname;
- GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetVertexAttribiv(index, pname, params);
- return 0;
- }
- } caller;
- caller.index = index;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(index);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribiv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint index;
- GLenum pname;
- GLvoid** pointer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glGetVertexAttribPointerv(index, pname, pointer);
- return 0;
- }
- } caller;
- caller.index = index;
- caller.pname = pname;
- caller.pointer = pointer;
-
- msg.set_arg0(index);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(pointer));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribPointerv);
-}
-
-void Debug_glHint(GLenum target, GLenum mode)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum mode;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glHint(target, mode);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.mode = mode;
-
- msg.set_arg0(target);
- msg.set_arg1(mode);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glHint);
-}
-
-GLboolean Debug_glIsBuffer(GLuint buffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint buffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsBuffer(buffer));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.buffer = buffer;
-
- msg.set_arg0(buffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsBuffer);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-GLboolean Debug_glIsEnabled(GLenum cap)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum cap;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsEnabled(cap));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.cap = cap;
-
- msg.set_arg0(cap);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsEnabled);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-GLboolean Debug_glIsFramebuffer(GLuint framebuffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint framebuffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsFramebuffer(framebuffer));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.framebuffer = framebuffer;
-
- msg.set_arg0(framebuffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsFramebuffer);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-GLboolean Debug_glIsProgram(GLuint program)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsProgram(program));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.program = program;
-
- msg.set_arg0(program);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsProgram);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-GLboolean Debug_glIsRenderbuffer(GLuint renderbuffer)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint renderbuffer;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsRenderbuffer(renderbuffer));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.renderbuffer = renderbuffer;
-
- msg.set_arg0(renderbuffer);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsRenderbuffer);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-GLboolean Debug_glIsShader(GLuint shader)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsShader(shader));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.shader = shader;
-
- msg.set_arg0(shader);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsShader);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-GLboolean Debug_glIsTexture(GLuint texture)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint texture;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int * ret = reinterpret_cast<const int *>(_c->glIsTexture(texture));
- msg.set_ret(ToInt(ret));
- return ret;
- }
- } caller;
- caller.texture = texture;
-
- msg.set_arg0(texture);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsTexture);
- return static_cast<GLboolean>(reinterpret_cast<int>(ret));
-}
-
-void Debug_glLineWidth(GLfloat width)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLfloat width;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glLineWidth(width);
- return 0;
- }
- } caller;
- caller.width = width;
-
- msg.set_arg0(ToInt(width));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glLineWidth);
-}
-
-void Debug_glLinkProgram(GLuint program)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glLinkProgram(program);
- return 0;
- }
- } caller;
- caller.program = program;
-
- msg.set_arg0(program);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glLinkProgram);
-}
-
-void Debug_glPixelStorei(GLenum pname, GLint param)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum pname;
- GLint param;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glPixelStorei(pname, param);
- return 0;
- }
- } caller;
- caller.pname = pname;
- caller.param = param;
-
- msg.set_arg0(pname);
- msg.set_arg1(param);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glPixelStorei);
-}
-
-void Debug_glPolygonOffset(GLfloat factor, GLfloat units)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLfloat factor;
- GLfloat units;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glPolygonOffset(factor, units);
- return 0;
- }
- } caller;
- caller.factor = factor;
- caller.units = units;
-
- msg.set_arg0(ToInt(factor));
- msg.set_arg1(ToInt(units));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glPolygonOffset);
-}
-
-void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint x;
- GLint y;
- GLsizei width;
- GLsizei height;
- GLenum format;
- GLenum type;
- GLvoid* pixels;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glReadPixels(x, y, width, height, format, type, pixels);
-#ifdef EXTEND_AFTER_CALL_Debug_glReadPixels
- EXTEND_AFTER_CALL_Debug_glReadPixels;
-#endif
- return 0;
- }
- } caller;
- caller.x = x;
- caller.y = y;
- caller.width = width;
- caller.height = height;
- caller.format = format;
- caller.type = type;
- caller.pixels = pixels;
-
- msg.set_arg0(x);
- msg.set_arg1(y);
- msg.set_arg2(width);
- msg.set_arg3(height);
- msg.set_arg4(format);
- msg.set_arg5(type);
- msg.set_arg6(ToInt(pixels));
-
- // FIXME: check for pointer usage
-#ifdef EXTEND_Debug_glReadPixels
- EXTEND_Debug_glReadPixels;
-#endif
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glReadPixels);
-}
-
-void Debug_glReleaseShaderCompiler(void)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glReleaseShaderCompiler();
- return 0;
- }
- } caller;
-
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glReleaseShaderCompiler);
-}
-
-void Debug_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum internalformat;
- GLsizei width;
- GLsizei height;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glRenderbufferStorage(target, internalformat, width, height);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.internalformat = internalformat;
- caller.width = width;
- caller.height = height;
-
- msg.set_arg0(target);
- msg.set_arg1(internalformat);
- msg.set_arg2(width);
- msg.set_arg3(height);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glRenderbufferStorage);
-}
-
-void Debug_glSampleCoverage(GLclampf value, GLboolean invert)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLclampf value;
- GLboolean invert;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glSampleCoverage(value, invert);
- return 0;
- }
- } caller;
- caller.value = value;
- caller.invert = invert;
-
- msg.set_arg0(ToInt(value));
- msg.set_arg1(invert);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glSampleCoverage);
-}
-
-void Debug_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint x;
- GLint y;
- GLsizei width;
- GLsizei height;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glScissor(x, y, width, height);
- return 0;
- }
- } caller;
- caller.x = x;
- caller.y = y;
- caller.width = width;
- caller.height = height;
-
- msg.set_arg0(x);
- msg.set_arg1(y);
- msg.set_arg2(width);
- msg.set_arg3(height);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glScissor);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLsizei n;
- const GLuint* shaders;
- GLenum binaryformat;
- const GLvoid* binary;
- GLsizei length;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glShaderBinary(n, shaders, binaryformat, binary, length);
- return 0;
- }
- } caller;
- caller.n = n;
- caller.shaders = shaders;
- caller.binaryformat = binaryformat;
- caller.binary = binary;
- caller.length = length;
-
- msg.set_arg0(n);
- msg.set_arg1(ToInt(shaders));
- msg.set_arg2(binaryformat);
- msg.set_arg3(ToInt(binary));
- msg.set_arg4(length);
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glShaderBinary);
-}
-
-void Debug_glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint shader;
- GLsizei count;
- const GLchar** string;
- const GLint* length;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glShaderSource(shader, count, string, length);
-#ifdef EXTEND_AFTER_CALL_Debug_glShaderSource
- EXTEND_AFTER_CALL_Debug_glShaderSource;
-#endif
- return 0;
- }
- } caller;
- caller.shader = shader;
- caller.count = count;
- caller.string = string;
- caller.length = length;
-
- msg.set_arg0(shader);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(string));
- msg.set_arg3(ToInt(length));
-
- // FIXME: check for pointer usage
-#ifdef EXTEND_Debug_glShaderSource
- EXTEND_Debug_glShaderSource;
-#endif
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glShaderSource);
-}
-
-void Debug_glStencilFunc(GLenum func, GLint ref, GLuint mask)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum func;
- GLint ref;
- GLuint mask;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glStencilFunc(func, ref, mask);
- return 0;
- }
- } caller;
- caller.func = func;
- caller.ref = ref;
- caller.mask = mask;
-
- msg.set_arg0(func);
- msg.set_arg1(ref);
- msg.set_arg2(mask);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilFunc);
-}
-
-void Debug_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum face;
- GLenum func;
- GLint ref;
- GLuint mask;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glStencilFuncSeparate(face, func, ref, mask);
- return 0;
- }
- } caller;
- caller.face = face;
- caller.func = func;
- caller.ref = ref;
- caller.mask = mask;
-
- msg.set_arg0(face);
- msg.set_arg1(func);
- msg.set_arg2(ref);
- msg.set_arg3(mask);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilFuncSeparate);
-}
-
-void Debug_glStencilMask(GLuint mask)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint mask;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glStencilMask(mask);
- return 0;
- }
- } caller;
- caller.mask = mask;
-
- msg.set_arg0(mask);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilMask);
-}
-
-void Debug_glStencilMaskSeparate(GLenum face, GLuint mask)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum face;
- GLuint mask;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glStencilMaskSeparate(face, mask);
- return 0;
- }
- } caller;
- caller.face = face;
- caller.mask = mask;
-
- msg.set_arg0(face);
- msg.set_arg1(mask);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilMaskSeparate);
-}
-
-void Debug_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum fail;
- GLenum zfail;
- GLenum zpass;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glStencilOp(fail, zfail, zpass);
- return 0;
- }
- } caller;
- caller.fail = fail;
- caller.zfail = zfail;
- caller.zpass = zpass;
-
- msg.set_arg0(fail);
- msg.set_arg1(zfail);
- msg.set_arg2(zpass);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilOp);
-}
-
-void Debug_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum face;
- GLenum fail;
- GLenum zfail;
- GLenum zpass;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glStencilOpSeparate(face, fail, zfail, zpass);
- return 0;
- }
- } caller;
- caller.face = face;
- caller.fail = fail;
- caller.zfail = zfail;
- caller.zpass = zpass;
-
- msg.set_arg0(face);
- msg.set_arg1(fail);
- msg.set_arg2(zfail);
- msg.set_arg3(zpass);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilOpSeparate);
-}
-
-void Debug_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLint level;
- GLint internalformat;
- GLsizei width;
- GLsizei height;
- GLint border;
- GLenum format;
- GLenum type;
- const GLvoid* pixels;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
-#ifdef EXTEND_AFTER_CALL_Debug_glTexImage2D
- EXTEND_AFTER_CALL_Debug_glTexImage2D;
-#endif
- return 0;
- }
- } caller;
- caller.target = target;
- caller.level = level;
- caller.internalformat = internalformat;
- caller.width = width;
- caller.height = height;
- caller.border = border;
- caller.format = format;
- caller.type = type;
- caller.pixels = pixels;
-
- msg.set_arg0(target);
- msg.set_arg1(level);
- msg.set_arg2(internalformat);
- msg.set_arg3(width);
- msg.set_arg4(height);
- msg.set_arg5(border);
- msg.set_arg6(format);
- msg.set_arg7(type);
- msg.set_arg8(ToInt(pixels));
-
- // FIXME: check for pointer usage
-#ifdef EXTEND_Debug_glTexImage2D
- EXTEND_Debug_glTexImage2D;
-#endif
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexImage2D);
-}
-
-void Debug_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- GLfloat param;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glTexParameterf(target, pname, param);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.param = param;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(param));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameterf);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- const GLfloat* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glTexParameterfv(target, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameterfv);
-}
-
-void Debug_glTexParameteri(GLenum target, GLenum pname, GLint param)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- GLint param;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glTexParameteri(target, pname, param);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.param = param;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(param);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameteri);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLenum pname;
- const GLint* params;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glTexParameteriv(target, pname, params);
- return 0;
- }
- } caller;
- caller.target = target;
- caller.pname = pname;
- caller.params = params;
-
- msg.set_arg0(target);
- msg.set_arg1(pname);
- msg.set_arg2(ToInt(params));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameteriv);
-}
-
-void Debug_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLenum target;
- GLint level;
- GLint xoffset;
- GLint yoffset;
- GLsizei width;
- GLsizei height;
- GLenum format;
- GLenum type;
- const GLvoid* pixels;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-#ifdef EXTEND_AFTER_CALL_Debug_glTexSubImage2D
- EXTEND_AFTER_CALL_Debug_glTexSubImage2D;
-#endif
- return 0;
- }
- } caller;
- caller.target = target;
- caller.level = level;
- caller.xoffset = xoffset;
- caller.yoffset = yoffset;
- caller.width = width;
- caller.height = height;
- caller.format = format;
- caller.type = type;
- caller.pixels = pixels;
-
- msg.set_arg0(target);
- msg.set_arg1(level);
- msg.set_arg2(xoffset);
- msg.set_arg3(yoffset);
- msg.set_arg4(width);
- msg.set_arg5(height);
- msg.set_arg6(format);
- msg.set_arg7(type);
- msg.set_arg8(ToInt(pixels));
-
- // FIXME: check for pointer usage
-#ifdef EXTEND_Debug_glTexSubImage2D
- EXTEND_Debug_glTexSubImage2D;
-#endif
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexSubImage2D);
-}
-
-void Debug_glUniform1f(GLint location, GLfloat x)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLfloat x;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform1f(location, x);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
-
- msg.set_arg0(location);
- msg.set_arg1(ToInt(x));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1f);
-}
-
-void Debug_glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLfloat* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform1fv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1fv);
-}
-
-void Debug_glUniform1i(GLint location, GLint x)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLint x;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform1i(location, x);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
-
- msg.set_arg0(location);
- msg.set_arg1(x);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1i);
-}
-
-void Debug_glUniform1iv(GLint location, GLsizei count, const GLint* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLint* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform1iv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1iv);
-}
-
-void Debug_glUniform2f(GLint location, GLfloat x, GLfloat y)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLfloat x;
- GLfloat y;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform2f(location, x, y);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
- caller.y = y;
-
- msg.set_arg0(location);
- msg.set_arg1(ToInt(x));
- msg.set_arg2(ToInt(y));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2f);
-}
-
-void Debug_glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLfloat* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform2fv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2fv);
-}
-
-void Debug_glUniform2i(GLint location, GLint x, GLint y)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLint x;
- GLint y;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform2i(location, x, y);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
- caller.y = y;
-
- msg.set_arg0(location);
- msg.set_arg1(x);
- msg.set_arg2(y);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2i);
-}
-
-void Debug_glUniform2iv(GLint location, GLsizei count, const GLint* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLint* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform2iv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2iv);
-}
-
-void Debug_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLfloat x;
- GLfloat y;
- GLfloat z;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform3f(location, x, y, z);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
- caller.y = y;
- caller.z = z;
-
- msg.set_arg0(location);
- msg.set_arg1(ToInt(x));
- msg.set_arg2(ToInt(y));
- msg.set_arg3(ToInt(z));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3f);
-}
-
-void Debug_glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLfloat* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform3fv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3fv);
-}
-
-void Debug_glUniform3i(GLint location, GLint x, GLint y, GLint z)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLint x;
- GLint y;
- GLint z;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform3i(location, x, y, z);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
- caller.y = y;
- caller.z = z;
-
- msg.set_arg0(location);
- msg.set_arg1(x);
- msg.set_arg2(y);
- msg.set_arg3(z);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3i);
-}
-
-void Debug_glUniform3iv(GLint location, GLsizei count, const GLint* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLint* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform3iv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3iv);
-}
-
-void Debug_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLfloat x;
- GLfloat y;
- GLfloat z;
- GLfloat w;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform4f(location, x, y, z, w);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
- caller.y = y;
- caller.z = z;
- caller.w = w;
-
- msg.set_arg0(location);
- msg.set_arg1(ToInt(x));
- msg.set_arg2(ToInt(y));
- msg.set_arg3(ToInt(z));
- msg.set_arg4(ToInt(w));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4f);
-}
-
-void Debug_glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLfloat* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform4fv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4fv);
-}
-
-void Debug_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLint x;
- GLint y;
- GLint z;
- GLint w;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform4i(location, x, y, z, w);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.x = x;
- caller.y = y;
- caller.z = z;
- caller.w = w;
-
- msg.set_arg0(location);
- msg.set_arg1(x);
- msg.set_arg2(y);
- msg.set_arg3(z);
- msg.set_arg4(w);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4i);
-}
-
-void Debug_glUniform4iv(GLint location, GLsizei count, const GLint* v)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- const GLint* v;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniform4iv(location, count, v);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.v = v;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(ToInt(v));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLint));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4iv);
-}
-
-void Debug_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- GLboolean transpose;
- const GLfloat* value;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniformMatrix2fv(location, count, transpose, value);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.transpose = transpose;
- caller.value = value;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(transpose);
- msg.set_arg3(ToInt(value));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 4*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix2fv);
-}
-
-void Debug_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- GLboolean transpose;
- const GLfloat* value;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniformMatrix3fv(location, count, transpose, value);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.transpose = transpose;
- caller.value = value;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(transpose);
- msg.set_arg3(ToInt(value));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 9*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix3fv);
-}
-
-void Debug_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint location;
- GLsizei count;
- GLboolean transpose;
- const GLfloat* value;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUniformMatrix4fv(location, count, transpose, value);
- return 0;
- }
- } caller;
- caller.location = location;
- caller.count = count;
- caller.transpose = transpose;
- caller.value = value;
-
- msg.set_arg0(location);
- msg.set_arg1(count);
- msg.set_arg2(transpose);
- msg.set_arg3(ToInt(value));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 16*count * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix4fv);
-}
-
-void Debug_glUseProgram(GLuint program)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glUseProgram(program);
- getDbgContextThreadSpecific()->glUseProgram(program);
- return 0;
- }
- } caller;
- caller.program = program;
-
- msg.set_arg0(program);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUseProgram);
-}
-
-void Debug_glValidateProgram(GLuint program)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint program;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glValidateProgram(program);
- return 0;
- }
- } caller;
- caller.program = program;
-
- msg.set_arg0(program);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glValidateProgram);
-}
-
-void Debug_glVertexAttrib1f(GLuint indx, GLfloat x)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- GLfloat x;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib1f(indx, x);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.x = x;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(x));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib1f);
-}
-
-void Debug_glVertexAttrib1fv(GLuint indx, const GLfloat* values)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- const GLfloat* values;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib1fv(indx, values);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.values = values;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(values));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 1 * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib1fv);
-}
-
-void Debug_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- GLfloat x;
- GLfloat y;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib2f(indx, x, y);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.x = x;
- caller.y = y;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(x));
- msg.set_arg2(ToInt(y));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib2f);
-}
-
-void Debug_glVertexAttrib2fv(GLuint indx, const GLfloat* values)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- const GLfloat* values;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib2fv(indx, values);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.values = values;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(values));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 2 * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib2fv);
-}
-
-void Debug_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- GLfloat x;
- GLfloat y;
- GLfloat z;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib3f(indx, x, y, z);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.x = x;
- caller.y = y;
- caller.z = z;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(x));
- msg.set_arg2(ToInt(y));
- msg.set_arg3(ToInt(z));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib3f);
-}
-
-void Debug_glVertexAttrib3fv(GLuint indx, const GLfloat* values)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- const GLfloat* values;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib3fv(indx, values);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.values = values;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(values));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 3 * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib3fv);
-}
-
-void Debug_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- GLfloat x;
- GLfloat y;
- GLfloat z;
- GLfloat w;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib4f(indx, x, y, z, w);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.x = x;
- caller.y = y;
- caller.z = z;
- caller.w = w;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(x));
- msg.set_arg2(ToInt(y));
- msg.set_arg3(ToInt(z));
- msg.set_arg4(ToInt(w));
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib4f);
-}
-
-void Debug_glVertexAttrib4fv(GLuint indx, const GLfloat* values)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- const GLfloat* values;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttrib4fv(indx, values);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.values = values;
-
- msg.set_arg0(indx);
- msg.set_arg1(ToInt(values));
-
- // FIXME: check for pointer usage
- msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 4 * sizeof(GLfloat));
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib4fv);
-}
-
-// FIXME: this function has pointers, it should be hand written
-void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLuint indx;
- GLint size;
- GLenum type;
- GLboolean normalized;
- GLsizei stride;
- const GLvoid* ptr;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
- getDbgContextThreadSpecific()->glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
- return 0;
- }
- } caller;
- caller.indx = indx;
- caller.size = size;
- caller.type = type;
- caller.normalized = normalized;
- caller.stride = stride;
- caller.ptr = ptr;
-
- msg.set_arg0(indx);
- msg.set_arg1(size);
- msg.set_arg2(type);
- msg.set_arg3(normalized);
- msg.set_arg4(stride);
- msg.set_arg5(ToInt(ptr));
-
- // FIXME: check for pointer usage
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttribPointer);
-}
-
-void Debug_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
-{
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- GLint x;
- GLint y;
- GLsizei width;
- GLsizei height;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- _c->glViewport(x, y, width, height);
- return 0;
- }
- } caller;
- caller.x = x;
- caller.y = y;
- caller.width = width;
- caller.height = height;
-
- msg.set_arg0(x);
- msg.set_arg1(y);
- msg.set_arg2(width);
- msg.set_arg3(height);
-
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glViewport);
-}
-
-// FIXME: the following functions should be written by hand
-void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
-void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
-void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
-void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
-void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
-void Debug_glGetBooleanv(GLenum pname, GLboolean* params);
-void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
-void Debug_glGetFloatv(GLenum pname, GLfloat* params);
-void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
-void Debug_glGetIntegerv(GLenum pname, GLint* params);
-void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
-void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
-void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
-void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
-void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
-const GLubyte* Debug_glGetString(GLenum name);
-void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
-void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
-void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params);
-void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params);
-void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
-void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
-void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
-void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
-void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
-void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params);
-void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
diff --git a/opengl/libs/GLES2_dbg/src/api.h b/opengl/libs/GLES2_dbg/src/api.h
deleted file mode 100644
index 0b227bc66c5c..000000000000
--- a/opengl/libs/GLES2_dbg/src/api.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define EXTEND_Debug_glCopyTexImage2D \
- DbgContext * const dbg = getDbgContextThreadSpecific(); \
- void * readData = dbg->GetReadPixelsBuffer(4 * width * height); \
- /* pick easy format for client to convert */ \
- dbg->hooks->gl.glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, readData); \
- dbg->CompressReadPixelBuffer(msg.mutable_data()); \
- msg.set_data_type(msg.ReferencedImage); \
- msg.set_pixel_format(GL_RGBA); \
- msg.set_pixel_type(GL_UNSIGNED_BYTE);
-
-#define EXTEND_Debug_glCopyTexSubImage2D EXTEND_Debug_glCopyTexImage2D
-
-#define EXTEND_AFTER_CALL_Debug_glReadPixels \
- { \
- DbgContext * const dbg = getDbgContextThreadSpecific(); \
- if (dbg->IsReadPixelBuffer(pixels)) { \
- dbg->CompressReadPixelBuffer(msg.mutable_data()); \
- msg.set_data_type(msg.ReferencedImage); \
- } else { \
- const unsigned int size = width * height * GetBytesPerPixel(format, type); \
- dbg->Compress(pixels, size, msg.mutable_data()); \
- msg.set_data_type(msg.NonreferencedImage); \
- } \
- }
-
-#define EXTEND_Debug_glShaderSource \
- std::string * const data = msg.mutable_data(); \
- for (unsigned i = 0; i < count; i++) \
- if (!length || length[i] < 0) \
- data->append(string[i]); \
- else \
- data->append(string[i], length[i]);
-
-#define EXTEND_Debug_glTexImage2D \
- if (pixels) { \
- DbgContext * const dbg = getDbgContextThreadSpecific(); \
- const unsigned size = GetBytesPerPixel(format, type) * width * height; \
- assert(0 < size); \
- dbg->Compress(pixels, size, msg.mutable_data()); \
- }
-
-#define EXTEND_Debug_glTexSubImage2D EXTEND_Debug_glTexImage2D
diff --git a/opengl/libs/GLES2_dbg/src/caller.cpp b/opengl/libs/GLES2_dbg/src/caller.cpp
deleted file mode 100644
index 70d23d67ca31..000000000000
--- a/opengl/libs/GLES2_dbg/src/caller.cpp
+++ /dev/null
@@ -1,778 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-// auto generated by generate_caller_cpp.py
-// implement declarations in caller.h
-
-#include "header.h"
-
-namespace android {
-
-static const int * GenerateCall_glCompressedTexImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glCompressedTexSubImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glDrawElements(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGenBuffers(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGenFramebuffers(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGenRenderbuffers(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGenTextures(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetActiveAttrib(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetActiveUniform(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetAttachedShaders(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetBooleanv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetBufferParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetFloatv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetFramebufferAttachmentParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetIntegerv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetProgramiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetProgramInfoLog(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetRenderbufferParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetShaderiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetShaderInfoLog(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetShaderPrecisionFormat(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetShaderSource(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetString(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetTexParameterfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetTexParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetUniformfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetUniformiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetVertexAttribfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetVertexAttribiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glGetVertexAttribPointerv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glReadPixels(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glShaderBinary(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glShaderSource(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glTexImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glTexParameterfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glTexParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glTexSubImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-static const int * GenerateCall_glVertexAttribPointer(DbgContext * const dbg,
- const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);
-
-#include "caller.h"
-
-const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- ALOGD("GenerateCall function=%u", cmd.function());
- const int * ret = prevRet; // only some functions have return value
- nsecs_t c0 = systemTime(timeMode);
- switch (cmd.function()) { case glesv2debugger::Message_Function_glActiveTexture:
- dbg->hooks->gl.glActiveTexture(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glAttachShader:
- dbg->hooks->gl.glAttachShader(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBindAttribLocation:
- dbg->hooks->gl.glBindAttribLocation(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLuint>(cmd.arg1()),
- reinterpret_cast<GLchar*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glBindBuffer:
- dbg->hooks->gl.glBindBuffer(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBindFramebuffer:
- dbg->hooks->gl.glBindFramebuffer(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBindRenderbuffer:
- dbg->hooks->gl.glBindRenderbuffer(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBindTexture:
- dbg->hooks->gl.glBindTexture(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBlendColor:
- dbg->hooks->gl.glBlendColor(
- static_cast<GLclampf>(cmd.arg0()), static_cast<GLclampf>(cmd.arg1()),
- static_cast<GLclampf>(cmd.arg2()), static_cast<GLclampf>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glBlendEquation:
- dbg->hooks->gl.glBlendEquation(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glBlendEquationSeparate:
- dbg->hooks->gl.glBlendEquationSeparate(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBlendFunc:
- dbg->hooks->gl.glBlendFunc(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glBlendFuncSeparate:
- dbg->hooks->gl.glBlendFuncSeparate(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLenum>(cmd.arg2()), static_cast<GLenum>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glBufferData:
- dbg->hooks->gl.glBufferData(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLsizeiptr>(cmd.arg1()),
- reinterpret_cast<GLvoid*>(const_cast<char *>(cmd.data().data())),
- static_cast<GLenum>(cmd.arg3()));
- break;
- case glesv2debugger::Message_Function_glBufferSubData:
- dbg->hooks->gl.glBufferSubData(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLintptr>(cmd.arg1()),
- static_cast<GLsizeiptr>(cmd.arg2()), reinterpret_cast<GLvoid*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glCheckFramebufferStatus:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glCheckFramebufferStatus(
- static_cast<GLenum>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glClear:
- dbg->hooks->gl.glClear(
- static_cast<GLbitfield>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glClearColor:
- dbg->hooks->gl.glClearColor(
- static_cast<GLclampf>(cmd.arg0()), static_cast<GLclampf>(cmd.arg1()),
- static_cast<GLclampf>(cmd.arg2()), static_cast<GLclampf>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glClearDepthf:
- dbg->hooks->gl.glClearDepthf(
- static_cast<GLclampf>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glClearStencil:
- dbg->hooks->gl.glClearStencil(
- static_cast<GLint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glColorMask:
- dbg->hooks->gl.glColorMask(
- GLboolean(cmd.arg0()), GLboolean(cmd.arg1()), GLboolean(cmd.arg2()),
- GLboolean(cmd.arg3()));
- break;
- case glesv2debugger::Message_Function_glCompileShader:
- dbg->hooks->gl.glCompileShader(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glCompressedTexImage2D:
- ret = GenerateCall_glCompressedTexImage2D(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glCompressedTexSubImage2D:
- ret = GenerateCall_glCompressedTexSubImage2D(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glCopyTexImage2D:
- dbg->hooks->gl.glCopyTexImage2D(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLenum>(cmd.arg2()), static_cast<GLint>(cmd.arg3()),
- static_cast<GLint>(cmd.arg4()), static_cast<GLsizei>(cmd.arg5()),
- static_cast<GLsizei>(cmd.arg6()), static_cast<GLint>(cmd.arg7())
- );
- break;
- case glesv2debugger::Message_Function_glCopyTexSubImage2D:
- dbg->hooks->gl.glCopyTexSubImage2D(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLint>(cmd.arg2()), static_cast<GLint>(cmd.arg3()),
- static_cast<GLint>(cmd.arg4()), static_cast<GLint>(cmd.arg5()),
- static_cast<GLsizei>(cmd.arg6()), static_cast<GLsizei>(cmd.arg7())
- );
- break;
- case glesv2debugger::Message_Function_glCreateProgram:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glCreateProgram(
- )));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glCreateShader:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glCreateShader(
- static_cast<GLenum>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glCullFace:
- dbg->hooks->gl.glCullFace(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDeleteBuffers:
- dbg->hooks->gl.glDeleteBuffers(
- static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glDeleteFramebuffers:
- dbg->hooks->gl.glDeleteFramebuffers(
- static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glDeleteProgram:
- dbg->hooks->gl.glDeleteProgram(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDeleteRenderbuffers:
- dbg->hooks->gl.glDeleteRenderbuffers(
- static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glDeleteShader:
- dbg->hooks->gl.glDeleteShader(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDeleteTextures:
- dbg->hooks->gl.glDeleteTextures(
- static_cast<GLsizei>(cmd.arg0()), reinterpret_cast<GLuint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glDepthFunc:
- dbg->hooks->gl.glDepthFunc(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDepthMask:
- dbg->hooks->gl.glDepthMask(
- GLboolean(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDepthRangef:
- dbg->hooks->gl.glDepthRangef(
- static_cast<GLclampf>(cmd.arg0()), static_cast<GLclampf>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glDetachShader:
- dbg->hooks->gl.glDetachShader(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glDisable:
- dbg->hooks->gl.glDisable(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDisableVertexAttribArray:
- dbg->hooks->gl.glDisableVertexAttribArray(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glDrawArrays:
- dbg->hooks->gl.glDrawArrays(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLsizei>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glDrawElements:
- ret = GenerateCall_glDrawElements(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glEnable:
- dbg->hooks->gl.glEnable(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glEnableVertexAttribArray:
- dbg->hooks->gl.glEnableVertexAttribArray(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glFinish:
- dbg->hooks->gl.glFinish(
- );
- break;
- case glesv2debugger::Message_Function_glFlush:
- dbg->hooks->gl.glFlush(
- );
- break;
- case glesv2debugger::Message_Function_glFramebufferRenderbuffer:
- dbg->hooks->gl.glFramebufferRenderbuffer(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLenum>(cmd.arg2()), static_cast<GLuint>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glFramebufferTexture2D:
- dbg->hooks->gl.glFramebufferTexture2D(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLenum>(cmd.arg2()), static_cast<GLuint>(cmd.arg3()),
- static_cast<GLint>(cmd.arg4()));
- break;
- case glesv2debugger::Message_Function_glFrontFace:
- dbg->hooks->gl.glFrontFace(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glGenBuffers:
- ret = GenerateCall_glGenBuffers(dbg, cmd, msg, prevRet);
- break; // annotated output pointers
- case glesv2debugger::Message_Function_glGenerateMipmap:
- dbg->hooks->gl.glGenerateMipmap(
- static_cast<GLenum>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glGenFramebuffers:
- ret = GenerateCall_glGenFramebuffers(dbg, cmd, msg, prevRet);
- break; // annotated output pointers
- case glesv2debugger::Message_Function_glGenRenderbuffers:
- ret = GenerateCall_glGenRenderbuffers(dbg, cmd, msg, prevRet);
- break; // annotated output pointers
- case glesv2debugger::Message_Function_glGenTextures:
- ret = GenerateCall_glGenTextures(dbg, cmd, msg, prevRet);
- break; // annotated output pointers
- case glesv2debugger::Message_Function_glGetActiveAttrib:
- ret = GenerateCall_glGetActiveAttrib(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetActiveUniform:
- ret = GenerateCall_glGetActiveUniform(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetAttachedShaders:
- ret = GenerateCall_glGetAttachedShaders(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetAttribLocation:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glGetAttribLocation(
- static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLchar*>(const_cast<char *>(cmd.data().data()))
- )));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glGetBooleanv:
- ret = GenerateCall_glGetBooleanv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetBufferParameteriv:
- ret = GenerateCall_glGetBufferParameteriv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetError:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glGetError(
- )));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glGetFloatv:
- ret = GenerateCall_glGetFloatv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv:
- ret = GenerateCall_glGetFramebufferAttachmentParameteriv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetIntegerv:
- ret = GenerateCall_glGetIntegerv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetProgramiv:
- ret = GenerateCall_glGetProgramiv(dbg, cmd, msg, prevRet);
- break; // annotated output pointers
- case glesv2debugger::Message_Function_glGetProgramInfoLog:
- ret = GenerateCall_glGetProgramInfoLog(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetRenderbufferParameteriv:
- ret = GenerateCall_glGetRenderbufferParameteriv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetShaderiv:
- ret = GenerateCall_glGetShaderiv(dbg, cmd, msg, prevRet);
- break; // annotated output pointers
- case glesv2debugger::Message_Function_glGetShaderInfoLog:
- ret = GenerateCall_glGetShaderInfoLog(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetShaderPrecisionFormat:
- ret = GenerateCall_glGetShaderPrecisionFormat(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetShaderSource:
- ret = GenerateCall_glGetShaderSource(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetString:
- ret = GenerateCall_glGetString(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetTexParameterfv:
- ret = GenerateCall_glGetTexParameterfv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetTexParameteriv:
- ret = GenerateCall_glGetTexParameteriv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetUniformfv:
- ret = GenerateCall_glGetUniformfv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetUniformiv:
- ret = GenerateCall_glGetUniformiv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetUniformLocation:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glGetUniformLocation(
- static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLchar*>(const_cast<char *>(cmd.data().data()))
- )));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glGetVertexAttribfv:
- ret = GenerateCall_glGetVertexAttribfv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetVertexAttribiv:
- ret = GenerateCall_glGetVertexAttribiv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glGetVertexAttribPointerv:
- ret = GenerateCall_glGetVertexAttribPointerv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glHint:
- dbg->hooks->gl.glHint(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glIsBuffer:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsBuffer(
- static_cast<GLuint>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glIsEnabled:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsEnabled(
- static_cast<GLenum>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glIsFramebuffer:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsFramebuffer(
- static_cast<GLuint>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glIsProgram:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsProgram(
- static_cast<GLuint>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glIsRenderbuffer:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsRenderbuffer(
- static_cast<GLuint>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glIsShader:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsShader(
- static_cast<GLuint>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glIsTexture:
- msg.set_ret(static_cast<int>(dbg->hooks->gl.glIsTexture(
- static_cast<GLuint>(cmd.arg0()))));
- if (cmd.has_ret())
- ret = reinterpret_cast<int *>(msg.ret());
- break;
- case glesv2debugger::Message_Function_glLineWidth:
- dbg->hooks->gl.glLineWidth(
- static_cast<GLfloat>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glLinkProgram:
- dbg->hooks->gl.glLinkProgram(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glPixelStorei:
- dbg->hooks->gl.glPixelStorei(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glPolygonOffset:
- dbg->hooks->gl.glPolygonOffset(
- static_cast<GLfloat>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glReadPixels:
- ret = GenerateCall_glReadPixels(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glReleaseShaderCompiler:
- dbg->hooks->gl.glReleaseShaderCompiler(
- );
- break;
- case glesv2debugger::Message_Function_glRenderbufferStorage:
- dbg->hooks->gl.glRenderbufferStorage(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLsizei>(cmd.arg2()), static_cast<GLsizei>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glSampleCoverage:
- dbg->hooks->gl.glSampleCoverage(
- static_cast<GLclampf>(cmd.arg0()), GLboolean(cmd.arg1()));
- break;
- case glesv2debugger::Message_Function_glScissor:
- dbg->hooks->gl.glScissor(
- static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLsizei>(cmd.arg2()), static_cast<GLsizei>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glShaderBinary:
- ret = GenerateCall_glShaderBinary(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glShaderSource:
- ret = GenerateCall_glShaderSource(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glStencilFunc:
- dbg->hooks->gl.glStencilFunc(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLuint>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glStencilFuncSeparate:
- dbg->hooks->gl.glStencilFuncSeparate(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLint>(cmd.arg2()), static_cast<GLuint>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glStencilMask:
- dbg->hooks->gl.glStencilMask(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glStencilMaskSeparate:
- dbg->hooks->gl.glStencilMaskSeparate(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLuint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glStencilOp:
- dbg->hooks->gl.glStencilOp(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLenum>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glStencilOpSeparate:
- dbg->hooks->gl.glStencilOpSeparate(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLenum>(cmd.arg2()), static_cast<GLenum>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glTexImage2D:
- ret = GenerateCall_glTexImage2D(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glTexParameterf:
- dbg->hooks->gl.glTexParameterf(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glTexParameterfv:
- ret = GenerateCall_glTexParameterfv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glTexParameteri:
- dbg->hooks->gl.glTexParameteri(
- static_cast<GLenum>(cmd.arg0()), static_cast<GLenum>(cmd.arg1()),
- static_cast<GLint>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glTexParameteriv:
- ret = GenerateCall_glTexParameteriv(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glTexSubImage2D:
- ret = GenerateCall_glTexSubImage2D(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glUniform1f:
- dbg->hooks->gl.glUniform1f(
- static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glUniform1fv:
- dbg->hooks->gl.glUniform1fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform1i:
- dbg->hooks->gl.glUniform1i(
- static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glUniform1iv:
- dbg->hooks->gl.glUniform1iv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform2f:
- dbg->hooks->gl.glUniform2f(
- static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glUniform2fv:
- dbg->hooks->gl.glUniform2fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform2i:
- dbg->hooks->gl.glUniform2i(
- static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLint>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glUniform2iv:
- dbg->hooks->gl.glUniform2iv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform3f:
- dbg->hooks->gl.glUniform3f(
- static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glUniform3fv:
- dbg->hooks->gl.glUniform3fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform3i:
- dbg->hooks->gl.glUniform3i(
- static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLint>(cmd.arg2()), static_cast<GLint>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glUniform3iv:
- dbg->hooks->gl.glUniform3iv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform4f:
- dbg->hooks->gl.glUniform4f(
- static_cast<GLint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3()),
- static_cast<GLfloat>(cmd.arg4()));
- break;
- case glesv2debugger::Message_Function_glUniform4fv:
- dbg->hooks->gl.glUniform4fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniform4i:
- dbg->hooks->gl.glUniform4i(
- static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLint>(cmd.arg2()), static_cast<GLint>(cmd.arg3()),
- static_cast<GLint>(cmd.arg4()));
- break;
- case glesv2debugger::Message_Function_glUniform4iv:
- dbg->hooks->gl.glUniform4iv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- reinterpret_cast<GLint*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniformMatrix2fv:
- dbg->hooks->gl.glUniformMatrix2fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- GLboolean(cmd.arg2()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniformMatrix3fv:
- dbg->hooks->gl.glUniformMatrix3fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- GLboolean(cmd.arg2()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUniformMatrix4fv:
- dbg->hooks->gl.glUniformMatrix4fv(
- static_cast<GLint>(cmd.arg0()), static_cast<GLsizei>(cmd.arg1()),
- GLboolean(cmd.arg2()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glUseProgram:
- dbg->hooks->gl.glUseProgram(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glValidateProgram:
- dbg->hooks->gl.glValidateProgram(
- static_cast<GLuint>(cmd.arg0()));
- break;
- case glesv2debugger::Message_Function_glVertexAttrib1f:
- dbg->hooks->gl.glVertexAttrib1f(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1())
- );
- break;
- case glesv2debugger::Message_Function_glVertexAttrib1fv:
- dbg->hooks->gl.glVertexAttrib1fv(
- static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glVertexAttrib2f:
- dbg->hooks->gl.glVertexAttrib2f(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()));
- break;
- case glesv2debugger::Message_Function_glVertexAttrib2fv:
- dbg->hooks->gl.glVertexAttrib2fv(
- static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glVertexAttrib3f:
- dbg->hooks->gl.glVertexAttrib3f(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3())
- );
- break;
- case glesv2debugger::Message_Function_glVertexAttrib3fv:
- dbg->hooks->gl.glVertexAttrib3fv(
- static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glVertexAttrib4f:
- dbg->hooks->gl.glVertexAttrib4f(
- static_cast<GLuint>(cmd.arg0()), static_cast<GLfloat>(cmd.arg1()),
- static_cast<GLfloat>(cmd.arg2()), static_cast<GLfloat>(cmd.arg3()),
- static_cast<GLfloat>(cmd.arg4()));
- break;
- case glesv2debugger::Message_Function_glVertexAttrib4fv:
- dbg->hooks->gl.glVertexAttrib4fv(
- static_cast<GLuint>(cmd.arg0()), reinterpret_cast<GLfloat*>(const_cast<char *>(cmd.data().data()))
- );
- break;
- case glesv2debugger::Message_Function_glVertexAttribPointer:
- ret = GenerateCall_glVertexAttribPointer(dbg, cmd, msg, prevRet);
- break;
- case glesv2debugger::Message_Function_glViewport:
- dbg->hooks->gl.glViewport(
- static_cast<GLint>(cmd.arg0()), static_cast<GLint>(cmd.arg1()),
- static_cast<GLsizei>(cmd.arg2()), static_cast<GLsizei>(cmd.arg3())
- );
- break;
- default:
- assert(0);
- }
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_function(cmd.function());
- msg.set_type(glesv2debugger::Message_Type_AfterGeneratedCall);
- return ret;
-}
-
-}; // name space android {
diff --git a/opengl/libs/GLES2_dbg/src/caller.h b/opengl/libs/GLES2_dbg/src/caller.h
deleted file mode 100644
index e8111b329224..000000000000
--- a/opengl/libs/GLES2_dbg/src/caller.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License")
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-static const int * GenerateCall_glCompressedTexImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glCompressedTexSubImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glDrawElements(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGenBuffers(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGenFramebuffers(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGenRenderbuffers(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGenTextures(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetActiveAttrib(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetActiveUniform(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetAttachedShaders(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetBooleanv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetBufferParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetFloatv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetFramebufferAttachmentParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetIntegerv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetProgramiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- GLint params = -1;
- dbg->hooks->gl.glGetProgramiv(cmd.arg0(), cmd.arg1(), &params);
- msg.mutable_data()->append(reinterpret_cast<char *>(&params), sizeof(params));
- return prevRet;
-}
-
-static const int * GenerateCall_glGetProgramInfoLog(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- const GLsizei bufSize = static_cast<GLsizei>(dbg->GetBufferSize());
- GLsizei length = -1;
- dbg->hooks->gl.glGetProgramInfoLog(cmd.arg0(), bufSize, &length, dbg->GetBuffer());
- msg.mutable_data()->append(dbg->GetBuffer(), length);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetRenderbufferParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetShaderiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- GLint params = -1;
- dbg->hooks->gl.glGetShaderiv(cmd.arg0(), cmd.arg1(), &params);
- msg.mutable_data()->append(reinterpret_cast<char *>(&params), sizeof(params));
- return prevRet;
-}
-
-static const int * GenerateCall_glGetShaderInfoLog(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- const GLsizei bufSize = static_cast<GLsizei>(dbg->GetBufferSize());
- GLsizei length = -1;
- dbg->hooks->gl.glGetShaderInfoLog(cmd.arg0(), bufSize, &length, dbg->GetBuffer());
- msg.mutable_data()->append(dbg->GetBuffer(), length);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetShaderPrecisionFormat(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetShaderSource(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetString(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetTexParameterfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetTexParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetUniformfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetUniformiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetVertexAttribfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetVertexAttribiv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glGetVertexAttribPointerv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glReadPixels(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glShaderBinary(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glShaderSource(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- const char * string = cmd.data().data();
- dbg->hooks->gl.glShaderSource(cmd.arg0(), 1, &string, NULL);
- return prevRet;
-}
-
-static const int * GenerateCall_glTexImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glTexParameterfv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glTexParameteriv(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glTexSubImage2D(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
-
-static const int * GenerateCall_glVertexAttribPointer(DbgContext * const dbg,
- const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet)
-{
- assert(0);
- return prevRet;
-}
diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
deleted file mode 100644
index 7bbaa18bc61d..000000000000
--- a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include "header.h"
-
-extern "C" {
-#include "liblzf/lzf.h"
-}
-
-namespace android {
-
-static pthread_key_t dbgEGLThreadLocalStorageKey = -1;
-static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
-
-DbgContext * getDbgContextThreadSpecific() {
- return (DbgContext*)pthread_getspecific(dbgEGLThreadLocalStorageKey);
-}
-
-DbgContext::DbgContext(const unsigned version, const gl_hooks_t * const hooks,
- const unsigned MAX_VERTEX_ATTRIBS)
- : lzf_buf(NULL), lzf_readIndex(0), lzf_refSize(0), lzf_refBufSize(0)
- , version(version), hooks(hooks)
- , MAX_VERTEX_ATTRIBS(MAX_VERTEX_ATTRIBS)
- , readBytesPerPixel(4)
- , captureSwap(0), captureDraw(0)
- , vertexAttribs(new VertexAttrib[MAX_VERTEX_ATTRIBS])
- , hasNonVBOAttribs(false), indexBuffers(NULL), indexBuffer(NULL)
- , program(0), maxAttrib(0)
-{
- lzf_ref[0] = lzf_ref[1] = NULL;
- for (unsigned i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- vertexAttribs[i] = VertexAttrib();
- memset(&expectResponse, 0, sizeof(expectResponse));
-}
-
-DbgContext::~DbgContext()
-{
- delete vertexAttribs;
- free(lzf_buf);
- free(lzf_ref[0]);
- free(lzf_ref[1]);
-}
-
-DbgContext* CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks)
-{
- pthread_mutex_lock(&gThreadLocalStorageKeyMutex);
- if (dbgEGLThreadLocalStorageKey == -1)
- pthread_key_create(&dbgEGLThreadLocalStorageKey, NULL);
- pthread_mutex_unlock(&gThreadLocalStorageKeyMutex);
-
- assert(version < 2);
- assert(GL_NO_ERROR == hooks->gl.glGetError());
- GLint MAX_VERTEX_ATTRIBS = 0;
- hooks->gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &MAX_VERTEX_ATTRIBS);
- DbgContext* dbg = new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS);
- glesv2debugger::Message msg, cmd;
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_expect_response(false);
- msg.set_type(msg.Response);
- msg.set_function(msg.SETPROP);
- msg.set_prop(msg.GLConstant);
- msg.set_arg0(GL_MAX_VERTEX_ATTRIBS);
- msg.set_arg1(MAX_VERTEX_ATTRIBS);
- Send(msg, cmd);
-
- GLint MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0;
- hooks->gl.glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- msg.set_arg0(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- msg.set_arg1(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- Send(msg, cmd);
-
- pthread_setspecific(dbgEGLThreadLocalStorageKey, dbg);
- return dbg;
-}
-
-void dbgReleaseThread() {
- delete getDbgContextThreadSpecific();
-}
-
-unsigned GetBytesPerPixel(const GLenum format, const GLenum type)
-{
- switch (type) {
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- return 2;
- case GL_UNSIGNED_BYTE:
- break;
- default:
- ALOGE("GetBytesPerPixel: unknown type %x", type);
- }
-
- switch (format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- return 1;
- case GL_LUMINANCE_ALPHA:
- return 2;
- case GL_RGB:
- return 3;
- case GL_RGBA:
- case 0x80E1: // GL_BGRA_EXT
- return 4;
- default:
- ALOGE("GetBytesPerPixel: unknown format %x", format);
- }
-
- return 1; // in doubt...
-}
-
-void DbgContext::Fetch(const unsigned index, std::string * const data) const
-{
- // VBO data is already on client, just send user pointer data
- for (unsigned i = 0; i < maxAttrib; i++) {
- if (!vertexAttribs[i].enabled)
- continue;
- if (vertexAttribs[i].buffer > 0)
- continue;
- const char * ptr = (const char *)vertexAttribs[i].ptr;
- ptr += index * vertexAttribs[i].stride;
- data->append(ptr, vertexAttribs[i].elemSize);
- }
-}
-
-void DbgContext::Compress(const void * in_data, unsigned int in_len,
- std::string * const outStr)
-{
- if (!lzf_buf)
- lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
- assert(lzf_buf);
- const uint32_t totalDecompSize = in_len;
- outStr->append((const char *)&totalDecompSize, sizeof(totalDecompSize));
- for (unsigned int i = 0; i < in_len; i += LZF_CHUNK_SIZE) {
- uint32_t chunkSize = LZF_CHUNK_SIZE;
- if (i + LZF_CHUNK_SIZE > in_len)
- chunkSize = in_len - i;
- const uint32_t compSize = lzf_compress((const char *)in_data + i, chunkSize,
- lzf_buf, LZF_CHUNK_SIZE);
- outStr->append((const char *)&chunkSize, sizeof(chunkSize));
- outStr->append((const char *)&compSize, sizeof(compSize));
- if (compSize > 0)
- outStr->append(lzf_buf, compSize);
- else // compressed chunk bigger than LZF_CHUNK_SIZE (and uncompressed)
- outStr->append((const char *)in_data + i, chunkSize);
- }
-}
-
-unsigned char * DbgContext::Decompress(const void * in, const unsigned int inLen,
- unsigned int * const outLen)
-{
- assert(inLen > 4 * 3);
- if (inLen < 4 * 3)
- return NULL;
- *outLen = *(uint32_t *)in;
- unsigned char * const out = (unsigned char *)malloc(*outLen);
- unsigned int outPos = 0;
- const unsigned char * const end = (const unsigned char *)in + inLen;
- for (const unsigned char * inData = (const unsigned char *)in + 4; inData < end; ) {
- const uint32_t chunkOut = *(uint32_t *)inData;
- inData += 4;
- const uint32_t chunkIn = *(uint32_t *)inData;
- inData += 4;
- if (chunkIn > 0) {
- assert(inData + chunkIn <= end);
- assert(outPos + chunkOut <= *outLen);
- outPos += lzf_decompress(inData, chunkIn, out + outPos, chunkOut);
- inData += chunkIn;
- } else {
- assert(inData + chunkOut <= end);
- assert(outPos + chunkOut <= *outLen);
- memcpy(out + outPos, inData, chunkOut);
- inData += chunkOut;
- outPos += chunkOut;
- }
- }
- return out;
-}
-
-void * DbgContext::GetReadPixelsBuffer(const unsigned size)
-{
- if (lzf_refBufSize < size + 8) {
- lzf_refBufSize = size + 8;
- lzf_ref[0] = (unsigned *)realloc(lzf_ref[0], lzf_refBufSize);
- assert(lzf_ref[0]);
- memset(lzf_ref[0], 0, lzf_refBufSize);
- lzf_ref[1] = (unsigned *)realloc(lzf_ref[1], lzf_refBufSize);
- assert(lzf_ref[1]);
- memset(lzf_ref[1], 0, lzf_refBufSize);
- }
- if (lzf_refSize != size) // need to clear unused ref to maintain consistency
- { // since ref and src are swapped each time
- memset((char *)lzf_ref[0] + lzf_refSize, 0, lzf_refBufSize - lzf_refSize);
- memset((char *)lzf_ref[1] + lzf_refSize, 0, lzf_refBufSize - lzf_refSize);
- }
- lzf_refSize = size;
- lzf_readIndex ^= 1;
- return lzf_ref[lzf_readIndex];
-}
-
-void DbgContext::CompressReadPixelBuffer(std::string * const outStr)
-{
- assert(lzf_ref[0] && lzf_ref[1]);
- unsigned * const ref = lzf_ref[lzf_readIndex ^ 1];
- unsigned * const src = lzf_ref[lzf_readIndex];
- for (unsigned i = 0; i < lzf_refSize / sizeof(*ref) + 1; i++)
- ref[i] ^= src[i];
- Compress(ref, lzf_refSize, outStr);
-}
-
-char * DbgContext::GetBuffer()
-{
- if (!lzf_buf)
- lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
- assert(lzf_buf);
- return lzf_buf;
-}
-
-unsigned int DbgContext::GetBufferSize()
-{
- if (!lzf_buf)
- lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
- assert(lzf_buf);
- if (lzf_buf)
- return LZF_CHUNK_SIZE;
- else
- return 0;
-}
-
-void DbgContext::glUseProgram(GLuint program)
-{
- while (GLenum error = hooks->gl.glGetError())
- ALOGD("DbgContext::glUseProgram(%u): before glGetError() = 0x%.4X",
- program, error);
- this->program = program;
- maxAttrib = 0;
- if (program == 0)
- return;
- GLint activeAttributes = 0;
- hooks->gl.glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
- maxAttrib = 0;
- GLint maxNameLen = -1;
- hooks->gl.glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLen);
- char * name = new char [maxNameLen + 1];
- name[maxNameLen] = 0;
- // find total number of attribute slots used
- for (unsigned i = 0; i < activeAttributes; i++) {
- GLint size = -1;
- GLenum type = -1;
- hooks->gl.glGetActiveAttrib(program, i, maxNameLen + 1, NULL, &size, &type, name);
- GLint slot = hooks->gl.glGetAttribLocation(program, name);
- assert(slot >= 0);
- switch (type) {
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- slot += size;
- break;
- case GL_FLOAT_MAT2:
- slot += size * 2;
- break;
- case GL_FLOAT_MAT3:
- slot += size * 3;
- break;
- case GL_FLOAT_MAT4:
- slot += size * 4;
- break;
- default:
- assert(0);
- }
- if (slot > maxAttrib)
- maxAttrib = slot;
- }
- delete name;
- while (GLenum error = hooks->gl.glGetError())
- ALOGD("DbgContext::glUseProgram(%u): after glGetError() = 0x%.4X",
- program, error);
-}
-
-static bool HasNonVBOAttribs(const DbgContext * const ctx)
-{
- bool need = false;
- for (unsigned i = 0; !need && i < ctx->maxAttrib; i++)
- if (ctx->vertexAttribs[i].enabled && ctx->vertexAttribs[i].buffer == 0)
- need = true;
- return need;
-}
-
-void DbgContext::glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
- GLboolean normalized, GLsizei stride, const GLvoid* ptr)
-{
- assert(GL_NO_ERROR == hooks->gl.glGetError());
- assert(indx < MAX_VERTEX_ATTRIBS);
- vertexAttribs[indx].size = size;
- vertexAttribs[indx].type = type;
- vertexAttribs[indx].normalized = normalized;
- switch (type) {
- case GL_FLOAT:
- vertexAttribs[indx].elemSize = sizeof(GLfloat) * size;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- vertexAttribs[indx].elemSize = sizeof(GLint) * size;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- vertexAttribs[indx].elemSize = sizeof(GLshort) * size;
- break;
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- vertexAttribs[indx].elemSize = sizeof(GLbyte) * size;
- break;
- default:
- assert(0);
- }
- if (0 == stride)
- stride = vertexAttribs[indx].elemSize;
- vertexAttribs[indx].stride = stride;
- vertexAttribs[indx].ptr = ptr;
- hooks->gl.glGetVertexAttribiv(indx, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING,
- (GLint *)&vertexAttribs[indx].buffer);
- hasNonVBOAttribs = HasNonVBOAttribs(this);
-}
-
-void DbgContext::glEnableVertexAttribArray(GLuint index)
-{
- if (index >= MAX_VERTEX_ATTRIBS)
- return;
- vertexAttribs[index].enabled = true;
- hasNonVBOAttribs = HasNonVBOAttribs(this);
-}
-
-void DbgContext::glDisableVertexAttribArray(GLuint index)
-{
- if (index >= MAX_VERTEX_ATTRIBS)
- return;
- vertexAttribs[index].enabled = false;
- hasNonVBOAttribs = HasNonVBOAttribs(this);
-}
-
-void DbgContext::glBindBuffer(GLenum target, GLuint buffer)
-{
- if (GL_ELEMENT_ARRAY_BUFFER != target)
- return;
- if (0 == buffer) {
- indexBuffer = NULL;
- return;
- }
- VBO * b = indexBuffers;
- indexBuffer = NULL;
- while (b) {
- if (b->name == buffer) {
- assert(GL_ELEMENT_ARRAY_BUFFER == b->target);
- indexBuffer = b;
- break;
- }
- b = b->next;
- }
- if (!indexBuffer)
- indexBuffer = indexBuffers = new VBO(buffer, target, indexBuffers);
-}
-
-void DbgContext::glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
-{
- if (GL_ELEMENT_ARRAY_BUFFER != target)
- return;
- assert(indexBuffer);
- assert(size >= 0);
- indexBuffer->size = size;
- indexBuffer->data = realloc(indexBuffer->data, size);
- memcpy(indexBuffer->data, data, size);
-}
-
-void DbgContext::glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
-{
- if (GL_ELEMENT_ARRAY_BUFFER != target)
- return;
- assert(indexBuffer);
- assert(size >= 0);
- assert(offset >= 0);
- assert(offset + size <= indexBuffer->size);
- memcpy((char *)indexBuffer->data + offset, data, size);
-}
-
-void DbgContext::glDeleteBuffers(GLsizei n, const GLuint *buffers)
-{
- for (unsigned i = 0; i < n; i++) {
- for (unsigned j = 0; j < MAX_VERTEX_ATTRIBS; j++)
- if (buffers[i] == vertexAttribs[j].buffer) {
- vertexAttribs[j].buffer = 0;
- vertexAttribs[j].enabled = false;
- }
- VBO * b = indexBuffers, * previous = NULL;
- while (b) {
- if (b->name == buffers[i]) {
- assert(GL_ELEMENT_ARRAY_BUFFER == b->target);
- if (indexBuffer == b)
- indexBuffer = NULL;
- if (previous)
- previous->next = b->next;
- else
- indexBuffers = b->next;
- free(b->data);
- delete b;
- break;
- }
- previous = b;
- b = b->next;
- }
- }
- hasNonVBOAttribs = HasNonVBOAttribs(this);
-}
-
-}; // namespace android
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp b/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
deleted file mode 100644
index 50f70f7dff0e..000000000000
--- a/opengl/libs/GLES2_dbg/src/debugger_message.pb.cpp
+++ /dev/null
@@ -1,1455 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-
-#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
-#include "debugger_message.pb.h"
-#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/wire_format_lite_inl.h>
-// @@protoc_insertion_point(includes)
-
-namespace com {
-namespace android {
-namespace glesv2debugger {
-
-void protobuf_ShutdownFile_debugger_5fmessage_2eproto() {
- delete Message::default_instance_;
-}
-
-void protobuf_AddDesc_debugger_5fmessage_2eproto() {
- static bool already_here = false;
- if (already_here) return;
- already_here = true;
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-
- Message::default_instance_ = new Message();
- Message::default_instance_->InitAsDefaultInstance();
- ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_debugger_5fmessage_2eproto);
-}
-
-// Force AddDescriptors() to be called at static initialization time.
-struct StaticDescriptorInitializer_debugger_5fmessage_2eproto {
- StaticDescriptorInitializer_debugger_5fmessage_2eproto() {
- protobuf_AddDesc_debugger_5fmessage_2eproto();
- }
-} static_descriptor_initializer_debugger_5fmessage_2eproto_;
-
-
-// ===================================================================
-
-bool Message_Function_IsValid(int value) {
- switch(value) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- case 17:
- case 18:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- case 24:
- case 25:
- case 26:
- case 27:
- case 28:
- case 29:
- case 30:
- case 31:
- case 32:
- case 33:
- case 34:
- case 35:
- case 36:
- case 37:
- case 38:
- case 39:
- case 40:
- case 41:
- case 42:
- case 43:
- case 44:
- case 45:
- case 46:
- case 47:
- case 48:
- case 49:
- case 50:
- case 51:
- case 52:
- case 53:
- case 54:
- case 55:
- case 56:
- case 57:
- case 58:
- case 59:
- case 60:
- case 61:
- case 62:
- case 63:
- case 64:
- case 65:
- case 66:
- case 67:
- case 68:
- case 69:
- case 70:
- case 71:
- case 72:
- case 73:
- case 74:
- case 75:
- case 76:
- case 77:
- case 78:
- case 79:
- case 80:
- case 81:
- case 82:
- case 83:
- case 84:
- case 85:
- case 86:
- case 87:
- case 88:
- case 89:
- case 90:
- case 91:
- case 92:
- case 93:
- case 94:
- case 95:
- case 96:
- case 97:
- case 98:
- case 99:
- case 100:
- case 101:
- case 102:
- case 103:
- case 104:
- case 105:
- case 106:
- case 107:
- case 108:
- case 109:
- case 110:
- case 111:
- case 112:
- case 113:
- case 114:
- case 115:
- case 116:
- case 117:
- case 118:
- case 119:
- case 120:
- case 121:
- case 122:
- case 123:
- case 124:
- case 125:
- case 126:
- case 127:
- case 128:
- case 129:
- case 130:
- case 131:
- case 132:
- case 133:
- case 134:
- case 135:
- case 136:
- case 137:
- case 138:
- case 139:
- case 140:
- case 141:
- case 142:
- case 143:
- case 144:
- case 145:
- case 146:
- case 147:
- case 148:
- case 149:
- case 150:
- case 151:
- case 152:
- case 153:
- case 154:
- case 155:
- case 156:
- case 157:
- case 158:
- case 159:
- case 160:
- case 161:
- case 162:
- case 163:
- case 164:
- case 165:
- case 166:
- case 167:
- case 168:
- case 169:
- case 170:
- case 171:
- case 172:
- case 173:
- case 174:
- case 175:
- case 176:
- case 177:
- case 178:
- case 179:
- case 180:
- case 181:
- case 182:
- case 183:
- case 184:
- case 185:
- case 186:
- case 187:
- case 188:
- case 189:
- case 190:
- return true;
- default:
- return false;
- }
-}
-
-#ifndef _MSC_VER
-const Message_Function Message::glActiveTexture;
-const Message_Function Message::glAttachShader;
-const Message_Function Message::glBindAttribLocation;
-const Message_Function Message::glBindBuffer;
-const Message_Function Message::glBindFramebuffer;
-const Message_Function Message::glBindRenderbuffer;
-const Message_Function Message::glBindTexture;
-const Message_Function Message::glBlendColor;
-const Message_Function Message::glBlendEquation;
-const Message_Function Message::glBlendEquationSeparate;
-const Message_Function Message::glBlendFunc;
-const Message_Function Message::glBlendFuncSeparate;
-const Message_Function Message::glBufferData;
-const Message_Function Message::glBufferSubData;
-const Message_Function Message::glCheckFramebufferStatus;
-const Message_Function Message::glClear;
-const Message_Function Message::glClearColor;
-const Message_Function Message::glClearDepthf;
-const Message_Function Message::glClearStencil;
-const Message_Function Message::glColorMask;
-const Message_Function Message::glCompileShader;
-const Message_Function Message::glCompressedTexImage2D;
-const Message_Function Message::glCompressedTexSubImage2D;
-const Message_Function Message::glCopyTexImage2D;
-const Message_Function Message::glCopyTexSubImage2D;
-const Message_Function Message::glCreateProgram;
-const Message_Function Message::glCreateShader;
-const Message_Function Message::glCullFace;
-const Message_Function Message::glDeleteBuffers;
-const Message_Function Message::glDeleteFramebuffers;
-const Message_Function Message::glDeleteProgram;
-const Message_Function Message::glDeleteRenderbuffers;
-const Message_Function Message::glDeleteShader;
-const Message_Function Message::glDeleteTextures;
-const Message_Function Message::glDepthFunc;
-const Message_Function Message::glDepthMask;
-const Message_Function Message::glDepthRangef;
-const Message_Function Message::glDetachShader;
-const Message_Function Message::glDisable;
-const Message_Function Message::glDisableVertexAttribArray;
-const Message_Function Message::glDrawArrays;
-const Message_Function Message::glDrawElements;
-const Message_Function Message::glEnable;
-const Message_Function Message::glEnableVertexAttribArray;
-const Message_Function Message::glFinish;
-const Message_Function Message::glFlush;
-const Message_Function Message::glFramebufferRenderbuffer;
-const Message_Function Message::glFramebufferTexture2D;
-const Message_Function Message::glFrontFace;
-const Message_Function Message::glGenBuffers;
-const Message_Function Message::glGenerateMipmap;
-const Message_Function Message::glGenFramebuffers;
-const Message_Function Message::glGenRenderbuffers;
-const Message_Function Message::glGenTextures;
-const Message_Function Message::glGetActiveAttrib;
-const Message_Function Message::glGetActiveUniform;
-const Message_Function Message::glGetAttachedShaders;
-const Message_Function Message::glGetAttribLocation;
-const Message_Function Message::glGetBooleanv;
-const Message_Function Message::glGetBufferParameteriv;
-const Message_Function Message::glGetError;
-const Message_Function Message::glGetFloatv;
-const Message_Function Message::glGetFramebufferAttachmentParameteriv;
-const Message_Function Message::glGetIntegerv;
-const Message_Function Message::glGetProgramiv;
-const Message_Function Message::glGetProgramInfoLog;
-const Message_Function Message::glGetRenderbufferParameteriv;
-const Message_Function Message::glGetShaderiv;
-const Message_Function Message::glGetShaderInfoLog;
-const Message_Function Message::glGetShaderPrecisionFormat;
-const Message_Function Message::glGetShaderSource;
-const Message_Function Message::glGetString;
-const Message_Function Message::glGetTexParameterfv;
-const Message_Function Message::glGetTexParameteriv;
-const Message_Function Message::glGetUniformfv;
-const Message_Function Message::glGetUniformiv;
-const Message_Function Message::glGetUniformLocation;
-const Message_Function Message::glGetVertexAttribfv;
-const Message_Function Message::glGetVertexAttribiv;
-const Message_Function Message::glGetVertexAttribPointerv;
-const Message_Function Message::glHint;
-const Message_Function Message::glIsBuffer;
-const Message_Function Message::glIsEnabled;
-const Message_Function Message::glIsFramebuffer;
-const Message_Function Message::glIsProgram;
-const Message_Function Message::glIsRenderbuffer;
-const Message_Function Message::glIsShader;
-const Message_Function Message::glIsTexture;
-const Message_Function Message::glLineWidth;
-const Message_Function Message::glLinkProgram;
-const Message_Function Message::glPixelStorei;
-const Message_Function Message::glPolygonOffset;
-const Message_Function Message::glReadPixels;
-const Message_Function Message::glReleaseShaderCompiler;
-const Message_Function Message::glRenderbufferStorage;
-const Message_Function Message::glSampleCoverage;
-const Message_Function Message::glScissor;
-const Message_Function Message::glShaderBinary;
-const Message_Function Message::glShaderSource;
-const Message_Function Message::glStencilFunc;
-const Message_Function Message::glStencilFuncSeparate;
-const Message_Function Message::glStencilMask;
-const Message_Function Message::glStencilMaskSeparate;
-const Message_Function Message::glStencilOp;
-const Message_Function Message::glStencilOpSeparate;
-const Message_Function Message::glTexImage2D;
-const Message_Function Message::glTexParameterf;
-const Message_Function Message::glTexParameterfv;
-const Message_Function Message::glTexParameteri;
-const Message_Function Message::glTexParameteriv;
-const Message_Function Message::glTexSubImage2D;
-const Message_Function Message::glUniform1f;
-const Message_Function Message::glUniform1fv;
-const Message_Function Message::glUniform1i;
-const Message_Function Message::glUniform1iv;
-const Message_Function Message::glUniform2f;
-const Message_Function Message::glUniform2fv;
-const Message_Function Message::glUniform2i;
-const Message_Function Message::glUniform2iv;
-const Message_Function Message::glUniform3f;
-const Message_Function Message::glUniform3fv;
-const Message_Function Message::glUniform3i;
-const Message_Function Message::glUniform3iv;
-const Message_Function Message::glUniform4f;
-const Message_Function Message::glUniform4fv;
-const Message_Function Message::glUniform4i;
-const Message_Function Message::glUniform4iv;
-const Message_Function Message::glUniformMatrix2fv;
-const Message_Function Message::glUniformMatrix3fv;
-const Message_Function Message::glUniformMatrix4fv;
-const Message_Function Message::glUseProgram;
-const Message_Function Message::glValidateProgram;
-const Message_Function Message::glVertexAttrib1f;
-const Message_Function Message::glVertexAttrib1fv;
-const Message_Function Message::glVertexAttrib2f;
-const Message_Function Message::glVertexAttrib2fv;
-const Message_Function Message::glVertexAttrib3f;
-const Message_Function Message::glVertexAttrib3fv;
-const Message_Function Message::glVertexAttrib4f;
-const Message_Function Message::glVertexAttrib4fv;
-const Message_Function Message::glVertexAttribPointer;
-const Message_Function Message::glViewport;
-const Message_Function Message::eglGetDisplay;
-const Message_Function Message::eglInitialize;
-const Message_Function Message::eglTerminate;
-const Message_Function Message::eglGetConfigs;
-const Message_Function Message::eglChooseConfig;
-const Message_Function Message::eglGetConfigAttrib;
-const Message_Function Message::eglCreateWindowSurface;
-const Message_Function Message::eglCreatePixmapSurface;
-const Message_Function Message::eglCreatePbufferSurface;
-const Message_Function Message::eglDestroySurface;
-const Message_Function Message::eglQuerySurface;
-const Message_Function Message::eglCreateContext;
-const Message_Function Message::eglDestroyContext;
-const Message_Function Message::eglMakeCurrent;
-const Message_Function Message::eglGetCurrentContext;
-const Message_Function Message::eglGetCurrentSurface;
-const Message_Function Message::eglGetCurrentDisplay;
-const Message_Function Message::eglQueryContext;
-const Message_Function Message::eglWaitGL;
-const Message_Function Message::eglWaitNative;
-const Message_Function Message::eglSwapBuffers;
-const Message_Function Message::eglCopyBuffers;
-const Message_Function Message::eglGetError;
-const Message_Function Message::eglQueryString;
-const Message_Function Message::eglGetProcAddress;
-const Message_Function Message::eglSurfaceAttrib;
-const Message_Function Message::eglBindTexImage;
-const Message_Function Message::eglReleaseTexImage;
-const Message_Function Message::eglSwapInterval;
-const Message_Function Message::eglBindAPI;
-const Message_Function Message::eglQueryAPI;
-const Message_Function Message::eglWaitClient;
-const Message_Function Message::eglReleaseThread;
-const Message_Function Message::eglCreatePbufferFromClientBuffer;
-const Message_Function Message::eglLockSurfaceKHR;
-const Message_Function Message::eglUnlockSurfaceKHR;
-const Message_Function Message::eglCreateImageKHR;
-const Message_Function Message::eglDestroyImageKHR;
-const Message_Function Message::eglCreateSyncKHR;
-const Message_Function Message::eglDestroySyncKHR;
-const Message_Function Message::eglClientWaitSyncKHR;
-const Message_Function Message::eglGetSyncAttribKHR;
-const Message_Function Message::eglSetSwapRectangleANDROID;
-const Message_Function Message::eglGetRenderBufferANDROID;
-const Message_Function Message::ACK;
-const Message_Function Message::NEG;
-const Message_Function Message::CONTINUE;
-const Message_Function Message::SKIP;
-const Message_Function Message::SETPROP;
-const Message_Function Message::Function_MIN;
-const Message_Function Message::Function_MAX;
-const int Message::Function_ARRAYSIZE;
-#endif // _MSC_VER
-bool Message_Type_IsValid(int value) {
- switch(value) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- return true;
- default:
- return false;
- }
-}
-
-#ifndef _MSC_VER
-const Message_Type Message::BeforeCall;
-const Message_Type Message::AfterCall;
-const Message_Type Message::AfterGeneratedCall;
-const Message_Type Message::Response;
-const Message_Type Message::CompleteCall;
-const Message_Type Message::Type_MIN;
-const Message_Type Message::Type_MAX;
-const int Message::Type_ARRAYSIZE;
-#endif // _MSC_VER
-bool Message_DataType_IsValid(int value) {
- switch(value) {
- case 0:
- case 1:
- return true;
- default:
- return false;
- }
-}
-
-#ifndef _MSC_VER
-const Message_DataType Message::ReferencedImage;
-const Message_DataType Message::NonreferencedImage;
-const Message_DataType Message::DataType_MIN;
-const Message_DataType Message::DataType_MAX;
-const int Message::DataType_ARRAYSIZE;
-#endif // _MSC_VER
-bool Message_Prop_IsValid(int value) {
- switch(value) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- return true;
- default:
- return false;
- }
-}
-
-#ifndef _MSC_VER
-const Message_Prop Message::CaptureDraw;
-const Message_Prop Message::TimeMode;
-const Message_Prop Message::ExpectResponse;
-const Message_Prop Message::CaptureSwap;
-const Message_Prop Message::GLConstant;
-const Message_Prop Message::Prop_MIN;
-const Message_Prop Message::Prop_MAX;
-const int Message::Prop_ARRAYSIZE;
-#endif // _MSC_VER
-const ::std::string Message::_default_data_;
-#ifndef _MSC_VER
-const int Message::kContextIdFieldNumber;
-const int Message::kFunctionFieldNumber;
-const int Message::kTypeFieldNumber;
-const int Message::kExpectResponseFieldNumber;
-const int Message::kRetFieldNumber;
-const int Message::kArg0FieldNumber;
-const int Message::kArg1FieldNumber;
-const int Message::kArg2FieldNumber;
-const int Message::kArg3FieldNumber;
-const int Message::kArg4FieldNumber;
-const int Message::kArg5FieldNumber;
-const int Message::kArg6FieldNumber;
-const int Message::kArg7FieldNumber;
-const int Message::kArg8FieldNumber;
-const int Message::kDataFieldNumber;
-const int Message::kDataTypeFieldNumber;
-const int Message::kPixelFormatFieldNumber;
-const int Message::kPixelTypeFieldNumber;
-const int Message::kImageWidthFieldNumber;
-const int Message::kImageHeightFieldNumber;
-const int Message::kTimeFieldNumber;
-const int Message::kPropFieldNumber;
-const int Message::kClockFieldNumber;
-#endif // !_MSC_VER
-
-Message::Message()
- : ::google::protobuf::MessageLite() {
- SharedCtor();
-}
-
-void Message::InitAsDefaultInstance() {
-}
-
-Message::Message(const Message& from)
- : ::google::protobuf::MessageLite() {
- SharedCtor();
- MergeFrom(from);
-}
-
-void Message::SharedCtor() {
- _cached_size_ = 0;
- context_id_ = 0;
- function_ = 187;
- type_ = 0;
- expect_response_ = false;
- ret_ = 0;
- arg0_ = 0;
- arg1_ = 0;
- arg2_ = 0;
- arg3_ = 0;
- arg4_ = 0;
- arg5_ = 0;
- arg6_ = 0;
- arg7_ = 0;
- arg8_ = 0;
- data_ = const_cast< ::std::string*>(&_default_data_);
- data_type_ = 0;
- pixel_format_ = 0;
- pixel_type_ = 0;
- image_width_ = 0;
- image_height_ = 0;
- time_ = 0;
- prop_ = 0;
- clock_ = 0;
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
-}
-
-Message::~Message() {
- SharedDtor();
-}
-
-void Message::SharedDtor() {
- if (data_ != &_default_data_) {
- delete data_;
- }
- if (this != default_instance_) {
- }
-}
-
-void Message::SetCachedSize(int size) const {
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
-}
-const Message& Message::default_instance() {
- if (default_instance_ == NULL) protobuf_AddDesc_debugger_5fmessage_2eproto(); return *default_instance_;
-}
-
-Message* Message::default_instance_ = NULL;
-
-Message* Message::New() const {
- return new Message;
-}
-
-void Message::Clear() {
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- context_id_ = 0;
- function_ = 187;
- type_ = 0;
- expect_response_ = false;
- ret_ = 0;
- arg0_ = 0;
- arg1_ = 0;
- arg2_ = 0;
- }
- if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- arg3_ = 0;
- arg4_ = 0;
- arg5_ = 0;
- arg6_ = 0;
- arg7_ = 0;
- arg8_ = 0;
- if (_has_bit(14)) {
- if (data_ != &_default_data_) {
- data_->clear();
- }
- }
- data_type_ = 0;
- }
- if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
- pixel_format_ = 0;
- pixel_type_ = 0;
- image_width_ = 0;
- image_height_ = 0;
- time_ = 0;
- prop_ = 0;
- clock_ = 0;
- }
- ::memset(_has_bits_, 0, sizeof(_has_bits_));
-}
-
-bool Message::MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
- ::google::protobuf::uint32 tag;
- while ((tag = input->ReadTag()) != 0) {
- switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
- // required int32 context_id = 1;
- case 1: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &context_id_)));
- _set_bit(0);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(16)) goto parse_function;
- break;
- }
-
- // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
- case 2: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_function:
- int value;
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
- input, &value)));
- if (::com::android::glesv2debugger::Message_Function_IsValid(value)) {
- set_function(static_cast< ::com::android::glesv2debugger::Message_Function >(value));
- }
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(24)) goto parse_type;
- break;
- }
-
- // required .com.android.glesv2debugger.Message.Type type = 3;
- case 3: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_type:
- int value;
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
- input, &value)));
- if (::com::android::glesv2debugger::Message_Type_IsValid(value)) {
- set_type(static_cast< ::com::android::glesv2debugger::Message_Type >(value));
- }
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(32)) goto parse_expect_response;
- break;
- }
-
- // required bool expect_response = 4;
- case 4: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_expect_response:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
- input, &expect_response_)));
- _set_bit(3);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(40)) goto parse_ret;
- break;
- }
-
- // optional int32 ret = 5;
- case 5: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_ret:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &ret_)));
- _set_bit(4);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(48)) goto parse_arg0;
- break;
- }
-
- // optional int32 arg0 = 6;
- case 6: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg0:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg0_)));
- _set_bit(5);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(56)) goto parse_arg1;
- break;
- }
-
- // optional int32 arg1 = 7;
- case 7: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg1:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg1_)));
- _set_bit(6);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(64)) goto parse_arg2;
- break;
- }
-
- // optional int32 arg2 = 8;
- case 8: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg2:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg2_)));
- _set_bit(7);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(72)) goto parse_arg3;
- break;
- }
-
- // optional int32 arg3 = 9;
- case 9: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg3:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg3_)));
- _set_bit(8);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(82)) goto parse_data;
- break;
- }
-
- // optional bytes data = 10;
- case 10: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
- parse_data:
- DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
- input, this->mutable_data()));
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(93)) goto parse_time;
- break;
- }
-
- // optional float time = 11;
- case 11: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
- parse_time:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
- input, &time_)));
- _set_bit(20);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(128)) goto parse_arg4;
- break;
- }
-
- // optional int32 arg4 = 16;
- case 16: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg4:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg4_)));
- _set_bit(9);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(136)) goto parse_arg5;
- break;
- }
-
- // optional int32 arg5 = 17;
- case 17: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg5:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg5_)));
- _set_bit(10);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(144)) goto parse_arg6;
- break;
- }
-
- // optional int32 arg6 = 18;
- case 18: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg6:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg6_)));
- _set_bit(11);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(152)) goto parse_arg7;
- break;
- }
-
- // optional int32 arg7 = 19;
- case 19: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg7:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg7_)));
- _set_bit(12);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(160)) goto parse_arg8;
- break;
- }
-
- // optional int32 arg8 = 20;
- case 20: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_arg8:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &arg8_)));
- _set_bit(13);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(168)) goto parse_prop;
- break;
- }
-
- // optional .com.android.glesv2debugger.Message.Prop prop = 21;
- case 21: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_prop:
- int value;
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
- input, &value)));
- if (::com::android::glesv2debugger::Message_Prop_IsValid(value)) {
- set_prop(static_cast< ::com::android::glesv2debugger::Message_Prop >(value));
- }
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(181)) goto parse_clock;
- break;
- }
-
- // optional float clock = 22;
- case 22: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
- parse_clock:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
- input, &clock_)));
- _set_bit(22);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(184)) goto parse_data_type;
- break;
- }
-
- // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
- case 23: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_data_type:
- int value;
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
- input, &value)));
- if (::com::android::glesv2debugger::Message_DataType_IsValid(value)) {
- set_data_type(static_cast< ::com::android::glesv2debugger::Message_DataType >(value));
- }
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(192)) goto parse_pixel_format;
- break;
- }
-
- // optional int32 pixel_format = 24;
- case 24: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_pixel_format:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &pixel_format_)));
- _set_bit(16);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(200)) goto parse_pixel_type;
- break;
- }
-
- // optional int32 pixel_type = 25;
- case 25: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_pixel_type:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &pixel_type_)));
- _set_bit(17);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(208)) goto parse_image_width;
- break;
- }
-
- // optional int32 image_width = 26;
- case 26: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_image_width:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &image_width_)));
- _set_bit(18);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectTag(216)) goto parse_image_height;
- break;
- }
-
- // optional int32 image_height = 27;
- case 27: {
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
- parse_image_height:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
- input, &image_height_)));
- _set_bit(19);
- } else {
- goto handle_uninterpreted;
- }
- if (input->ExpectAtEnd()) return true;
- break;
- }
-
- default: {
- handle_uninterpreted:
- if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
- ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
- return true;
- }
- DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
- break;
- }
- }
- }
- return true;
-#undef DO_
-}
-
-void Message::SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const {
- // required int32 context_id = 1;
- if (_has_bit(0)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->context_id(), output);
- }
-
- // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
- if (_has_bit(1)) {
- ::google::protobuf::internal::WireFormatLite::WriteEnum(
- 2, this->function(), output);
- }
-
- // required .com.android.glesv2debugger.Message.Type type = 3;
- if (_has_bit(2)) {
- ::google::protobuf::internal::WireFormatLite::WriteEnum(
- 3, this->type(), output);
- }
-
- // required bool expect_response = 4;
- if (_has_bit(3)) {
- ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->expect_response(), output);
- }
-
- // optional int32 ret = 5;
- if (_has_bit(4)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(5, this->ret(), output);
- }
-
- // optional int32 arg0 = 6;
- if (_has_bit(5)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(6, this->arg0(), output);
- }
-
- // optional int32 arg1 = 7;
- if (_has_bit(6)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->arg1(), output);
- }
-
- // optional int32 arg2 = 8;
- if (_has_bit(7)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(8, this->arg2(), output);
- }
-
- // optional int32 arg3 = 9;
- if (_has_bit(8)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->arg3(), output);
- }
-
- // optional bytes data = 10;
- if (_has_bit(14)) {
- ::google::protobuf::internal::WireFormatLite::WriteBytes(
- 10, this->data(), output);
- }
-
- // optional float time = 11;
- if (_has_bit(20)) {
- ::google::protobuf::internal::WireFormatLite::WriteFloat(11, this->time(), output);
- }
-
- // optional int32 arg4 = 16;
- if (_has_bit(9)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(16, this->arg4(), output);
- }
-
- // optional int32 arg5 = 17;
- if (_has_bit(10)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(17, this->arg5(), output);
- }
-
- // optional int32 arg6 = 18;
- if (_has_bit(11)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(18, this->arg6(), output);
- }
-
- // optional int32 arg7 = 19;
- if (_has_bit(12)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(19, this->arg7(), output);
- }
-
- // optional int32 arg8 = 20;
- if (_has_bit(13)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(20, this->arg8(), output);
- }
-
- // optional .com.android.glesv2debugger.Message.Prop prop = 21;
- if (_has_bit(21)) {
- ::google::protobuf::internal::WireFormatLite::WriteEnum(
- 21, this->prop(), output);
- }
-
- // optional float clock = 22;
- if (_has_bit(22)) {
- ::google::protobuf::internal::WireFormatLite::WriteFloat(22, this->clock(), output);
- }
-
- // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
- if (_has_bit(15)) {
- ::google::protobuf::internal::WireFormatLite::WriteEnum(
- 23, this->data_type(), output);
- }
-
- // optional int32 pixel_format = 24;
- if (_has_bit(16)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(24, this->pixel_format(), output);
- }
-
- // optional int32 pixel_type = 25;
- if (_has_bit(17)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(25, this->pixel_type(), output);
- }
-
- // optional int32 image_width = 26;
- if (_has_bit(18)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(26, this->image_width(), output);
- }
-
- // optional int32 image_height = 27;
- if (_has_bit(19)) {
- ::google::protobuf::internal::WireFormatLite::WriteInt32(27, this->image_height(), output);
- }
-
-}
-
-int Message::ByteSize() const {
- int total_size = 0;
-
- if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- // required int32 context_id = 1;
- if (has_context_id()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->context_id());
- }
-
- // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
- if (has_function()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::EnumSize(this->function());
- }
-
- // required .com.android.glesv2debugger.Message.Type type = 3;
- if (has_type()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
- }
-
- // required bool expect_response = 4;
- if (has_expect_response()) {
- total_size += 1 + 1;
- }
-
- // optional int32 ret = 5;
- if (has_ret()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->ret());
- }
-
- // optional int32 arg0 = 6;
- if (has_arg0()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg0());
- }
-
- // optional int32 arg1 = 7;
- if (has_arg1()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg1());
- }
-
- // optional int32 arg2 = 8;
- if (has_arg2()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg2());
- }
-
- }
- if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- // optional int32 arg3 = 9;
- if (has_arg3()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg3());
- }
-
- // optional int32 arg4 = 16;
- if (has_arg4()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg4());
- }
-
- // optional int32 arg5 = 17;
- if (has_arg5()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg5());
- }
-
- // optional int32 arg6 = 18;
- if (has_arg6()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg6());
- }
-
- // optional int32 arg7 = 19;
- if (has_arg7()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg7());
- }
-
- // optional int32 arg8 = 20;
- if (has_arg8()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->arg8());
- }
-
- // optional bytes data = 10;
- if (has_data()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::BytesSize(
- this->data());
- }
-
- // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
- if (has_data_type()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::EnumSize(this->data_type());
- }
-
- }
- if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) {
- // optional int32 pixel_format = 24;
- if (has_pixel_format()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->pixel_format());
- }
-
- // optional int32 pixel_type = 25;
- if (has_pixel_type()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->pixel_type());
- }
-
- // optional int32 image_width = 26;
- if (has_image_width()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->image_width());
- }
-
- // optional int32 image_height = 27;
- if (has_image_height()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::Int32Size(
- this->image_height());
- }
-
- // optional float time = 11;
- if (has_time()) {
- total_size += 1 + 4;
- }
-
- // optional .com.android.glesv2debugger.Message.Prop prop = 21;
- if (has_prop()) {
- total_size += 2 +
- ::google::protobuf::internal::WireFormatLite::EnumSize(this->prop());
- }
-
- // optional float clock = 22;
- if (has_clock()) {
- total_size += 2 + 4;
- }
-
- }
- GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
- _cached_size_ = total_size;
- GOOGLE_SAFE_CONCURRENT_WRITES_END();
- return total_size;
-}
-
-void Message::CheckTypeAndMergeFrom(
- const ::google::protobuf::MessageLite& from) {
- MergeFrom(*::google::protobuf::down_cast<const Message*>(&from));
-}
-
-void Message::MergeFrom(const Message& from) {
- GOOGLE_CHECK_NE(&from, this);
- if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
- if (from._has_bit(0)) {
- set_context_id(from.context_id());
- }
- if (from._has_bit(1)) {
- set_function(from.function());
- }
- if (from._has_bit(2)) {
- set_type(from.type());
- }
- if (from._has_bit(3)) {
- set_expect_response(from.expect_response());
- }
- if (from._has_bit(4)) {
- set_ret(from.ret());
- }
- if (from._has_bit(5)) {
- set_arg0(from.arg0());
- }
- if (from._has_bit(6)) {
- set_arg1(from.arg1());
- }
- if (from._has_bit(7)) {
- set_arg2(from.arg2());
- }
- }
- if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
- if (from._has_bit(8)) {
- set_arg3(from.arg3());
- }
- if (from._has_bit(9)) {
- set_arg4(from.arg4());
- }
- if (from._has_bit(10)) {
- set_arg5(from.arg5());
- }
- if (from._has_bit(11)) {
- set_arg6(from.arg6());
- }
- if (from._has_bit(12)) {
- set_arg7(from.arg7());
- }
- if (from._has_bit(13)) {
- set_arg8(from.arg8());
- }
- if (from._has_bit(14)) {
- set_data(from.data());
- }
- if (from._has_bit(15)) {
- set_data_type(from.data_type());
- }
- }
- if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) {
- if (from._has_bit(16)) {
- set_pixel_format(from.pixel_format());
- }
- if (from._has_bit(17)) {
- set_pixel_type(from.pixel_type());
- }
- if (from._has_bit(18)) {
- set_image_width(from.image_width());
- }
- if (from._has_bit(19)) {
- set_image_height(from.image_height());
- }
- if (from._has_bit(20)) {
- set_time(from.time());
- }
- if (from._has_bit(21)) {
- set_prop(from.prop());
- }
- if (from._has_bit(22)) {
- set_clock(from.clock());
- }
- }
-}
-
-void Message::CopyFrom(const Message& from) {
- if (&from == this) return;
- Clear();
- MergeFrom(from);
-}
-
-bool Message::IsInitialized() const {
- if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false;
-
- return true;
-}
-
-void Message::Swap(Message* other) {
- if (other != this) {
- std::swap(context_id_, other->context_id_);
- std::swap(function_, other->function_);
- std::swap(type_, other->type_);
- std::swap(expect_response_, other->expect_response_);
- std::swap(ret_, other->ret_);
- std::swap(arg0_, other->arg0_);
- std::swap(arg1_, other->arg1_);
- std::swap(arg2_, other->arg2_);
- std::swap(arg3_, other->arg3_);
- std::swap(arg4_, other->arg4_);
- std::swap(arg5_, other->arg5_);
- std::swap(arg6_, other->arg6_);
- std::swap(arg7_, other->arg7_);
- std::swap(arg8_, other->arg8_);
- std::swap(data_, other->data_);
- std::swap(data_type_, other->data_type_);
- std::swap(pixel_format_, other->pixel_format_);
- std::swap(pixel_type_, other->pixel_type_);
- std::swap(image_width_, other->image_width_);
- std::swap(image_height_, other->image_height_);
- std::swap(time_, other->time_);
- std::swap(prop_, other->prop_);
- std::swap(clock_, other->clock_);
- std::swap(_has_bits_[0], other->_has_bits_[0]);
- std::swap(_cached_size_, other->_cached_size_);
- }
-}
-
-::std::string Message::GetTypeName() const {
- return "com.android.glesv2debugger.Message";
-}
-
-
-// @@protoc_insertion_point(namespace_scope)
-
-} // namespace glesv2debugger
-} // namespace android
-} // namespace com
-
-// @@protoc_insertion_point(global_scope)
diff --git a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h b/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
deleted file mode 100644
index 5c946644a1a9..000000000000
--- a/opengl/libs/GLES2_dbg/src/debugger_message.pb.h
+++ /dev/null
@@ -1,1187 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: debugger_message.proto
-
-#ifndef PROTOBUF_debugger_5fmessage_2eproto__INCLUDED
-#define PROTOBUF_debugger_5fmessage_2eproto__INCLUDED
-
-#include <string>
-
-#include <google/protobuf/stubs/common.h>
-
-#if GOOGLE_PROTOBUF_VERSION < 2003000
-#error This file was generated by a newer version of protoc which is
-#error incompatible with your Protocol Buffer headers. Please update
-#error your headers.
-#endif
-#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
-#error This file was generated by an older version of protoc which is
-#error incompatible with your Protocol Buffer headers. Please
-#error regenerate this file with a newer version of protoc.
-#endif
-
-#include <google/protobuf/generated_message_util.h>
-#include <google/protobuf/repeated_field.h>
-#include <google/protobuf/extension_set.h>
-// @@protoc_insertion_point(includes)
-
-namespace com {
-namespace android {
-namespace glesv2debugger {
-
-// Internal implementation detail -- do not call these.
-void protobuf_AddDesc_debugger_5fmessage_2eproto();
-void protobuf_AssignDesc_debugger_5fmessage_2eproto();
-void protobuf_ShutdownFile_debugger_5fmessage_2eproto();
-
-class Message;
-
-enum Message_Function {
- Message_Function_glActiveTexture = 0,
- Message_Function_glAttachShader = 1,
- Message_Function_glBindAttribLocation = 2,
- Message_Function_glBindBuffer = 3,
- Message_Function_glBindFramebuffer = 4,
- Message_Function_glBindRenderbuffer = 5,
- Message_Function_glBindTexture = 6,
- Message_Function_glBlendColor = 7,
- Message_Function_glBlendEquation = 8,
- Message_Function_glBlendEquationSeparate = 9,
- Message_Function_glBlendFunc = 10,
- Message_Function_glBlendFuncSeparate = 11,
- Message_Function_glBufferData = 12,
- Message_Function_glBufferSubData = 13,
- Message_Function_glCheckFramebufferStatus = 14,
- Message_Function_glClear = 15,
- Message_Function_glClearColor = 16,
- Message_Function_glClearDepthf = 17,
- Message_Function_glClearStencil = 18,
- Message_Function_glColorMask = 19,
- Message_Function_glCompileShader = 20,
- Message_Function_glCompressedTexImage2D = 21,
- Message_Function_glCompressedTexSubImage2D = 22,
- Message_Function_glCopyTexImage2D = 23,
- Message_Function_glCopyTexSubImage2D = 24,
- Message_Function_glCreateProgram = 25,
- Message_Function_glCreateShader = 26,
- Message_Function_glCullFace = 27,
- Message_Function_glDeleteBuffers = 28,
- Message_Function_glDeleteFramebuffers = 29,
- Message_Function_glDeleteProgram = 30,
- Message_Function_glDeleteRenderbuffers = 31,
- Message_Function_glDeleteShader = 32,
- Message_Function_glDeleteTextures = 33,
- Message_Function_glDepthFunc = 34,
- Message_Function_glDepthMask = 35,
- Message_Function_glDepthRangef = 36,
- Message_Function_glDetachShader = 37,
- Message_Function_glDisable = 38,
- Message_Function_glDisableVertexAttribArray = 39,
- Message_Function_glDrawArrays = 40,
- Message_Function_glDrawElements = 41,
- Message_Function_glEnable = 42,
- Message_Function_glEnableVertexAttribArray = 43,
- Message_Function_glFinish = 44,
- Message_Function_glFlush = 45,
- Message_Function_glFramebufferRenderbuffer = 46,
- Message_Function_glFramebufferTexture2D = 47,
- Message_Function_glFrontFace = 48,
- Message_Function_glGenBuffers = 49,
- Message_Function_glGenerateMipmap = 50,
- Message_Function_glGenFramebuffers = 51,
- Message_Function_glGenRenderbuffers = 52,
- Message_Function_glGenTextures = 53,
- Message_Function_glGetActiveAttrib = 54,
- Message_Function_glGetActiveUniform = 55,
- Message_Function_glGetAttachedShaders = 56,
- Message_Function_glGetAttribLocation = 57,
- Message_Function_glGetBooleanv = 58,
- Message_Function_glGetBufferParameteriv = 59,
- Message_Function_glGetError = 60,
- Message_Function_glGetFloatv = 61,
- Message_Function_glGetFramebufferAttachmentParameteriv = 62,
- Message_Function_glGetIntegerv = 63,
- Message_Function_glGetProgramiv = 64,
- Message_Function_glGetProgramInfoLog = 65,
- Message_Function_glGetRenderbufferParameteriv = 66,
- Message_Function_glGetShaderiv = 67,
- Message_Function_glGetShaderInfoLog = 68,
- Message_Function_glGetShaderPrecisionFormat = 69,
- Message_Function_glGetShaderSource = 70,
- Message_Function_glGetString = 71,
- Message_Function_glGetTexParameterfv = 72,
- Message_Function_glGetTexParameteriv = 73,
- Message_Function_glGetUniformfv = 74,
- Message_Function_glGetUniformiv = 75,
- Message_Function_glGetUniformLocation = 76,
- Message_Function_glGetVertexAttribfv = 77,
- Message_Function_glGetVertexAttribiv = 78,
- Message_Function_glGetVertexAttribPointerv = 79,
- Message_Function_glHint = 80,
- Message_Function_glIsBuffer = 81,
- Message_Function_glIsEnabled = 82,
- Message_Function_glIsFramebuffer = 83,
- Message_Function_glIsProgram = 84,
- Message_Function_glIsRenderbuffer = 85,
- Message_Function_glIsShader = 86,
- Message_Function_glIsTexture = 87,
- Message_Function_glLineWidth = 88,
- Message_Function_glLinkProgram = 89,
- Message_Function_glPixelStorei = 90,
- Message_Function_glPolygonOffset = 91,
- Message_Function_glReadPixels = 92,
- Message_Function_glReleaseShaderCompiler = 93,
- Message_Function_glRenderbufferStorage = 94,
- Message_Function_glSampleCoverage = 95,
- Message_Function_glScissor = 96,
- Message_Function_glShaderBinary = 97,
- Message_Function_glShaderSource = 98,
- Message_Function_glStencilFunc = 99,
- Message_Function_glStencilFuncSeparate = 100,
- Message_Function_glStencilMask = 101,
- Message_Function_glStencilMaskSeparate = 102,
- Message_Function_glStencilOp = 103,
- Message_Function_glStencilOpSeparate = 104,
- Message_Function_glTexImage2D = 105,
- Message_Function_glTexParameterf = 106,
- Message_Function_glTexParameterfv = 107,
- Message_Function_glTexParameteri = 108,
- Message_Function_glTexParameteriv = 109,
- Message_Function_glTexSubImage2D = 110,
- Message_Function_glUniform1f = 111,
- Message_Function_glUniform1fv = 112,
- Message_Function_glUniform1i = 113,
- Message_Function_glUniform1iv = 114,
- Message_Function_glUniform2f = 115,
- Message_Function_glUniform2fv = 116,
- Message_Function_glUniform2i = 117,
- Message_Function_glUniform2iv = 118,
- Message_Function_glUniform3f = 119,
- Message_Function_glUniform3fv = 120,
- Message_Function_glUniform3i = 121,
- Message_Function_glUniform3iv = 122,
- Message_Function_glUniform4f = 123,
- Message_Function_glUniform4fv = 124,
- Message_Function_glUniform4i = 125,
- Message_Function_glUniform4iv = 126,
- Message_Function_glUniformMatrix2fv = 127,
- Message_Function_glUniformMatrix3fv = 128,
- Message_Function_glUniformMatrix4fv = 129,
- Message_Function_glUseProgram = 130,
- Message_Function_glValidateProgram = 131,
- Message_Function_glVertexAttrib1f = 132,
- Message_Function_glVertexAttrib1fv = 133,
- Message_Function_glVertexAttrib2f = 134,
- Message_Function_glVertexAttrib2fv = 135,
- Message_Function_glVertexAttrib3f = 136,
- Message_Function_glVertexAttrib3fv = 137,
- Message_Function_glVertexAttrib4f = 138,
- Message_Function_glVertexAttrib4fv = 139,
- Message_Function_glVertexAttribPointer = 140,
- Message_Function_glViewport = 141,
- Message_Function_eglGetDisplay = 142,
- Message_Function_eglInitialize = 143,
- Message_Function_eglTerminate = 144,
- Message_Function_eglGetConfigs = 145,
- Message_Function_eglChooseConfig = 146,
- Message_Function_eglGetConfigAttrib = 147,
- Message_Function_eglCreateWindowSurface = 148,
- Message_Function_eglCreatePixmapSurface = 149,
- Message_Function_eglCreatePbufferSurface = 150,
- Message_Function_eglDestroySurface = 151,
- Message_Function_eglQuerySurface = 152,
- Message_Function_eglCreateContext = 153,
- Message_Function_eglDestroyContext = 154,
- Message_Function_eglMakeCurrent = 155,
- Message_Function_eglGetCurrentContext = 156,
- Message_Function_eglGetCurrentSurface = 157,
- Message_Function_eglGetCurrentDisplay = 158,
- Message_Function_eglQueryContext = 159,
- Message_Function_eglWaitGL = 160,
- Message_Function_eglWaitNative = 161,
- Message_Function_eglSwapBuffers = 162,
- Message_Function_eglCopyBuffers = 163,
- Message_Function_eglGetError = 164,
- Message_Function_eglQueryString = 165,
- Message_Function_eglGetProcAddress = 166,
- Message_Function_eglSurfaceAttrib = 167,
- Message_Function_eglBindTexImage = 168,
- Message_Function_eglReleaseTexImage = 169,
- Message_Function_eglSwapInterval = 170,
- Message_Function_eglBindAPI = 171,
- Message_Function_eglQueryAPI = 172,
- Message_Function_eglWaitClient = 173,
- Message_Function_eglReleaseThread = 174,
- Message_Function_eglCreatePbufferFromClientBuffer = 175,
- Message_Function_eglLockSurfaceKHR = 176,
- Message_Function_eglUnlockSurfaceKHR = 177,
- Message_Function_eglCreateImageKHR = 178,
- Message_Function_eglDestroyImageKHR = 179,
- Message_Function_eglCreateSyncKHR = 180,
- Message_Function_eglDestroySyncKHR = 181,
- Message_Function_eglClientWaitSyncKHR = 182,
- Message_Function_eglGetSyncAttribKHR = 183,
- Message_Function_eglSetSwapRectangleANDROID = 184,
- Message_Function_eglGetRenderBufferANDROID = 185,
- Message_Function_ACK = 186,
- Message_Function_NEG = 187,
- Message_Function_CONTINUE = 188,
- Message_Function_SKIP = 189,
- Message_Function_SETPROP = 190
-};
-bool Message_Function_IsValid(int value);
-const Message_Function Message_Function_Function_MIN = Message_Function_glActiveTexture;
-const Message_Function Message_Function_Function_MAX = Message_Function_SETPROP;
-const int Message_Function_Function_ARRAYSIZE = Message_Function_Function_MAX + 1;
-
-enum Message_Type {
- Message_Type_BeforeCall = 0,
- Message_Type_AfterCall = 1,
- Message_Type_AfterGeneratedCall = 2,
- Message_Type_Response = 3,
- Message_Type_CompleteCall = 4
-};
-bool Message_Type_IsValid(int value);
-const Message_Type Message_Type_Type_MIN = Message_Type_BeforeCall;
-const Message_Type Message_Type_Type_MAX = Message_Type_CompleteCall;
-const int Message_Type_Type_ARRAYSIZE = Message_Type_Type_MAX + 1;
-
-enum Message_DataType {
- Message_DataType_ReferencedImage = 0,
- Message_DataType_NonreferencedImage = 1
-};
-bool Message_DataType_IsValid(int value);
-const Message_DataType Message_DataType_DataType_MIN = Message_DataType_ReferencedImage;
-const Message_DataType Message_DataType_DataType_MAX = Message_DataType_NonreferencedImage;
-const int Message_DataType_DataType_ARRAYSIZE = Message_DataType_DataType_MAX + 1;
-
-enum Message_Prop {
- Message_Prop_CaptureDraw = 0,
- Message_Prop_TimeMode = 1,
- Message_Prop_ExpectResponse = 2,
- Message_Prop_CaptureSwap = 3,
- Message_Prop_GLConstant = 4
-};
-bool Message_Prop_IsValid(int value);
-const Message_Prop Message_Prop_Prop_MIN = Message_Prop_CaptureDraw;
-const Message_Prop Message_Prop_Prop_MAX = Message_Prop_GLConstant;
-const int Message_Prop_Prop_ARRAYSIZE = Message_Prop_Prop_MAX + 1;
-
-// ===================================================================
-
-class Message : public ::google::protobuf::MessageLite {
- public:
- Message();
- virtual ~Message();
-
- Message(const Message& from);
-
- inline Message& operator=(const Message& from) {
- CopyFrom(from);
- return *this;
- }
-
- static const Message& default_instance();
-
- void Swap(Message* other);
-
- // implements Message ----------------------------------------------
-
- Message* New() const;
- void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
- void CopyFrom(const Message& from);
- void MergeFrom(const Message& from);
- void Clear();
- bool IsInitialized() const;
-
- int ByteSize() const;
- bool MergePartialFromCodedStream(
- ::google::protobuf::io::CodedInputStream* input);
- void SerializeWithCachedSizes(
- ::google::protobuf::io::CodedOutputStream* output) const;
- int GetCachedSize() const { return _cached_size_; }
- private:
- void SharedCtor();
- void SharedDtor();
- void SetCachedSize(int size) const;
- public:
-
- ::std::string GetTypeName() const;
-
- // nested types ----------------------------------------------------
-
- typedef Message_Function Function;
- static const Function glActiveTexture = Message_Function_glActiveTexture;
- static const Function glAttachShader = Message_Function_glAttachShader;
- static const Function glBindAttribLocation = Message_Function_glBindAttribLocation;
- static const Function glBindBuffer = Message_Function_glBindBuffer;
- static const Function glBindFramebuffer = Message_Function_glBindFramebuffer;
- static const Function glBindRenderbuffer = Message_Function_glBindRenderbuffer;
- static const Function glBindTexture = Message_Function_glBindTexture;
- static const Function glBlendColor = Message_Function_glBlendColor;
- static const Function glBlendEquation = Message_Function_glBlendEquation;
- static const Function glBlendEquationSeparate = Message_Function_glBlendEquationSeparate;
- static const Function glBlendFunc = Message_Function_glBlendFunc;
- static const Function glBlendFuncSeparate = Message_Function_glBlendFuncSeparate;
- static const Function glBufferData = Message_Function_glBufferData;
- static const Function glBufferSubData = Message_Function_glBufferSubData;
- static const Function glCheckFramebufferStatus = Message_Function_glCheckFramebufferStatus;
- static const Function glClear = Message_Function_glClear;
- static const Function glClearColor = Message_Function_glClearColor;
- static const Function glClearDepthf = Message_Function_glClearDepthf;
- static const Function glClearStencil = Message_Function_glClearStencil;
- static const Function glColorMask = Message_Function_glColorMask;
- static const Function glCompileShader = Message_Function_glCompileShader;
- static const Function glCompressedTexImage2D = Message_Function_glCompressedTexImage2D;
- static const Function glCompressedTexSubImage2D = Message_Function_glCompressedTexSubImage2D;
- static const Function glCopyTexImage2D = Message_Function_glCopyTexImage2D;
- static const Function glCopyTexSubImage2D = Message_Function_glCopyTexSubImage2D;
- static const Function glCreateProgram = Message_Function_glCreateProgram;
- static const Function glCreateShader = Message_Function_glCreateShader;
- static const Function glCullFace = Message_Function_glCullFace;
- static const Function glDeleteBuffers = Message_Function_glDeleteBuffers;
- static const Function glDeleteFramebuffers = Message_Function_glDeleteFramebuffers;
- static const Function glDeleteProgram = Message_Function_glDeleteProgram;
- static const Function glDeleteRenderbuffers = Message_Function_glDeleteRenderbuffers;
- static const Function glDeleteShader = Message_Function_glDeleteShader;
- static const Function glDeleteTextures = Message_Function_glDeleteTextures;
- static const Function glDepthFunc = Message_Function_glDepthFunc;
- static const Function glDepthMask = Message_Function_glDepthMask;
- static const Function glDepthRangef = Message_Function_glDepthRangef;
- static const Function glDetachShader = Message_Function_glDetachShader;
- static const Function glDisable = Message_Function_glDisable;
- static const Function glDisableVertexAttribArray = Message_Function_glDisableVertexAttribArray;
- static const Function glDrawArrays = Message_Function_glDrawArrays;
- static const Function glDrawElements = Message_Function_glDrawElements;
- static const Function glEnable = Message_Function_glEnable;
- static const Function glEnableVertexAttribArray = Message_Function_glEnableVertexAttribArray;
- static const Function glFinish = Message_Function_glFinish;
- static const Function glFlush = Message_Function_glFlush;
- static const Function glFramebufferRenderbuffer = Message_Function_glFramebufferRenderbuffer;
- static const Function glFramebufferTexture2D = Message_Function_glFramebufferTexture2D;
- static const Function glFrontFace = Message_Function_glFrontFace;
- static const Function glGenBuffers = Message_Function_glGenBuffers;
- static const Function glGenerateMipmap = Message_Function_glGenerateMipmap;
- static const Function glGenFramebuffers = Message_Function_glGenFramebuffers;
- static const Function glGenRenderbuffers = Message_Function_glGenRenderbuffers;
- static const Function glGenTextures = Message_Function_glGenTextures;
- static const Function glGetActiveAttrib = Message_Function_glGetActiveAttrib;
- static const Function glGetActiveUniform = Message_Function_glGetActiveUniform;
- static const Function glGetAttachedShaders = Message_Function_glGetAttachedShaders;
- static const Function glGetAttribLocation = Message_Function_glGetAttribLocation;
- static const Function glGetBooleanv = Message_Function_glGetBooleanv;
- static const Function glGetBufferParameteriv = Message_Function_glGetBufferParameteriv;
- static const Function glGetError = Message_Function_glGetError;
- static const Function glGetFloatv = Message_Function_glGetFloatv;
- static const Function glGetFramebufferAttachmentParameteriv = Message_Function_glGetFramebufferAttachmentParameteriv;
- static const Function glGetIntegerv = Message_Function_glGetIntegerv;
- static const Function glGetProgramiv = Message_Function_glGetProgramiv;
- static const Function glGetProgramInfoLog = Message_Function_glGetProgramInfoLog;
- static const Function glGetRenderbufferParameteriv = Message_Function_glGetRenderbufferParameteriv;
- static const Function glGetShaderiv = Message_Function_glGetShaderiv;
- static const Function glGetShaderInfoLog = Message_Function_glGetShaderInfoLog;
- static const Function glGetShaderPrecisionFormat = Message_Function_glGetShaderPrecisionFormat;
- static const Function glGetShaderSource = Message_Function_glGetShaderSource;
- static const Function glGetString = Message_Function_glGetString;
- static const Function glGetTexParameterfv = Message_Function_glGetTexParameterfv;
- static const Function glGetTexParameteriv = Message_Function_glGetTexParameteriv;
- static const Function glGetUniformfv = Message_Function_glGetUniformfv;
- static const Function glGetUniformiv = Message_Function_glGetUniformiv;
- static const Function glGetUniformLocation = Message_Function_glGetUniformLocation;
- static const Function glGetVertexAttribfv = Message_Function_glGetVertexAttribfv;
- static const Function glGetVertexAttribiv = Message_Function_glGetVertexAttribiv;
- static const Function glGetVertexAttribPointerv = Message_Function_glGetVertexAttribPointerv;
- static const Function glHint = Message_Function_glHint;
- static const Function glIsBuffer = Message_Function_glIsBuffer;
- static const Function glIsEnabled = Message_Function_glIsEnabled;
- static const Function glIsFramebuffer = Message_Function_glIsFramebuffer;
- static const Function glIsProgram = Message_Function_glIsProgram;
- static const Function glIsRenderbuffer = Message_Function_glIsRenderbuffer;
- static const Function glIsShader = Message_Function_glIsShader;
- static const Function glIsTexture = Message_Function_glIsTexture;
- static const Function glLineWidth = Message_Function_glLineWidth;
- static const Function glLinkProgram = Message_Function_glLinkProgram;
- static const Function glPixelStorei = Message_Function_glPixelStorei;
- static const Function glPolygonOffset = Message_Function_glPolygonOffset;
- static const Function glReadPixels = Message_Function_glReadPixels;
- static const Function glReleaseShaderCompiler = Message_Function_glReleaseShaderCompiler;
- static const Function glRenderbufferStorage = Message_Function_glRenderbufferStorage;
- static const Function glSampleCoverage = Message_Function_glSampleCoverage;
- static const Function glScissor = Message_Function_glScissor;
- static const Function glShaderBinary = Message_Function_glShaderBinary;
- static const Function glShaderSource = Message_Function_glShaderSource;
- static const Function glStencilFunc = Message_Function_glStencilFunc;
- static const Function glStencilFuncSeparate = Message_Function_glStencilFuncSeparate;
- static const Function glStencilMask = Message_Function_glStencilMask;
- static const Function glStencilMaskSeparate = Message_Function_glStencilMaskSeparate;
- static const Function glStencilOp = Message_Function_glStencilOp;
- static const Function glStencilOpSeparate = Message_Function_glStencilOpSeparate;
- static const Function glTexImage2D = Message_Function_glTexImage2D;
- static const Function glTexParameterf = Message_Function_glTexParameterf;
- static const Function glTexParameterfv = Message_Function_glTexParameterfv;
- static const Function glTexParameteri = Message_Function_glTexParameteri;
- static const Function glTexParameteriv = Message_Function_glTexParameteriv;
- static const Function glTexSubImage2D = Message_Function_glTexSubImage2D;
- static const Function glUniform1f = Message_Function_glUniform1f;
- static const Function glUniform1fv = Message_Function_glUniform1fv;
- static const Function glUniform1i = Message_Function_glUniform1i;
- static const Function glUniform1iv = Message_Function_glUniform1iv;
- static const Function glUniform2f = Message_Function_glUniform2f;
- static const Function glUniform2fv = Message_Function_glUniform2fv;
- static const Function glUniform2i = Message_Function_glUniform2i;
- static const Function glUniform2iv = Message_Function_glUniform2iv;
- static const Function glUniform3f = Message_Function_glUniform3f;
- static const Function glUniform3fv = Message_Function_glUniform3fv;
- static const Function glUniform3i = Message_Function_glUniform3i;
- static const Function glUniform3iv = Message_Function_glUniform3iv;
- static const Function glUniform4f = Message_Function_glUniform4f;
- static const Function glUniform4fv = Message_Function_glUniform4fv;
- static const Function glUniform4i = Message_Function_glUniform4i;
- static const Function glUniform4iv = Message_Function_glUniform4iv;
- static const Function glUniformMatrix2fv = Message_Function_glUniformMatrix2fv;
- static const Function glUniformMatrix3fv = Message_Function_glUniformMatrix3fv;
- static const Function glUniformMatrix4fv = Message_Function_glUniformMatrix4fv;
- static const Function glUseProgram = Message_Function_glUseProgram;
- static const Function glValidateProgram = Message_Function_glValidateProgram;
- static const Function glVertexAttrib1f = Message_Function_glVertexAttrib1f;
- static const Function glVertexAttrib1fv = Message_Function_glVertexAttrib1fv;
- static const Function glVertexAttrib2f = Message_Function_glVertexAttrib2f;
- static const Function glVertexAttrib2fv = Message_Function_glVertexAttrib2fv;
- static const Function glVertexAttrib3f = Message_Function_glVertexAttrib3f;
- static const Function glVertexAttrib3fv = Message_Function_glVertexAttrib3fv;
- static const Function glVertexAttrib4f = Message_Function_glVertexAttrib4f;
- static const Function glVertexAttrib4fv = Message_Function_glVertexAttrib4fv;
- static const Function glVertexAttribPointer = Message_Function_glVertexAttribPointer;
- static const Function glViewport = Message_Function_glViewport;
- static const Function eglGetDisplay = Message_Function_eglGetDisplay;
- static const Function eglInitialize = Message_Function_eglInitialize;
- static const Function eglTerminate = Message_Function_eglTerminate;
- static const Function eglGetConfigs = Message_Function_eglGetConfigs;
- static const Function eglChooseConfig = Message_Function_eglChooseConfig;
- static const Function eglGetConfigAttrib = Message_Function_eglGetConfigAttrib;
- static const Function eglCreateWindowSurface = Message_Function_eglCreateWindowSurface;
- static const Function eglCreatePixmapSurface = Message_Function_eglCreatePixmapSurface;
- static const Function eglCreatePbufferSurface = Message_Function_eglCreatePbufferSurface;
- static const Function eglDestroySurface = Message_Function_eglDestroySurface;
- static const Function eglQuerySurface = Message_Function_eglQuerySurface;
- static const Function eglCreateContext = Message_Function_eglCreateContext;
- static const Function eglDestroyContext = Message_Function_eglDestroyContext;
- static const Function eglMakeCurrent = Message_Function_eglMakeCurrent;
- static const Function eglGetCurrentContext = Message_Function_eglGetCurrentContext;
- static const Function eglGetCurrentSurface = Message_Function_eglGetCurrentSurface;
- static const Function eglGetCurrentDisplay = Message_Function_eglGetCurrentDisplay;
- static const Function eglQueryContext = Message_Function_eglQueryContext;
- static const Function eglWaitGL = Message_Function_eglWaitGL;
- static const Function eglWaitNative = Message_Function_eglWaitNative;
- static const Function eglSwapBuffers = Message_Function_eglSwapBuffers;
- static const Function eglCopyBuffers = Message_Function_eglCopyBuffers;
- static const Function eglGetError = Message_Function_eglGetError;
- static const Function eglQueryString = Message_Function_eglQueryString;
- static const Function eglGetProcAddress = Message_Function_eglGetProcAddress;
- static const Function eglSurfaceAttrib = Message_Function_eglSurfaceAttrib;
- static const Function eglBindTexImage = Message_Function_eglBindTexImage;
- static const Function eglReleaseTexImage = Message_Function_eglReleaseTexImage;
- static const Function eglSwapInterval = Message_Function_eglSwapInterval;
- static const Function eglBindAPI = Message_Function_eglBindAPI;
- static const Function eglQueryAPI = Message_Function_eglQueryAPI;
- static const Function eglWaitClient = Message_Function_eglWaitClient;
- static const Function eglReleaseThread = Message_Function_eglReleaseThread;
- static const Function eglCreatePbufferFromClientBuffer = Message_Function_eglCreatePbufferFromClientBuffer;
- static const Function eglLockSurfaceKHR = Message_Function_eglLockSurfaceKHR;
- static const Function eglUnlockSurfaceKHR = Message_Function_eglUnlockSurfaceKHR;
- static const Function eglCreateImageKHR = Message_Function_eglCreateImageKHR;
- static const Function eglDestroyImageKHR = Message_Function_eglDestroyImageKHR;
- static const Function eglCreateSyncKHR = Message_Function_eglCreateSyncKHR;
- static const Function eglDestroySyncKHR = Message_Function_eglDestroySyncKHR;
- static const Function eglClientWaitSyncKHR = Message_Function_eglClientWaitSyncKHR;
- static const Function eglGetSyncAttribKHR = Message_Function_eglGetSyncAttribKHR;
- static const Function eglSetSwapRectangleANDROID = Message_Function_eglSetSwapRectangleANDROID;
- static const Function eglGetRenderBufferANDROID = Message_Function_eglGetRenderBufferANDROID;
- static const Function ACK = Message_Function_ACK;
- static const Function NEG = Message_Function_NEG;
- static const Function CONTINUE = Message_Function_CONTINUE;
- static const Function SKIP = Message_Function_SKIP;
- static const Function SETPROP = Message_Function_SETPROP;
- static inline bool Function_IsValid(int value) {
- return Message_Function_IsValid(value);
- }
- static const Function Function_MIN =
- Message_Function_Function_MIN;
- static const Function Function_MAX =
- Message_Function_Function_MAX;
- static const int Function_ARRAYSIZE =
- Message_Function_Function_ARRAYSIZE;
-
- typedef Message_Type Type;
- static const Type BeforeCall = Message_Type_BeforeCall;
- static const Type AfterCall = Message_Type_AfterCall;
- static const Type AfterGeneratedCall = Message_Type_AfterGeneratedCall;
- static const Type Response = Message_Type_Response;
- static const Type CompleteCall = Message_Type_CompleteCall;
- static inline bool Type_IsValid(int value) {
- return Message_Type_IsValid(value);
- }
- static const Type Type_MIN =
- Message_Type_Type_MIN;
- static const Type Type_MAX =
- Message_Type_Type_MAX;
- static const int Type_ARRAYSIZE =
- Message_Type_Type_ARRAYSIZE;
-
- typedef Message_DataType DataType;
- static const DataType ReferencedImage = Message_DataType_ReferencedImage;
- static const DataType NonreferencedImage = Message_DataType_NonreferencedImage;
- static inline bool DataType_IsValid(int value) {
- return Message_DataType_IsValid(value);
- }
- static const DataType DataType_MIN =
- Message_DataType_DataType_MIN;
- static const DataType DataType_MAX =
- Message_DataType_DataType_MAX;
- static const int DataType_ARRAYSIZE =
- Message_DataType_DataType_ARRAYSIZE;
-
- typedef Message_Prop Prop;
- static const Prop CaptureDraw = Message_Prop_CaptureDraw;
- static const Prop TimeMode = Message_Prop_TimeMode;
- static const Prop ExpectResponse = Message_Prop_ExpectResponse;
- static const Prop CaptureSwap = Message_Prop_CaptureSwap;
- static const Prop GLConstant = Message_Prop_GLConstant;
- static inline bool Prop_IsValid(int value) {
- return Message_Prop_IsValid(value);
- }
- static const Prop Prop_MIN =
- Message_Prop_Prop_MIN;
- static const Prop Prop_MAX =
- Message_Prop_Prop_MAX;
- static const int Prop_ARRAYSIZE =
- Message_Prop_Prop_ARRAYSIZE;
-
- // accessors -------------------------------------------------------
-
- // required int32 context_id = 1;
- inline bool has_context_id() const;
- inline void clear_context_id();
- static const int kContextIdFieldNumber = 1;
- inline ::google::protobuf::int32 context_id() const;
- inline void set_context_id(::google::protobuf::int32 value);
-
- // required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
- inline bool has_function() const;
- inline void clear_function();
- static const int kFunctionFieldNumber = 2;
- inline ::com::android::glesv2debugger::Message_Function function() const;
- inline void set_function(::com::android::glesv2debugger::Message_Function value);
-
- // required .com.android.glesv2debugger.Message.Type type = 3;
- inline bool has_type() const;
- inline void clear_type();
- static const int kTypeFieldNumber = 3;
- inline ::com::android::glesv2debugger::Message_Type type() const;
- inline void set_type(::com::android::glesv2debugger::Message_Type value);
-
- // required bool expect_response = 4;
- inline bool has_expect_response() const;
- inline void clear_expect_response();
- static const int kExpectResponseFieldNumber = 4;
- inline bool expect_response() const;
- inline void set_expect_response(bool value);
-
- // optional int32 ret = 5;
- inline bool has_ret() const;
- inline void clear_ret();
- static const int kRetFieldNumber = 5;
- inline ::google::protobuf::int32 ret() const;
- inline void set_ret(::google::protobuf::int32 value);
-
- // optional int32 arg0 = 6;
- inline bool has_arg0() const;
- inline void clear_arg0();
- static const int kArg0FieldNumber = 6;
- inline ::google::protobuf::int32 arg0() const;
- inline void set_arg0(::google::protobuf::int32 value);
-
- // optional int32 arg1 = 7;
- inline bool has_arg1() const;
- inline void clear_arg1();
- static const int kArg1FieldNumber = 7;
- inline ::google::protobuf::int32 arg1() const;
- inline void set_arg1(::google::protobuf::int32 value);
-
- // optional int32 arg2 = 8;
- inline bool has_arg2() const;
- inline void clear_arg2();
- static const int kArg2FieldNumber = 8;
- inline ::google::protobuf::int32 arg2() const;
- inline void set_arg2(::google::protobuf::int32 value);
-
- // optional int32 arg3 = 9;
- inline bool has_arg3() const;
- inline void clear_arg3();
- static const int kArg3FieldNumber = 9;
- inline ::google::protobuf::int32 arg3() const;
- inline void set_arg3(::google::protobuf::int32 value);
-
- // optional int32 arg4 = 16;
- inline bool has_arg4() const;
- inline void clear_arg4();
- static const int kArg4FieldNumber = 16;
- inline ::google::protobuf::int32 arg4() const;
- inline void set_arg4(::google::protobuf::int32 value);
-
- // optional int32 arg5 = 17;
- inline bool has_arg5() const;
- inline void clear_arg5();
- static const int kArg5FieldNumber = 17;
- inline ::google::protobuf::int32 arg5() const;
- inline void set_arg5(::google::protobuf::int32 value);
-
- // optional int32 arg6 = 18;
- inline bool has_arg6() const;
- inline void clear_arg6();
- static const int kArg6FieldNumber = 18;
- inline ::google::protobuf::int32 arg6() const;
- inline void set_arg6(::google::protobuf::int32 value);
-
- // optional int32 arg7 = 19;
- inline bool has_arg7() const;
- inline void clear_arg7();
- static const int kArg7FieldNumber = 19;
- inline ::google::protobuf::int32 arg7() const;
- inline void set_arg7(::google::protobuf::int32 value);
-
- // optional int32 arg8 = 20;
- inline bool has_arg8() const;
- inline void clear_arg8();
- static const int kArg8FieldNumber = 20;
- inline ::google::protobuf::int32 arg8() const;
- inline void set_arg8(::google::protobuf::int32 value);
-
- // optional bytes data = 10;
- inline bool has_data() const;
- inline void clear_data();
- static const int kDataFieldNumber = 10;
- inline const ::std::string& data() const;
- inline void set_data(const ::std::string& value);
- inline void set_data(const char* value);
- inline void set_data(const void* value, size_t size);
- inline ::std::string* mutable_data();
-
- // optional .com.android.glesv2debugger.Message.DataType data_type = 23;
- inline bool has_data_type() const;
- inline void clear_data_type();
- static const int kDataTypeFieldNumber = 23;
- inline ::com::android::glesv2debugger::Message_DataType data_type() const;
- inline void set_data_type(::com::android::glesv2debugger::Message_DataType value);
-
- // optional int32 pixel_format = 24;
- inline bool has_pixel_format() const;
- inline void clear_pixel_format();
- static const int kPixelFormatFieldNumber = 24;
- inline ::google::protobuf::int32 pixel_format() const;
- inline void set_pixel_format(::google::protobuf::int32 value);
-
- // optional int32 pixel_type = 25;
- inline bool has_pixel_type() const;
- inline void clear_pixel_type();
- static const int kPixelTypeFieldNumber = 25;
- inline ::google::protobuf::int32 pixel_type() const;
- inline void set_pixel_type(::google::protobuf::int32 value);
-
- // optional int32 image_width = 26;
- inline bool has_image_width() const;
- inline void clear_image_width();
- static const int kImageWidthFieldNumber = 26;
- inline ::google::protobuf::int32 image_width() const;
- inline void set_image_width(::google::protobuf::int32 value);
-
- // optional int32 image_height = 27;
- inline bool has_image_height() const;
- inline void clear_image_height();
- static const int kImageHeightFieldNumber = 27;
- inline ::google::protobuf::int32 image_height() const;
- inline void set_image_height(::google::protobuf::int32 value);
-
- // optional float time = 11;
- inline bool has_time() const;
- inline void clear_time();
- static const int kTimeFieldNumber = 11;
- inline float time() const;
- inline void set_time(float value);
-
- // optional .com.android.glesv2debugger.Message.Prop prop = 21;
- inline bool has_prop() const;
- inline void clear_prop();
- static const int kPropFieldNumber = 21;
- inline ::com::android::glesv2debugger::Message_Prop prop() const;
- inline void set_prop(::com::android::glesv2debugger::Message_Prop value);
-
- // optional float clock = 22;
- inline bool has_clock() const;
- inline void clear_clock();
- static const int kClockFieldNumber = 22;
- inline float clock() const;
- inline void set_clock(float value);
-
- // @@protoc_insertion_point(class_scope:com.android.glesv2debugger.Message)
- private:
- mutable int _cached_size_;
-
- ::google::protobuf::int32 context_id_;
- int function_;
- int type_;
- bool expect_response_;
- ::google::protobuf::int32 ret_;
- ::google::protobuf::int32 arg0_;
- ::google::protobuf::int32 arg1_;
- ::google::protobuf::int32 arg2_;
- ::google::protobuf::int32 arg3_;
- ::google::protobuf::int32 arg4_;
- ::google::protobuf::int32 arg5_;
- ::google::protobuf::int32 arg6_;
- ::google::protobuf::int32 arg7_;
- ::google::protobuf::int32 arg8_;
- ::std::string* data_;
- static const ::std::string _default_data_;
- int data_type_;
- ::google::protobuf::int32 pixel_format_;
- ::google::protobuf::int32 pixel_type_;
- ::google::protobuf::int32 image_width_;
- ::google::protobuf::int32 image_height_;
- float time_;
- int prop_;
- float clock_;
- friend void protobuf_AddDesc_debugger_5fmessage_2eproto();
- friend void protobuf_AssignDesc_debugger_5fmessage_2eproto();
- friend void protobuf_ShutdownFile_debugger_5fmessage_2eproto();
-
- ::google::protobuf::uint32 _has_bits_[(23 + 31) / 32];
-
- // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
- inline bool _has_bit(int index) const {
- return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
- }
- inline void _set_bit(int index) {
- _has_bits_[index / 32] |= (1u << (index % 32));
- }
- inline void _clear_bit(int index) {
- _has_bits_[index / 32] &= ~(1u << (index % 32));
- }
-
- void InitAsDefaultInstance();
- static Message* default_instance_;
-};
-// ===================================================================
-
-
-// ===================================================================
-
-// Message
-
-// required int32 context_id = 1;
-inline bool Message::has_context_id() const {
- return _has_bit(0);
-}
-inline void Message::clear_context_id() {
- context_id_ = 0;
- _clear_bit(0);
-}
-inline ::google::protobuf::int32 Message::context_id() const {
- return context_id_;
-}
-inline void Message::set_context_id(::google::protobuf::int32 value) {
- _set_bit(0);
- context_id_ = value;
-}
-
-// required .com.android.glesv2debugger.Message.Function function = 2 [default = NEG];
-inline bool Message::has_function() const {
- return _has_bit(1);
-}
-inline void Message::clear_function() {
- function_ = 187;
- _clear_bit(1);
-}
-inline ::com::android::glesv2debugger::Message_Function Message::function() const {
- return static_cast< ::com::android::glesv2debugger::Message_Function >(function_);
-}
-inline void Message::set_function(::com::android::glesv2debugger::Message_Function value) {
- GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Function_IsValid(value));
- _set_bit(1);
- function_ = value;
-}
-
-// required .com.android.glesv2debugger.Message.Type type = 3;
-inline bool Message::has_type() const {
- return _has_bit(2);
-}
-inline void Message::clear_type() {
- type_ = 0;
- _clear_bit(2);
-}
-inline ::com::android::glesv2debugger::Message_Type Message::type() const {
- return static_cast< ::com::android::glesv2debugger::Message_Type >(type_);
-}
-inline void Message::set_type(::com::android::glesv2debugger::Message_Type value) {
- GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Type_IsValid(value));
- _set_bit(2);
- type_ = value;
-}
-
-// required bool expect_response = 4;
-inline bool Message::has_expect_response() const {
- return _has_bit(3);
-}
-inline void Message::clear_expect_response() {
- expect_response_ = false;
- _clear_bit(3);
-}
-inline bool Message::expect_response() const {
- return expect_response_;
-}
-inline void Message::set_expect_response(bool value) {
- _set_bit(3);
- expect_response_ = value;
-}
-
-// optional int32 ret = 5;
-inline bool Message::has_ret() const {
- return _has_bit(4);
-}
-inline void Message::clear_ret() {
- ret_ = 0;
- _clear_bit(4);
-}
-inline ::google::protobuf::int32 Message::ret() const {
- return ret_;
-}
-inline void Message::set_ret(::google::protobuf::int32 value) {
- _set_bit(4);
- ret_ = value;
-}
-
-// optional int32 arg0 = 6;
-inline bool Message::has_arg0() const {
- return _has_bit(5);
-}
-inline void Message::clear_arg0() {
- arg0_ = 0;
- _clear_bit(5);
-}
-inline ::google::protobuf::int32 Message::arg0() const {
- return arg0_;
-}
-inline void Message::set_arg0(::google::protobuf::int32 value) {
- _set_bit(5);
- arg0_ = value;
-}
-
-// optional int32 arg1 = 7;
-inline bool Message::has_arg1() const {
- return _has_bit(6);
-}
-inline void Message::clear_arg1() {
- arg1_ = 0;
- _clear_bit(6);
-}
-inline ::google::protobuf::int32 Message::arg1() const {
- return arg1_;
-}
-inline void Message::set_arg1(::google::protobuf::int32 value) {
- _set_bit(6);
- arg1_ = value;
-}
-
-// optional int32 arg2 = 8;
-inline bool Message::has_arg2() const {
- return _has_bit(7);
-}
-inline void Message::clear_arg2() {
- arg2_ = 0;
- _clear_bit(7);
-}
-inline ::google::protobuf::int32 Message::arg2() const {
- return arg2_;
-}
-inline void Message::set_arg2(::google::protobuf::int32 value) {
- _set_bit(7);
- arg2_ = value;
-}
-
-// optional int32 arg3 = 9;
-inline bool Message::has_arg3() const {
- return _has_bit(8);
-}
-inline void Message::clear_arg3() {
- arg3_ = 0;
- _clear_bit(8);
-}
-inline ::google::protobuf::int32 Message::arg3() const {
- return arg3_;
-}
-inline void Message::set_arg3(::google::protobuf::int32 value) {
- _set_bit(8);
- arg3_ = value;
-}
-
-// optional int32 arg4 = 16;
-inline bool Message::has_arg4() const {
- return _has_bit(9);
-}
-inline void Message::clear_arg4() {
- arg4_ = 0;
- _clear_bit(9);
-}
-inline ::google::protobuf::int32 Message::arg4() const {
- return arg4_;
-}
-inline void Message::set_arg4(::google::protobuf::int32 value) {
- _set_bit(9);
- arg4_ = value;
-}
-
-// optional int32 arg5 = 17;
-inline bool Message::has_arg5() const {
- return _has_bit(10);
-}
-inline void Message::clear_arg5() {
- arg5_ = 0;
- _clear_bit(10);
-}
-inline ::google::protobuf::int32 Message::arg5() const {
- return arg5_;
-}
-inline void Message::set_arg5(::google::protobuf::int32 value) {
- _set_bit(10);
- arg5_ = value;
-}
-
-// optional int32 arg6 = 18;
-inline bool Message::has_arg6() const {
- return _has_bit(11);
-}
-inline void Message::clear_arg6() {
- arg6_ = 0;
- _clear_bit(11);
-}
-inline ::google::protobuf::int32 Message::arg6() const {
- return arg6_;
-}
-inline void Message::set_arg6(::google::protobuf::int32 value) {
- _set_bit(11);
- arg6_ = value;
-}
-
-// optional int32 arg7 = 19;
-inline bool Message::has_arg7() const {
- return _has_bit(12);
-}
-inline void Message::clear_arg7() {
- arg7_ = 0;
- _clear_bit(12);
-}
-inline ::google::protobuf::int32 Message::arg7() const {
- return arg7_;
-}
-inline void Message::set_arg7(::google::protobuf::int32 value) {
- _set_bit(12);
- arg7_ = value;
-}
-
-// optional int32 arg8 = 20;
-inline bool Message::has_arg8() const {
- return _has_bit(13);
-}
-inline void Message::clear_arg8() {
- arg8_ = 0;
- _clear_bit(13);
-}
-inline ::google::protobuf::int32 Message::arg8() const {
- return arg8_;
-}
-inline void Message::set_arg8(::google::protobuf::int32 value) {
- _set_bit(13);
- arg8_ = value;
-}
-
-// optional bytes data = 10;
-inline bool Message::has_data() const {
- return _has_bit(14);
-}
-inline void Message::clear_data() {
- if (data_ != &_default_data_) {
- data_->clear();
- }
- _clear_bit(14);
-}
-inline const ::std::string& Message::data() const {
- return *data_;
-}
-inline void Message::set_data(const ::std::string& value) {
- _set_bit(14);
- if (data_ == &_default_data_) {
- data_ = new ::std::string;
- }
- data_->assign(value);
-}
-inline void Message::set_data(const char* value) {
- _set_bit(14);
- if (data_ == &_default_data_) {
- data_ = new ::std::string;
- }
- data_->assign(value);
-}
-inline void Message::set_data(const void* value, size_t size) {
- _set_bit(14);
- if (data_ == &_default_data_) {
- data_ = new ::std::string;
- }
- data_->assign(reinterpret_cast<const char*>(value), size);
-}
-inline ::std::string* Message::mutable_data() {
- _set_bit(14);
- if (data_ == &_default_data_) {
- data_ = new ::std::string;
- }
- return data_;
-}
-
-// optional .com.android.glesv2debugger.Message.DataType data_type = 23;
-inline bool Message::has_data_type() const {
- return _has_bit(15);
-}
-inline void Message::clear_data_type() {
- data_type_ = 0;
- _clear_bit(15);
-}
-inline ::com::android::glesv2debugger::Message_DataType Message::data_type() const {
- return static_cast< ::com::android::glesv2debugger::Message_DataType >(data_type_);
-}
-inline void Message::set_data_type(::com::android::glesv2debugger::Message_DataType value) {
- GOOGLE_DCHECK(::com::android::glesv2debugger::Message_DataType_IsValid(value));
- _set_bit(15);
- data_type_ = value;
-}
-
-// optional int32 pixel_format = 24;
-inline bool Message::has_pixel_format() const {
- return _has_bit(16);
-}
-inline void Message::clear_pixel_format() {
- pixel_format_ = 0;
- _clear_bit(16);
-}
-inline ::google::protobuf::int32 Message::pixel_format() const {
- return pixel_format_;
-}
-inline void Message::set_pixel_format(::google::protobuf::int32 value) {
- _set_bit(16);
- pixel_format_ = value;
-}
-
-// optional int32 pixel_type = 25;
-inline bool Message::has_pixel_type() const {
- return _has_bit(17);
-}
-inline void Message::clear_pixel_type() {
- pixel_type_ = 0;
- _clear_bit(17);
-}
-inline ::google::protobuf::int32 Message::pixel_type() const {
- return pixel_type_;
-}
-inline void Message::set_pixel_type(::google::protobuf::int32 value) {
- _set_bit(17);
- pixel_type_ = value;
-}
-
-// optional int32 image_width = 26;
-inline bool Message::has_image_width() const {
- return _has_bit(18);
-}
-inline void Message::clear_image_width() {
- image_width_ = 0;
- _clear_bit(18);
-}
-inline ::google::protobuf::int32 Message::image_width() const {
- return image_width_;
-}
-inline void Message::set_image_width(::google::protobuf::int32 value) {
- _set_bit(18);
- image_width_ = value;
-}
-
-// optional int32 image_height = 27;
-inline bool Message::has_image_height() const {
- return _has_bit(19);
-}
-inline void Message::clear_image_height() {
- image_height_ = 0;
- _clear_bit(19);
-}
-inline ::google::protobuf::int32 Message::image_height() const {
- return image_height_;
-}
-inline void Message::set_image_height(::google::protobuf::int32 value) {
- _set_bit(19);
- image_height_ = value;
-}
-
-// optional float time = 11;
-inline bool Message::has_time() const {
- return _has_bit(20);
-}
-inline void Message::clear_time() {
- time_ = 0;
- _clear_bit(20);
-}
-inline float Message::time() const {
- return time_;
-}
-inline void Message::set_time(float value) {
- _set_bit(20);
- time_ = value;
-}
-
-// optional .com.android.glesv2debugger.Message.Prop prop = 21;
-inline bool Message::has_prop() const {
- return _has_bit(21);
-}
-inline void Message::clear_prop() {
- prop_ = 0;
- _clear_bit(21);
-}
-inline ::com::android::glesv2debugger::Message_Prop Message::prop() const {
- return static_cast< ::com::android::glesv2debugger::Message_Prop >(prop_);
-}
-inline void Message::set_prop(::com::android::glesv2debugger::Message_Prop value) {
- GOOGLE_DCHECK(::com::android::glesv2debugger::Message_Prop_IsValid(value));
- _set_bit(21);
- prop_ = value;
-}
-
-// optional float clock = 22;
-inline bool Message::has_clock() const {
- return _has_bit(22);
-}
-inline void Message::clear_clock() {
- clock_ = 0;
- _clear_bit(22);
-}
-inline float Message::clock() const {
- return clock_;
-}
-inline void Message::set_clock(float value) {
- _set_bit(22);
- clock_ = value;
-}
-
-
-// @@protoc_insertion_point(namespace_scope)
-
-} // namespace glesv2debugger
-} // namespace android
-} // namespace com
-
-// @@protoc_insertion_point(global_scope)
-
-#endif // PROTOBUF_debugger_5fmessage_2eproto__INCLUDED
diff --git a/opengl/libs/GLES2_dbg/src/egl.cpp b/opengl/libs/GLES2_dbg/src/egl.cpp
deleted file mode 100644
index bbea3bd5572a..000000000000
--- a/opengl/libs/GLES2_dbg/src/egl.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include "header.h"
-
-EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
-{
- DbgContext * const dbg = getDbgContextThreadSpecific();
- glesv2debugger::Message msg;
- struct : public FunctionCall {
- EGLDisplay dpy;
- EGLSurface draw;
-
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- msg.set_time(-1);
- return reinterpret_cast<const int *>(true);
- }
- } caller;
- caller.dpy = dpy;
- caller.draw = draw;
-
- msg.set_arg0(reinterpret_cast<int>(dpy));
- msg.set_arg1(reinterpret_cast<int>(draw));
- if (dbg->captureSwap > 0) {
- dbg->captureSwap--;
- int viewport[4] = {};
- dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
- void * pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
- dbg->readBytesPerPixel);
- dbg->hooks->gl.glReadPixels(viewport[0], viewport[1], viewport[2],
- viewport[3], GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- dbg->CompressReadPixelBuffer(msg.mutable_data());
- msg.set_data_type(msg.ReferencedImage);
- msg.set_pixel_format(GL_RGBA);
- msg.set_pixel_type(GL_UNSIGNED_BYTE);
- msg.set_image_width(viewport[2]);
- msg.set_image_height(viewport[3]);
- }
- int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_eglSwapBuffers);
- return static_cast<EGLBoolean>(reinterpret_cast<int>(ret));
-}
diff --git a/opengl/libs/GLES2_dbg/src/header.h b/opengl/libs/GLES2_dbg/src/header.h
deleted file mode 100644
index 0ab48902b27c..000000000000
--- a/opengl/libs/GLES2_dbg/src/header.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#ifndef ANDROID_GLES2_DBG_HEADER_H
-#define ANDROID_GLES2_DBG_HEADER_H
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <cutils/log.h>
-#include <utils/Timers.h>
-
-#include "hooks.h"
-
-#include "glesv2dbg.h"
-
-#define GL_ENTRY(_r, _api, ...) _r Debug_##_api ( __VA_ARGS__ );
-#include "glesv2dbg_functions.h"
-
-#include "debugger_message.pb.h"
-
-using namespace android;
-using namespace com::android;
-
-#ifndef __location__
-#define __HIERALLOC_STRING_0__(s) #s
-#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
-#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
-#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
-#endif
-
-#undef assert
-#define assert(expr) if (!(expr)) { ALOGD("\n*\n*\n* assert: %s at %s \n*\n*", #expr, __location__); int * x = 0; *x = 5; }
-//#undef ALOGD
-//#define ALOGD(...)
-
-namespace android
-{
-
-struct GLFunctionBitfield {
- unsigned char field [24]; // 8 * 24 = 192
-
- void Bit(const glesv2debugger::Message_Function function, bool bit) {
- const unsigned byte = function / 8, mask = 1 << (function % 8);
- if (bit)
- field[byte] |= mask;
- else
- field[byte] &= ~mask;
- }
-
- bool Bit(const glesv2debugger::Message_Function function) const {
- const unsigned byte = function / 8, mask = 1 << (function % 8);
- return field[byte] & mask;
- }
-};
-
-struct DbgContext {
- static const unsigned int LZF_CHUNK_SIZE = 256 * 1024;
-
-private:
- char * lzf_buf; // malloc / free; for lzf chunk compression and other uses
-
- // used as buffer and reference frame for ReadPixels; malloc/free
- unsigned * lzf_ref [2];
- unsigned lzf_readIndex; // 0 or 1
- unsigned lzf_refSize, lzf_refBufSize; // bytes
-
-public:
- const unsigned int version; // 0 is GLES1, 1 is GLES2
- const gl_hooks_t * const hooks;
- const unsigned int MAX_VERTEX_ATTRIBS;
- const unsigned int readBytesPerPixel;
-
- unsigned int captureSwap; // number of eglSwapBuffers to glReadPixels
- unsigned int captureDraw; // number of glDrawArrays/Elements to glReadPixels
-
- GLFunctionBitfield expectResponse;
-
- struct VertexAttrib {
- GLenum type; // element data type
- unsigned size; // number of data per element
- unsigned stride; // calculated number of bytes between elements
- const void * ptr;
- unsigned elemSize; // calculated number of bytes per element
- GLuint buffer; // buffer name
- GLboolean normalized : 1;
- GLboolean enabled : 1;
- VertexAttrib() : type(0), size(0), stride(0), ptr(NULL), elemSize(0),
- buffer(0), normalized(0), enabled(0) {}
- } * vertexAttribs;
- bool hasNonVBOAttribs; // whether any enabled vertexAttrib is user pointer
-
- struct VBO {
- const GLuint name;
- const GLenum target;
- VBO * next;
- void * data; // malloc/free
- unsigned size; // in bytes
- VBO(const GLuint name, const GLenum target, VBO * head) : name(name),
- target(target), next(head), data(NULL), size(0) {}
- } * indexBuffers; // linked list of all index buffers
- VBO * indexBuffer; // currently bound index buffer
-
- GLuint program;
- unsigned maxAttrib; // number of slots used by program
-
- DbgContext(const unsigned version, const gl_hooks_t * const hooks,
- const unsigned MAX_VERTEX_ATTRIBS);
- ~DbgContext();
-
- void Fetch(const unsigned index, std::string * const data) const;
- void Compress(const void * in_data, unsigned in_len, std::string * const outStr);
- static unsigned char * Decompress(const void * in, const unsigned int inLen,
- unsigned int * const outLen); // malloc/free
- void * GetReadPixelsBuffer(const unsigned size);
- bool IsReadPixelBuffer(const void * const ptr) {
- return ptr == lzf_ref[lzf_readIndex];
- }
- void CompressReadPixelBuffer(std::string * const outStr);
- char * GetBuffer(); // allocates lzf_buf if NULL
- unsigned int GetBufferSize(); // allocates lzf_buf if NULL
-
- void glUseProgram(GLuint program);
- void glEnableVertexAttribArray(GLuint index);
- void glDisableVertexAttribArray(GLuint index);
- void glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
- GLboolean normalized, GLsizei stride, const GLvoid* ptr);
- void glBindBuffer(GLenum target, GLuint buffer);
- void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
- void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
- void glDeleteBuffers(GLsizei n, const GLuint *buffers);
-};
-
-DbgContext * getDbgContextThreadSpecific();
-
-struct FunctionCall {
- virtual const int * operator()(gl_hooks_t::gl_t const * const _c,
- glesv2debugger::Message & msg) = 0;
- virtual ~FunctionCall() {}
-};
-
-// move these into DbgContext as static
-extern int timeMode; // SYSTEM_TIME_
-
-extern int clientSock, serverSock;
-
-unsigned GetBytesPerPixel(const GLenum format, const GLenum type);
-
-// every Debug_gl* function calls this to send message to client and possibly receive commands
-int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
- const glesv2debugger::Message_Function function);
-
-void Receive(glesv2debugger::Message & cmd);
-float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
-void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd);
-const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
- glesv2debugger::Message & msg, const int * const prevRet);
-}; // namespace android {
-
-#endif // #ifndef ANDROID_GLES2_DBG_HEADER_H
diff --git a/opengl/libs/GLES2_dbg/src/server.cpp b/opengl/libs/GLES2_dbg/src/server.cpp
deleted file mode 100644
index 3e9369707422..000000000000
--- a/opengl/libs/GLES2_dbg/src/server.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <pthread.h>
-
-#include "header.h"
-
-namespace android
-{
-
-int serverSock = -1, clientSock = -1;
-FILE * file = NULL;
-unsigned int MAX_FILE_SIZE = 0;
-int timeMode = SYSTEM_TIME_THREAD;
-
-static void Die(const char * msg)
-{
- ALOGD("\n*\n*\n* GLESv2_dbg: Die: %s \n*\n*", msg);
- StopDebugServer();
- exit(1);
-}
-
-void StartDebugServer(const unsigned short port, const bool forceUseFile,
- const unsigned int maxFileSize, const char * const filePath)
-{
- MAX_FILE_SIZE = maxFileSize;
-
- ALOGD("GLESv2_dbg: StartDebugServer");
- if (serverSock >= 0 || file)
- return;
-
- ALOGD("GLESv2_dbg: StartDebugServer create socket");
- struct sockaddr_in server = {}, client = {};
-
- /* Create the TCP socket */
- if (forceUseFile || (serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- file = fopen(filePath, "wb");
- if (!file)
- Die("Failed to create socket and file");
- else
- return;
- }
- /* Construct the server sockaddr_in structure */
- server.sin_family = AF_INET; /* Internet/IP */
- server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Incoming addr */
- server.sin_port = htons(port); /* server port */
-
- /* Bind the server socket */
- socklen_t sizeofSockaddr_in = sizeof(sockaddr_in);
- if (bind(serverSock, (struct sockaddr *) &server,
- sizeof(server)) < 0) {
- Die("Failed to bind the server socket");
- }
- /* Listen on the server socket */
- if (listen(serverSock, 1) < 0) {
- Die("Failed to listen on server socket");
- }
-
- ALOGD("server started on %d \n", server.sin_port);
-
-
- /* Wait for client connection */
- if ((clientSock =
- accept(serverSock, (struct sockaddr *) &client,
- &sizeofSockaddr_in)) < 0) {
- Die("Failed to accept client connection");
- }
-
- ALOGD("Client connected: %s\n", inet_ntoa(client.sin_addr));
-// fcntl(clientSock, F_SETFL, O_NONBLOCK);
-}
-
-void StopDebugServer()
-{
- ALOGD("GLESv2_dbg: StopDebugServer");
- if (clientSock > 0) {
- close(clientSock);
- clientSock = -1;
- }
- if (serverSock > 0) {
- close(serverSock);
- serverSock = -1;
- }
- if (file) {
- fclose(file);
- file = NULL;
- }
-}
-
-void Receive(glesv2debugger::Message & cmd)
-{
- if (clientSock < 0)
- return;
- unsigned len = 0;
- int received = recv(clientSock, &len, 4, MSG_WAITALL);
- if (received < 0)
- Die("Failed to receive response length");
- else if (4 != received) {
- ALOGD("received %dB: %.8X", received, len);
- Die("Received length mismatch, expected 4");
- }
- static void * buffer = NULL;
- static unsigned bufferSize = 0;
- if (bufferSize < len) {
- buffer = realloc(buffer, len);
- assert(buffer);
- bufferSize = len;
- }
- received = recv(clientSock, buffer, len, MSG_WAITALL);
- if (received < 0)
- Die("Failed to receive response");
- else if (len != received)
- Die("Received length mismatch");
- cmd.Clear();
- cmd.ParseFromArray(buffer, len);
-}
-
-bool TryReceive(glesv2debugger::Message & cmd)
-{
- if (clientSock < 0)
- return false;
- fd_set readSet;
- FD_ZERO(&readSet);
- FD_SET(clientSock, &readSet);
- timeval timeout;
- timeout.tv_sec = timeout.tv_usec = 0;
-
- int rc = select(clientSock + 1, &readSet, NULL, NULL, &timeout);
- if (rc < 0)
- Die("failed to select clientSock");
-
- bool received = false;
- if (FD_ISSET(clientSock, &readSet)) {
- ALOGD("TryReceive: avaiable for read");
- Receive(cmd);
- return true;
- }
- return false;
-}
-
-float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
-{
- // TODO: use per DbgContext send/receive buffer and async socket
- // instead of mutex and blocking io; watch out for large messages
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- struct Autolock {
- Autolock() {
- pthread_mutex_lock(&mutex);
- }
- ~Autolock() {
- pthread_mutex_unlock(&mutex);
- }
- } autolock;
-
- if (msg.function() != glesv2debugger::Message_Function_ACK)
- assert(msg.has_context_id() && msg.context_id() != 0);
- static std::string str;
- msg.SerializeToString(&str);
- const uint32_t len = str.length();
- if (clientSock < 0) {
- if (file) {
- fwrite(&len, sizeof(len), 1, file);
- fwrite(str.data(), len, 1, file);
- if (ftell(file) >= MAX_FILE_SIZE) {
- fclose(file);
- Die("MAX_FILE_SIZE reached");
- }
- }
- return 0;
- }
- int sent = -1;
- sent = send(clientSock, &len, sizeof(len), 0);
- if (sent != sizeof(len)) {
- ALOGD("actual sent=%d expected=%d clientSock=%d", sent, sizeof(len), clientSock);
- Die("Failed to send message length");
- }
- nsecs_t c0 = systemTime(timeMode);
- sent = send(clientSock, str.data(), str.length(), 0);
- float t = (float)ns2ms(systemTime(timeMode) - c0);
- if (sent != str.length()) {
- ALOGD("actual sent=%d expected=%d clientSock=%d", sent, str.length(), clientSock);
- Die("Failed to send message");
- }
- // TODO: factor Receive & TryReceive out and into MessageLoop, or add control argument.
- // mean while, if server is sending a SETPROP then don't try to receive,
- // because server will not be processing received command
- if (msg.function() == msg.SETPROP)
- return t;
- // try to receive commands even though not expecting response,
- // since client can send SETPROP and other commands anytime
- if (!msg.expect_response()) {
- if (TryReceive(cmd)) {
- if (glesv2debugger::Message_Function_SETPROP == cmd.function())
- ALOGD("Send: TryReceived SETPROP");
- else
- ALOGD("Send: TryReceived %u", cmd.function());
- }
- } else
- Receive(cmd);
- return t;
-}
-
-void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd)
-{
- switch (cmd.prop()) {
- case glesv2debugger::Message_Prop_CaptureDraw:
- ALOGD("SetProp Message_Prop_CaptureDraw %d", cmd.arg0());
- dbg->captureDraw = cmd.arg0();
- break;
- case glesv2debugger::Message_Prop_TimeMode:
- ALOGD("SetProp Message_Prop_TimeMode %d", cmd.arg0());
- timeMode = cmd.arg0();
- break;
- case glesv2debugger::Message_Prop_ExpectResponse:
- ALOGD("SetProp Message_Prop_ExpectResponse %d=%d", cmd.arg0(), cmd.arg1());
- dbg->expectResponse.Bit((glesv2debugger::Message_Function)cmd.arg0(), cmd.arg1());
- break;
- case glesv2debugger::Message_Prop_CaptureSwap:
- ALOGD("SetProp CaptureSwap %d", cmd.arg0());
- dbg->captureSwap = cmd.arg0();
- break;
- default:
- assert(0);
- }
-}
-
-int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
- const glesv2debugger::Message_Function function)
-{
- DbgContext * const dbg = getDbgContextThreadSpecific();
- const int * ret = 0;
- glesv2debugger::Message cmd;
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_type(glesv2debugger::Message_Type_BeforeCall);
- bool expectResponse = dbg->expectResponse.Bit(function);
- msg.set_expect_response(expectResponse);
- msg.set_function(function);
-
- // when not exectResponse, set cmd to CONTINUE then SKIP
- // cmd will be overwritten by received command
- cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
- cmd.set_expect_response(expectResponse);
- glesv2debugger::Message_Function oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- while (true) {
- msg.Clear();
- nsecs_t c0 = systemTime(timeMode);
- switch (cmd.function()) {
- case glesv2debugger::Message_Function_CONTINUE:
- ret = functionCall(&dbg->hooks->gl, msg);
- while (GLenum error = dbg->hooks->gl.glGetError())
- ALOGD("Function=%u glGetError() = 0x%.4X", function, error);
- if (!msg.has_time()) // some has output data copy, so time inside call
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_function(function);
- msg.set_type(glesv2debugger::Message_Type_AfterCall);
- msg.set_expect_response(expectResponse);
- if (!expectResponse) {
- cmd.set_function(glesv2debugger::Message_Function_SKIP);
- cmd.set_expect_response(false);
- }
- oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- break;
- case glesv2debugger::Message_Function_SKIP:
- return const_cast<int *>(ret);
- case glesv2debugger::Message_Function_SETPROP:
- SetProp(dbg, cmd);
- expectResponse = cmd.expect_response();
- if (!expectResponse) // SETPROP is "out of band"
- cmd.set_function(oldCmd);
- else
- Receive(cmd);
- break;
- default:
- ret = GenerateCall(dbg, cmd, msg, ret);
- msg.set_expect_response(expectResponse);
- if (!expectResponse) {
- cmd.set_function(cmd.SKIP);
- cmd.set_expect_response(expectResponse);
- }
- oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- break;
- }
- }
- return 0;
-}
-}; // namespace android {
diff --git a/opengl/libs/GLES2_dbg/src/vertex.cpp b/opengl/libs/GLES2_dbg/src/vertex.cpp
deleted file mode 100644
index 70c34333db96..000000000000
--- a/opengl/libs/GLES2_dbg/src/vertex.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include "header.h"
-
-namespace android
-{
-bool capture; // capture after each glDraw*
-}
-
-void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
-{
- DbgContext * const dbg = getDbgContextThreadSpecific();
- glesv2debugger::Message msg, cmd;
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_type(glesv2debugger::Message_Type_BeforeCall);
- bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawArrays);
- msg.set_expect_response(expectResponse);
- msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
- msg.set_arg0(mode);
- msg.set_arg1(first);
- msg.set_arg2(count);
-
- msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
- if (dbg->hasNonVBOAttribs) {
- std::string * const data = msg.mutable_data();
- for (unsigned i = 0; i < count; i++)
- dbg->Fetch(i + first, data);
- }
-
- void * pixels = NULL;
- int viewport[4] = {};
- cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
- cmd.set_expect_response(expectResponse);
- glesv2debugger::Message_Function oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- while (true) {
- msg.Clear();
- nsecs_t c0 = systemTime(timeMode);
- switch (cmd.function()) {
- case glesv2debugger::Message_Function_CONTINUE:
- dbg->hooks->gl.glDrawArrays(mode, first, count);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
- msg.set_type(glesv2debugger::Message_Type_AfterCall);
- msg.set_expect_response(expectResponse);
- if (!expectResponse) {
- cmd.set_function(glesv2debugger::Message_Function_SKIP);
- cmd.set_expect_response(false);
- }
- oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- // TODO: pack glReadPixels data with vertex data instead of
- // relying on sperate call for transport, this would allow
- // auto generated message loop using EXTEND_Debug macro
- if (dbg->captureDraw > 0) {
- dbg->captureDraw--;
- dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
-// ALOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
-// viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
- pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
- dbg->readBytesPerPixel);
- Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
- GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- }
- break;
- case glesv2debugger::Message_Function_SKIP:
- return;
- case glesv2debugger::Message_Function_SETPROP:
- SetProp(dbg, cmd);
- expectResponse = cmd.expect_response();
- if (!expectResponse) // SETPROP is "out of band"
- cmd.set_function(oldCmd);
- else
- Receive(cmd);
- break;
- default:
- GenerateCall(dbg, cmd, msg, NULL);
- msg.set_expect_response(expectResponse);
- if (!expectResponse) {
- cmd.set_function(cmd.SKIP);
- cmd.set_expect_response(expectResponse);
- }
- oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- break;
- }
- }
-}
-
-template<typename T>
-static inline void FetchIndexed(const unsigned count, const T * indices,
- std::string * const data, const DbgContext * const ctx)
-{
- for (unsigned i = 0; i < count; i++) {
- if (!ctx->indexBuffer)
- data->append((const char *)(indices + i), sizeof(*indices));
- if (ctx->hasNonVBOAttribs)
- ctx->Fetch(indices[i], data);
- }
-}
-
-void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
-{
- DbgContext * const dbg = getDbgContextThreadSpecific();
- glesv2debugger::Message msg, cmd;
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_type(glesv2debugger::Message_Type_BeforeCall);
- bool expectResponse = dbg->expectResponse.Bit(glesv2debugger::Message_Function_glDrawElements);
- msg.set_expect_response(expectResponse);
- msg.set_function(glesv2debugger::Message_Function_glDrawElements);
- msg.set_arg0(mode);
- msg.set_arg1(count);
- msg.set_arg2(type);
- msg.set_arg3(reinterpret_cast<int>(indices));
-
- msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
- std::string * const data = msg.mutable_data();
- if (GL_UNSIGNED_BYTE == type) {
- if (dbg->indexBuffer) {
- FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
- (unsigned long)indices, data, dbg);
- } else {
- FetchIndexed(count, (unsigned char *)indices, data, dbg);
- }
- } else if (GL_UNSIGNED_SHORT == type) {
- if (dbg->indexBuffer) {
- FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
- (unsigned long)indices), data, dbg);
- } else {
- FetchIndexed(count, (unsigned short *)indices, data, dbg);
- }
- } else {
- assert(0);
- }
-
- void * pixels = NULL;
- int viewport[4] = {};
- cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
- cmd.set_expect_response(expectResponse);
- glesv2debugger::Message_Function oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- while (true) {
- msg.Clear();
- nsecs_t c0 = systemTime(timeMode);
- switch (cmd.function()) {
- case glesv2debugger::Message_Function_CONTINUE:
- dbg->hooks->gl.glDrawElements(mode, count, type, indices);
- msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
- msg.set_context_id(reinterpret_cast<int>(dbg));
- msg.set_function(glesv2debugger::Message_Function_glDrawElements);
- msg.set_type(glesv2debugger::Message_Type_AfterCall);
- msg.set_expect_response(expectResponse);
- if (!expectResponse) {
- cmd.set_function(glesv2debugger::Message_Function_SKIP);
- cmd.set_expect_response(false);
- }
- oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- // TODO: pack glReadPixels data with vertex data instead of
- // relying on separate call for transport, this would allow
- // auto generated message loop using EXTEND_Debug macro
- if (dbg->captureDraw > 0) {
- dbg->captureDraw--;
- dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
- pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
- dbg->readBytesPerPixel);
- Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
- GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- }
- break;
- case glesv2debugger::Message_Function_SKIP:
- return;
- case glesv2debugger::Message_Function_SETPROP:
- SetProp(dbg, cmd);
- expectResponse = cmd.expect_response();
- if (!expectResponse) // SETPROP is "out of band"
- cmd.set_function(oldCmd);
- else
- Receive(cmd);
- break;
- default:
- GenerateCall(dbg, cmd, msg, NULL);
- msg.set_expect_response(expectResponse);
- if (!expectResponse) {
- cmd.set_function(cmd.SKIP);
- cmd.set_expect_response(expectResponse);
- }
- oldCmd = cmd.function();
- Send(msg, cmd);
- expectResponse = cmd.expect_response();
- break;
- }
- }
-}
diff --git a/opengl/libs/GLES2_dbg/test/Android.mk b/opengl/libs/GLES2_dbg/test/Android.mk
deleted file mode 100644
index 8708d439dfbd..000000000000
--- a/opengl/libs/GLES2_dbg/test/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH) \
- $(LOCAL_PATH)/../src \
- $(LOCAL_PATH)/../../ \
- external/gtest/include \
- external/stlport/stlport \
- external/protobuf/src \
- bionic \
- external \
-#
-
-LOCAL_SRC_FILES:= \
- test_main.cpp \
- test_server.cpp \
- test_socket.cpp \
-#
-
-LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2_dbg libstlport
-LOCAL_STATIC_LIBRARIES := libgtest libprotobuf-cpp-2.3.0-lite liblzf
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE:= libGLESv2_dbg_test
-
-ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
- LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
-endif
-LOCAL_C_INCLUDES += bionic/libc/private
-
-LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\"
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-LOCAL_CFLAGS += -fvisibility=hidden
-
-include $(BUILD_EXECUTABLE)
-
diff --git a/opengl/libs/GLES2_dbg/test/test_main.cpp b/opengl/libs/GLES2_dbg/test/test_main.cpp
deleted file mode 100644
index 183bf8ecb760..000000000000
--- a/opengl/libs/GLES2_dbg/test/test_main.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include "header.h"
-#include "gtest/gtest.h"
-#include "hooks.h"
-
-namespace
-{
-
-// The fixture for testing class Foo.
-class DbgContextTest : public ::testing::Test
-{
-protected:
- android::DbgContext dbg;
- gl_hooks_t hooks;
-
- DbgContextTest()
- : dbg(1, &hooks, 32) {
- // You can do set-up work for each test here.
- hooks.gl.glGetError = GetError;
- }
-
- static GLenum GetError() {
- return GL_NO_ERROR;
- }
-
- virtual ~DbgContextTest() {
- // You can do clean-up work that doesn't throw exceptions here.
- }
-
- // If the constructor and destructor are not enough for setting up
- // and cleaning up each test, you can define the following methods:
-
- virtual void SetUp() {
- // Code here will be called immediately after the constructor (right
- // before each test).
- }
-
- virtual void TearDown() {
- // Code here will be called immediately after each test (right
- // before the destructor).
- }
-};
-
-TEST_F(DbgContextTest, GetReadPixelBuffer)
-{
- const unsigned int bufferSize = 512;
- // test that it's allocating two buffers and swapping them
- void * const buffer0 = dbg.GetReadPixelsBuffer(bufferSize);
- ASSERT_NE((void *)NULL, buffer0);
- for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++) {
- EXPECT_EQ(0, ((unsigned int *)buffer0)[i])
- << "GetReadPixelsBuffer should allocate and zero";
- ((unsigned int *)buffer0)[i] = i * 13;
- }
-
- void * const buffer1 = dbg.GetReadPixelsBuffer(bufferSize);
- ASSERT_NE((void *)NULL, buffer1);
- EXPECT_NE(buffer0, buffer1);
- for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++) {
- EXPECT_EQ(0, ((unsigned int *)buffer1)[i])
- << "GetReadPixelsBuffer should allocate and zero";
- ((unsigned int *)buffer1)[i] = i * 17;
- }
-
- void * const buffer2 = dbg.GetReadPixelsBuffer(bufferSize);
- EXPECT_EQ(buffer2, buffer0);
- for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++)
- EXPECT_EQ(i * 13, ((unsigned int *)buffer2)[i])
- << "GetReadPixelsBuffer should swap buffers";
-
- void * const buffer3 = dbg.GetReadPixelsBuffer(bufferSize);
- EXPECT_EQ(buffer3, buffer1);
- for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++)
- EXPECT_EQ(i * 17, ((unsigned int *)buffer3)[i])
- << "GetReadPixelsBuffer should swap buffers";
-
- void * const buffer4 = dbg.GetReadPixelsBuffer(bufferSize);
- EXPECT_NE(buffer3, buffer4);
- EXPECT_EQ(buffer0, buffer2);
- EXPECT_EQ(buffer1, buffer3);
- EXPECT_EQ(buffer2, buffer4);
-
- // it reallocs as necessary; 0 size may result in NULL
- for (unsigned int i = 0; i < 42; i++) {
- void * const buffer = dbg.GetReadPixelsBuffer(((i & 7)) << 20);
- EXPECT_NE((void *)NULL, buffer)
- << "should be able to get a variety of reasonable sizes";
- EXPECT_TRUE(dbg.IsReadPixelBuffer(buffer));
- }
-}
-
-TEST_F(DbgContextTest, CompressReadPixelBuffer)
-{
- const unsigned int bufferSize = dbg.LZF_CHUNK_SIZE * 4 + 33;
- std::string out;
- unsigned char * buffer = (unsigned char *)dbg.GetReadPixelsBuffer(bufferSize);
- for (unsigned int i = 0; i < bufferSize; i++)
- buffer[i] = i * 13;
- dbg.CompressReadPixelBuffer(&out);
- uint32_t decompSize = 0;
- ASSERT_LT(12, out.length()); // at least written chunk header
- ASSERT_EQ(bufferSize, *(uint32_t *)out.data())
- << "total decompressed size should be as requested in GetReadPixelsBuffer";
- for (unsigned int i = 4; i < out.length();) {
- const uint32_t outSize = *(uint32_t *)(out.data() + i);
- i += 4;
- const uint32_t inSize = *(uint32_t *)(out.data() + i);
- i += 4;
- if (inSize == 0)
- i += outSize; // chunk not compressed
- else
- i += inSize; // skip the actual compressed chunk
- decompSize += outSize;
- }
- ASSERT_EQ(bufferSize, decompSize);
- decompSize = 0;
-
- unsigned char * decomp = dbg.Decompress(out.data(), out.length(), &decompSize);
- ASSERT_EQ(decompSize, bufferSize);
- for (unsigned int i = 0; i < bufferSize; i++)
- EXPECT_EQ((unsigned char)(i * 13), decomp[i]) << "xor with 0 ref is identity";
- free(decomp);
-
- buffer = (unsigned char *)dbg.GetReadPixelsBuffer(bufferSize);
- for (unsigned int i = 0; i < bufferSize; i++)
- buffer[i] = i * 13;
- out.clear();
- dbg.CompressReadPixelBuffer(&out);
- decompSize = 0;
- decomp = dbg.Decompress(out.data(), out.length(), &decompSize);
- ASSERT_EQ(decompSize, bufferSize);
- for (unsigned int i = 0; i < bufferSize; i++)
- EXPECT_EQ(0, decomp[i]) << "xor with same ref is 0";
- free(decomp);
-
- buffer = (unsigned char *)dbg.GetReadPixelsBuffer(bufferSize);
- for (unsigned int i = 0; i < bufferSize; i++)
- buffer[i] = i * 19;
- out.clear();
- dbg.CompressReadPixelBuffer(&out);
- decompSize = 0;
- decomp = dbg.Decompress(out.data(), out.length(), &decompSize);
- ASSERT_EQ(decompSize, bufferSize);
- for (unsigned int i = 0; i < bufferSize; i++)
- EXPECT_EQ((unsigned char)(i * 13) ^ (unsigned char)(i * 19), decomp[i])
- << "xor ref";
- free(decomp);
-}
-
-TEST_F(DbgContextTest, UseProgram)
-{
- static const GLuint _program = 74568;
- static const struct Attribute {
- const char * name;
- GLint location;
- GLint size;
- GLenum type;
- } _attributes [] = {
- {"aaa", 2, 2, GL_FLOAT_VEC2},
- {"bb", 6, 2, GL_FLOAT_MAT2},
- {"c", 1, 1, GL_FLOAT},
- };
- static const unsigned int _attributeCount = sizeof(_attributes) / sizeof(*_attributes);
- struct GL {
- static void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
- EXPECT_EQ(_program, program);
- ASSERT_NE((GLint *)NULL, params);
- switch (pname) {
- case GL_ACTIVE_ATTRIBUTES:
- *params = _attributeCount;
- return;
- case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
- *params = 4; // includes NULL terminator
- return;
- default:
- ADD_FAILURE() << "not handled pname: " << pname;
- }
- }
-
- static GLint GetAttribLocation(GLuint program, const GLchar* name) {
- EXPECT_EQ(_program, program);
- for (unsigned int i = 0; i < _attributeCount; i++)
- if (!strcmp(name, _attributes[i].name))
- return _attributes[i].location;
- ADD_FAILURE() << "unknown attribute name: " << name;
- return -1;
- }
-
- static void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
- GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
- EXPECT_EQ(_program, program);
- ASSERT_LT(index, _attributeCount);
- const Attribute & att = _attributes[index];
- ASSERT_GE(bufsize, strlen(att.name) + 1);
- ASSERT_NE((GLint *)NULL, size);
- ASSERT_NE((GLenum *)NULL, type);
- ASSERT_NE((GLchar *)NULL, name);
- strcpy(name, att.name);
- if (length)
- *length = strlen(name) + 1;
- *size = att.size;
- *type = att.type;
- }
- };
- hooks.gl.glGetProgramiv = GL::GetProgramiv;
- hooks.gl.glGetAttribLocation = GL::GetAttribLocation;
- hooks.gl.glGetActiveAttrib = GL::GetActiveAttrib;
- dbg.glUseProgram(_program);
- EXPECT_EQ(10, dbg.maxAttrib);
- dbg.glUseProgram(0);
- EXPECT_EQ(0, dbg.maxAttrib);
-}
-} // namespace
-
-int main(int argc, char **argv)
-{
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/opengl/libs/GLES2_dbg/test/test_server.cpp b/opengl/libs/GLES2_dbg/test/test_server.cpp
deleted file mode 100644
index 0ab87b08ef0b..000000000000
--- a/opengl/libs/GLES2_dbg/test/test_server.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include "header.h"
-#include "gtest/gtest.h"
-#include "hooks.h"
-
-namespace android
-{
-extern FILE * file;
-extern unsigned int MAX_FILE_SIZE;
-};
-
-// tmpfile fails, so need to manually make a writable file first
-static const char * filePath = "/data/local/tmp/dump.gles2dbg";
-
-class ServerFileTest : public ::testing::Test
-{
-protected:
- ServerFileTest() { }
-
- virtual ~ServerFileTest() { }
-
- virtual void SetUp() {
- MAX_FILE_SIZE = 8 << 20;
- ASSERT_EQ((FILE *)NULL, file);
- file = fopen("/data/local/tmp/dump.gles2dbg", "wb+");
- ASSERT_NE((FILE *)NULL, file) << "make sure file is writable: "
- << filePath;
- }
-
- virtual void TearDown() {
- ASSERT_NE((FILE *)NULL, file);
- fclose(file);
- file = NULL;
- }
-
- void Read(glesv2debugger::Message & msg) const {
- msg.Clear();
- uint32_t len = 0;
- ASSERT_EQ(sizeof(len), fread(&len, 1, sizeof(len), file));
- ASSERT_GT(len, 0u);
- char * buffer = new char [len];
- ASSERT_EQ(len, fread(buffer, 1, len, file));
- msg.ParseFromArray(buffer, len);
- delete buffer;
- }
-
- void CheckNoAvailable() {
- const long pos = ftell(file);
- fseek(file, 0, SEEK_END);
- EXPECT_EQ(pos, ftell(file)) << "check no available";
- }
-};
-
-TEST_F(ServerFileTest, Send)
-{
- glesv2debugger::Message msg, cmd, read;
- msg.set_context_id(1);
- msg.set_function(msg.glFinish);
- msg.set_expect_response(false);
- msg.set_type(msg.BeforeCall);
- rewind(file);
- android::Send(msg, cmd);
- rewind(file);
- Read(read);
- EXPECT_EQ(msg.context_id(), read.context_id());
- EXPECT_EQ(msg.function(), read.function());
- EXPECT_EQ(msg.expect_response(), read.expect_response());
- EXPECT_EQ(msg.type(), read.type());
-}
-
-TEST_F(ServerFileTest, CreateDbgContext)
-{
- gl_hooks_t hooks;
- struct Constant {
- GLenum pname;
- GLint param;
- };
- static const Constant constants [] = {
- {GL_MAX_VERTEX_ATTRIBS, 16},
- {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32},
- {GL_IMPLEMENTATION_COLOR_READ_FORMAT, GL_RGBA},
- {GL_IMPLEMENTATION_COLOR_READ_TYPE, GL_UNSIGNED_BYTE},
- };
- struct HookMock {
- static void GetIntegerv(GLenum pname, GLint* params) {
- ASSERT_TRUE(params != NULL);
- for (unsigned int i = 0; i < sizeof(constants) / sizeof(*constants); i++)
- if (pname == constants[i].pname) {
- *params = constants[i].param;
- return;
- }
- FAIL() << "GetIntegerv unknown pname: " << pname;
- }
- static GLenum GetError() {
- return GL_NO_ERROR;
- }
- };
- hooks.gl.glGetError = HookMock::GetError;
- hooks.gl.glGetIntegerv = HookMock::GetIntegerv;
- DbgContext * const dbg = CreateDbgContext(1, &hooks);
- ASSERT_TRUE(dbg != NULL);
- EXPECT_TRUE(dbg->vertexAttribs != NULL);
-
- rewind(file);
- glesv2debugger::Message read;
- for (unsigned int i = 0; i < 2; i++) {
- Read(read);
- EXPECT_EQ(reinterpret_cast<int>(dbg), read.context_id());
- EXPECT_FALSE(read.expect_response());
- EXPECT_EQ(read.Response, read.type());
- EXPECT_EQ(read.SETPROP, read.function());
- EXPECT_EQ(read.GLConstant, read.prop());
- GLint expectedConstant = 0;
- HookMock::GetIntegerv(read.arg0(), &expectedConstant);
- EXPECT_EQ(expectedConstant, read.arg1());
- }
- CheckNoAvailable();
- dbgReleaseThread();
-}
-
-void * glNoop()
-{
- return 0;
-}
-
-class ServerFileContextTest : public ServerFileTest
-{
-protected:
- DbgContext* dbg;
- gl_hooks_t hooks;
-
- ServerFileContextTest() { }
-
- virtual ~ServerFileContextTest() { }
-
- virtual void SetUp() {
- ServerFileTest::SetUp();
-
- dbg = new DbgContext(1, &hooks, 32);
- ASSERT_NE((void *)NULL, dbg);
- for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
- ((void **)&hooks)[i] = reinterpret_cast<void *>(glNoop);
- }
-
- virtual void TearDown() {
- ServerFileTest::TearDown();
- }
-};
-
-TEST_F(ServerFileContextTest, MessageLoop)
-{
- static const int arg0 = 45;
- static const float arg7 = -87.2331f;
- static const int arg8 = -3;
- static const int * ret = reinterpret_cast<int *>(870);
-
- struct Caller : public FunctionCall {
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- msg.set_arg0(arg0);
- msg.set_arg7((int &)arg7);
- msg.set_arg8(arg8);
- return ret;
- }
- } caller;
- const int contextId = reinterpret_cast<int>(dbg);
- glesv2debugger::Message msg, read;
-
- EXPECT_EQ(ret, MessageLoop(caller, msg, msg.glFinish));
-
- rewind(file);
- Read(read);
- EXPECT_EQ(contextId, read.context_id());
- EXPECT_EQ(read.glFinish, read.function());
- EXPECT_EQ(false, read.expect_response());
- EXPECT_EQ(read.BeforeCall, read.type());
-
- Read(read);
- EXPECT_EQ(contextId, read.context_id());
- EXPECT_EQ(read.glFinish, read.function());
- EXPECT_EQ(false, read.expect_response());
- EXPECT_EQ(read.AfterCall, read.type());
- EXPECT_TRUE(read.has_time());
- EXPECT_EQ(arg0, read.arg0());
- const int readArg7 = read.arg7();
- EXPECT_EQ(arg7, (float &)readArg7);
- EXPECT_EQ(arg8, read.arg8());
-
- const long pos = ftell(file);
- fseek(file, 0, SEEK_END);
- EXPECT_EQ(pos, ftell(file))
- << "should only write the BeforeCall and AfterCall messages";
-}
-
-TEST_F(ServerFileContextTest, DisableEnableVertexAttribArray)
-{
- Debug_glEnableVertexAttribArray(dbg->MAX_VERTEX_ATTRIBS + 2); // should just ignore invalid index
-
- glesv2debugger::Message read;
- rewind(file);
- Read(read);
- EXPECT_EQ(read.glEnableVertexAttribArray, read.function());
- EXPECT_EQ(dbg->MAX_VERTEX_ATTRIBS + 2, read.arg0());
- Read(read);
-
- rewind(file);
- Debug_glDisableVertexAttribArray(dbg->MAX_VERTEX_ATTRIBS + 4); // should just ignore invalid index
- rewind(file);
- Read(read);
- Read(read);
-
- for (unsigned int i = 0; i < dbg->MAX_VERTEX_ATTRIBS; i += 5) {
- rewind(file);
- Debug_glEnableVertexAttribArray(i);
- EXPECT_TRUE(dbg->vertexAttribs[i].enabled);
- rewind(file);
- Read(read);
- EXPECT_EQ(read.glEnableVertexAttribArray, read.function());
- EXPECT_EQ(i, read.arg0());
- Read(read);
-
- rewind(file);
- Debug_glDisableVertexAttribArray(i);
- EXPECT_FALSE(dbg->vertexAttribs[i].enabled);
- rewind(file);
- Read(read);
- EXPECT_EQ(read.glDisableVertexAttribArray, read.function());
- EXPECT_EQ(i, read.arg0());
- Read(read);
- }
-}
diff --git a/opengl/libs/GLES2_dbg/test/test_socket.cpp b/opengl/libs/GLES2_dbg/test/test_socket.cpp
deleted file mode 100644
index 9f815e211bb5..000000000000
--- a/opengl/libs/GLES2_dbg/test/test_socket.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- ** Copyright 2011, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include "header.h"
-#include "gtest/gtest.h"
-#include "hooks.h"
-
-namespace android
-{
-extern int serverSock, clientSock;
-};
-
-void * glNoop();
-
-class SocketContextTest : public ::testing::Test
-{
-protected:
- DbgContext* dbg;
- gl_hooks_t hooks;
- int sock;
- char * buffer;
- unsigned int bufferSize;
-
- SocketContextTest() : sock(-1) {
- }
-
- virtual ~SocketContextTest() {
- }
-
- virtual void SetUp() {
- dbg = new DbgContext(1, &hooks, 32);
- ASSERT_TRUE(dbg != NULL);
- for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
- ((void **)&hooks)[i] = (void *)glNoop;
-
- int socks[2] = {-1, -1};
- ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, socks));
- clientSock = socks[0];
- sock = socks[1];
-
- bufferSize = 128;
- buffer = new char [128];
- ASSERT_NE((char *)NULL, buffer);
- }
-
- virtual void TearDown() {
- close(sock);
- close(clientSock);
- clientSock = -1;
- delete buffer;
- }
-
- void Write(glesv2debugger::Message & msg) const {
- msg.set_context_id((int)dbg);
- msg.set_type(msg.Response);
- ASSERT_TRUE(msg.has_context_id());
- ASSERT_TRUE(msg.has_function());
- ASSERT_TRUE(msg.has_type());
- ASSERT_TRUE(msg.has_expect_response());
- static std::string str;
- msg.SerializeToString(&str);
- const uint32_t len = str.length();
- ASSERT_EQ(sizeof(len), send(sock, &len, sizeof(len), 0));
- ASSERT_EQ(str.length(), send(sock, str.data(), str.length(), 0));
- }
-
- void Read(glesv2debugger::Message & msg) {
- int available = 0;
- ASSERT_EQ(0, ioctl(sock, FIONREAD, &available));
- ASSERT_GT(available, 0);
- uint32_t len = 0;
- ASSERT_EQ(sizeof(len), recv(sock, &len, sizeof(len), 0));
- if (len > bufferSize) {
- bufferSize = len;
- buffer = new char[bufferSize];
- ASSERT_TRUE(buffer != NULL);
- }
- ASSERT_EQ(len, recv(sock, buffer, len, 0));
- msg.Clear();
- msg.ParseFromArray(buffer, len);
- ASSERT_TRUE(msg.has_context_id());
- ASSERT_TRUE(msg.has_function());
- ASSERT_TRUE(msg.has_type());
- ASSERT_TRUE(msg.has_expect_response());
- }
-
- void CheckNoAvailable() {
- int available = 0;
- ASSERT_EQ(0, ioctl(sock, FIONREAD, &available));
- ASSERT_EQ(available, 0);
- }
-};
-
-TEST_F(SocketContextTest, MessageLoopSkip)
-{
- static const int arg0 = 45;
- static const float arg7 = -87.2331f;
- static const int arg8 = -3;
- static const int * ret = (int *)870;
-
- struct Caller : public FunctionCall {
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- msg.set_arg0(arg0);
- msg.set_arg7((int &)arg7);
- msg.set_arg8(arg8);
- return ret;
- }
- } caller;
- glesv2debugger::Message msg, read, cmd;
- dbg->expectResponse.Bit(msg.glFinish, true);
-
- cmd.set_function(cmd.SKIP);
- cmd.set_expect_response(false);
- Write(cmd);
-
- EXPECT_NE(ret, MessageLoop(caller, msg, msg.glFinish));
-
- Read(read);
- EXPECT_EQ(read.glFinish, read.function());
- EXPECT_EQ(read.BeforeCall, read.type());
- EXPECT_NE(arg0, read.arg0());
- EXPECT_NE((int &)arg7, read.arg7());
- EXPECT_NE(arg8, read.arg8());
-
- CheckNoAvailable();
-}
-
-TEST_F(SocketContextTest, MessageLoopContinue)
-{
- static const int arg0 = GL_FRAGMENT_SHADER;
- static const int ret = -342;
- struct Caller : public FunctionCall {
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- msg.set_ret(ret);
- return (int *)ret;
- }
- } caller;
- glesv2debugger::Message msg, read, cmd;
- dbg->expectResponse.Bit(msg.glCreateShader, true);
-
- cmd.set_function(cmd.CONTINUE);
- cmd.set_expect_response(false); // MessageLoop should automatically skip after continue
- Write(cmd);
-
- msg.set_arg0(arg0);
- EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateShader));
-
- Read(read);
- EXPECT_EQ(read.glCreateShader, read.function());
- EXPECT_EQ(read.BeforeCall, read.type());
- EXPECT_EQ(arg0, read.arg0());
-
- Read(read);
- EXPECT_EQ(read.glCreateShader, read.function());
- EXPECT_EQ(read.AfterCall, read.type());
- EXPECT_EQ(ret, read.ret());
-
- CheckNoAvailable();
-}
-
-TEST_F(SocketContextTest, MessageLoopGenerateCall)
-{
- static const int ret = -342;
- static unsigned int createShader, createProgram;
- createShader = 0;
- createProgram = 0;
- struct Caller : public FunctionCall {
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int r = (int)_c->glCreateProgram();
- msg.set_ret(r);
- return (int *)r;
- }
- static GLuint CreateShader(const GLenum type) {
- createShader++;
- return type;
- }
- static GLuint CreateProgram() {
- createProgram++;
- return ret;
- }
- } caller;
- glesv2debugger::Message msg, read, cmd;
- hooks.gl.glCreateShader = caller.CreateShader;
- hooks.gl.glCreateProgram = caller.CreateProgram;
- dbg->expectResponse.Bit(msg.glCreateProgram, true);
-
- cmd.set_function(cmd.glCreateShader);
- cmd.set_arg0(GL_FRAGMENT_SHADER);
- cmd.set_expect_response(true);
- Write(cmd);
-
- cmd.Clear();
- cmd.set_function(cmd.CONTINUE);
- cmd.set_expect_response(true);
- Write(cmd);
-
- cmd.set_function(cmd.glCreateShader);
- cmd.set_arg0(GL_VERTEX_SHADER);
- cmd.set_expect_response(false); // MessageLoop should automatically skip afterwards
- Write(cmd);
-
- EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateProgram));
-
- Read(read);
- EXPECT_EQ(read.glCreateProgram, read.function());
- EXPECT_EQ(read.BeforeCall, read.type());
-
- Read(read);
- EXPECT_EQ(read.glCreateShader, read.function());
- EXPECT_EQ(read.AfterGeneratedCall, read.type());
- EXPECT_EQ(GL_FRAGMENT_SHADER, read.ret());
-
- Read(read);
- EXPECT_EQ(read.glCreateProgram, read.function());
- EXPECT_EQ(read.AfterCall, read.type());
- EXPECT_EQ(ret, read.ret());
-
- Read(read);
- EXPECT_EQ(read.glCreateShader, read.function());
- EXPECT_EQ(read.AfterGeneratedCall, read.type());
- EXPECT_EQ(GL_VERTEX_SHADER, read.ret());
-
- EXPECT_EQ(2, createShader);
- EXPECT_EQ(1, createProgram);
-
- CheckNoAvailable();
-}
-
-TEST_F(SocketContextTest, MessageLoopSetProp)
-{
- static const int ret = -342;
- static unsigned int createShader, createProgram;
- createShader = 0;
- createProgram = 0;
- struct Caller : public FunctionCall {
- const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
- const int r = (int)_c->glCreateProgram();
- msg.set_ret(r);
- return (int *)r;
- }
- static GLuint CreateShader(const GLenum type) {
- createShader++;
- return type;
- }
- static GLuint CreateProgram() {
- createProgram++;
- return ret;
- }
- } caller;
- glesv2debugger::Message msg, read, cmd;
- hooks.gl.glCreateShader = caller.CreateShader;
- hooks.gl.glCreateProgram = caller.CreateProgram;
- dbg->expectResponse.Bit(msg.glCreateProgram, false);
-
- cmd.set_function(cmd.SETPROP);
- cmd.set_prop(cmd.ExpectResponse);
- cmd.set_arg0(cmd.glCreateProgram);
- cmd.set_arg1(true);
- cmd.set_expect_response(true);
- Write(cmd);
-
- cmd.Clear();
- cmd.set_function(cmd.glCreateShader);
- cmd.set_arg0(GL_FRAGMENT_SHADER);
- cmd.set_expect_response(true);
- Write(cmd);
-
- cmd.set_function(cmd.SETPROP);
- cmd.set_prop(cmd.CaptureDraw);
- cmd.set_arg0(819);
- cmd.set_expect_response(true);
- Write(cmd);
-
- cmd.Clear();
- cmd.set_function(cmd.CONTINUE);
- cmd.set_expect_response(true);
- Write(cmd);
-
- cmd.set_function(cmd.glCreateShader);
- cmd.set_arg0(GL_VERTEX_SHADER);
- cmd.set_expect_response(false); // MessageLoop should automatically skip afterwards
- Write(cmd);
-
- EXPECT_EQ((int *)ret, MessageLoop(caller, msg, msg.glCreateProgram));
-
- EXPECT_TRUE(dbg->expectResponse.Bit(msg.glCreateProgram));
- EXPECT_EQ(819, dbg->captureDraw);
-
- Read(read);
- EXPECT_EQ(read.glCreateProgram, read.function());
- EXPECT_EQ(read.BeforeCall, read.type());
-
- Read(read);
- EXPECT_EQ(read.glCreateShader, read.function());
- EXPECT_EQ(read.AfterGeneratedCall, read.type());
- EXPECT_EQ(GL_FRAGMENT_SHADER, read.ret());
-
- Read(read);
- EXPECT_EQ(read.glCreateProgram, read.function());
- EXPECT_EQ(read.AfterCall, read.type());
- EXPECT_EQ(ret, read.ret());
-
- Read(read);
- EXPECT_EQ(read.glCreateShader, read.function());
- EXPECT_EQ(read.AfterGeneratedCall, read.type());
- EXPECT_EQ(GL_VERTEX_SHADER, read.ret());
-
- EXPECT_EQ(2, createShader);
- EXPECT_EQ(1, createProgram);
-
- CheckNoAvailable();
-}
-
-TEST_F(SocketContextTest, TexImage2D)
-{
- static const GLenum _target = GL_TEXTURE_2D;
- static const GLint _level = 1, _internalformat = GL_RGBA;
- static const GLsizei _width = 2, _height = 2;
- static const GLint _border = 333;
- static const GLenum _format = GL_RGB, _type = GL_UNSIGNED_SHORT_5_6_5;
- static const short _pixels [_width * _height] = {11, 22, 33, 44};
- static unsigned int texImage2D;
- texImage2D = 0;
-
- struct Caller {
- static void TexImage2D(GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type, const GLvoid* pixels) {
- EXPECT_EQ(_target, target);
- EXPECT_EQ(_level, level);
- EXPECT_EQ(_internalformat, internalformat);
- EXPECT_EQ(_width, width);
- EXPECT_EQ(_height, height);
- EXPECT_EQ(_border, border);
- EXPECT_EQ(_format, format);
- EXPECT_EQ(_type, type);
- EXPECT_EQ(0, memcmp(_pixels, pixels, sizeof(_pixels)));
- texImage2D++;
- }
- } caller;
- glesv2debugger::Message msg, read, cmd;
- hooks.gl.glTexImage2D = caller.TexImage2D;
- dbg->expectResponse.Bit(msg.glTexImage2D, false);
-
- Debug_glTexImage2D(_target, _level, _internalformat, _width, _height, _border,
- _format, _type, _pixels);
- EXPECT_EQ(1, texImage2D);
-
- Read(read);
- EXPECT_EQ(read.glTexImage2D, read.function());
- EXPECT_EQ(read.BeforeCall, read.type());
- EXPECT_EQ(_target, read.arg0());
- EXPECT_EQ(_level, read.arg1());
- EXPECT_EQ(_internalformat, read.arg2());
- EXPECT_EQ(_width, read.arg3());
- EXPECT_EQ(_height, read.arg4());
- EXPECT_EQ(_border, read.arg5());
- EXPECT_EQ(_format, read.arg6());
- EXPECT_EQ(_type, read.arg7());
-
- EXPECT_TRUE(read.has_data());
- uint32_t dataLen = 0;
- const unsigned char * data = dbg->Decompress(read.data().data(),
- read.data().length(), &dataLen);
- EXPECT_EQ(sizeof(_pixels), dataLen);
- if (sizeof(_pixels) == dataLen)
- EXPECT_EQ(0, memcmp(_pixels, data, sizeof(_pixels)));
-
- Read(read);
- EXPECT_EQ(read.glTexImage2D, read.function());
- EXPECT_EQ(read.AfterCall, read.type());
-
- CheckNoAvailable();
-}
-
-TEST_F(SocketContextTest, CopyTexImage2D)
-{
- static const GLenum _target = GL_TEXTURE_2D;
- static const GLint _level = 1, _internalformat = GL_RGBA;
- static const GLint _x = 9, _y = 99;
- static const GLsizei _width = 2, _height = 3;
- static const GLint _border = 333;
- static const int _pixels [_width * _height] = {11, 22, 33, 44, 55, 66};
- static unsigned int copyTexImage2D, readPixels;
- copyTexImage2D = 0, readPixels = 0;
-
- struct Caller {
- static void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
- EXPECT_EQ(_target, target);
- EXPECT_EQ(_level, level);
- EXPECT_EQ(_internalformat, internalformat);
- EXPECT_EQ(_x, x);
- EXPECT_EQ(_y, y);
- EXPECT_EQ(_width, width);
- EXPECT_EQ(_height, height);
- EXPECT_EQ(_border, border);
- copyTexImage2D++;
- }
- static void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLvoid* pixels) {
- EXPECT_EQ(_x, x);
- EXPECT_EQ(_y, y);
- EXPECT_EQ(_width, width);
- EXPECT_EQ(_height, height);
- EXPECT_EQ(GL_RGBA, format);
- EXPECT_EQ(GL_UNSIGNED_BYTE, type);
- ASSERT_TRUE(pixels != NULL);
- memcpy(pixels, _pixels, sizeof(_pixels));
- readPixels++;
- }
- } caller;
- glesv2debugger::Message msg, read, cmd;
- hooks.gl.glCopyTexImage2D = caller.CopyTexImage2D;
- hooks.gl.glReadPixels = caller.ReadPixels;
- dbg->expectResponse.Bit(msg.glCopyTexImage2D, false);
-
- Debug_glCopyTexImage2D(_target, _level, _internalformat, _x, _y, _width, _height,
- _border);
- ASSERT_EQ(1, copyTexImage2D);
- ASSERT_EQ(1, readPixels);
-
- Read(read);
- EXPECT_EQ(read.glCopyTexImage2D, read.function());
- EXPECT_EQ(read.BeforeCall, read.type());
- EXPECT_EQ(_target, read.arg0());
- EXPECT_EQ(_level, read.arg1());
- EXPECT_EQ(_internalformat, read.arg2());
- EXPECT_EQ(_x, read.arg3());
- EXPECT_EQ(_y, read.arg4());
- EXPECT_EQ(_width, read.arg5());
- EXPECT_EQ(_height, read.arg6());
- EXPECT_EQ(_border, read.arg7());
-
- EXPECT_TRUE(read.has_data());
- EXPECT_EQ(read.ReferencedImage, read.data_type());
- EXPECT_EQ(GL_RGBA, read.pixel_format());
- EXPECT_EQ(GL_UNSIGNED_BYTE, read.pixel_type());
- uint32_t dataLen = 0;
- unsigned char * const data = dbg->Decompress(read.data().data(),
- read.data().length(), &dataLen);
- ASSERT_EQ(sizeof(_pixels), dataLen);
- for (unsigned i = 0; i < sizeof(_pixels) / sizeof(*_pixels); i++)
- EXPECT_EQ(_pixels[i], ((const int *)data)[i]) << "xor with 0 ref is identity";
- free(data);
-
- Read(read);
- EXPECT_EQ(read.glCopyTexImage2D, read.function());
- EXPECT_EQ(read.AfterCall, read.type());
-
- CheckNoAvailable();
-}
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 2d31a35177c2..adeaa5b8233d 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -165,6 +165,20 @@ extern "C" {
#undef CALL_GL_API
#undef CALL_GL_API_RETURN
+/*
+ * glGetString() is special because we expose some extensions in the wrapper
+ */
+
+extern "C" const GLubyte * __glGetString(GLenum name);
+
+const GLubyte * glGetString(GLenum name)
+{
+ const GLubyte * ret = egl_get_string_for_current_context(name);
+ if (ret == NULL) {
+ ret = __glGetString(name);
+ }
+ return ret;
+}
/*
* These GL calls are special because they need to EGL to retrieve some
diff --git a/opengl/libs/GLES_CM/gl_api.in b/opengl/libs/GLES_CM/gl_api.in
index 7f20c4fda493..c8f6b0c4d6c3 100644
--- a/opengl/libs/GLES_CM/gl_api.in
+++ b/opengl/libs/GLES_CM/gl_api.in
@@ -262,7 +262,7 @@ void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
void API_ENTRY(glGetPointerv)(GLenum pname, GLvoid **params) {
CALL_GL_API(glGetPointerv, pname, params);
}
-const GLubyte * API_ENTRY(glGetString)(GLenum name) {
+const GLubyte * API_ENTRY(__glGetString)(GLenum name) {
CALL_GL_API_RETURN(glGetString, name);
}
void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) {
diff --git a/opengl/libs/GLES_CM/glext_api.in b/opengl/libs/GLES_CM/glext_api.in
index 5393fa61a056..268a5352bab5 100644
--- a/opengl/libs/GLES_CM/glext_api.in
+++ b/opengl/libs/GLES_CM/glext_api.in
@@ -280,15 +280,57 @@ void API_ENTRY(glGenVertexArraysOES)(GLsizei n, GLuint *arrays) {
GLboolean API_ENTRY(glIsVertexArrayOES)(GLuint array) {
CALL_GL_API_RETURN(glIsVertexArrayOES, array);
}
+void API_ENTRY(glRenderbufferStorageMultisampleAPPLE)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorageMultisampleAPPLE, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glResolveMultisampleFramebufferAPPLE)(void) {
+ CALL_GL_API(glResolveMultisampleFramebufferAPPLE);
+}
void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
}
+void API_ENTRY(glRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorageMultisampleEXT, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glFramebufferTexture2DMultisampleEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+ CALL_GL_API(glFramebufferTexture2DMultisampleEXT, target, attachment, textarget, texture, level, samples);
+}
void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
}
void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
}
+GLenum API_ENTRY(glGetGraphicsResetStatusEXT)(void) {
+ CALL_GL_API_RETURN(glGetGraphicsResetStatusEXT);
+}
+void API_ENTRY(glReadnPixelsEXT)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) {
+ CALL_GL_API(glReadnPixelsEXT, x, y, width, height, format, type, bufSize, data);
+}
+void API_ENTRY(glGetnUniformfvEXT)(GLuint program, GLint location, GLsizei bufSize, float *params) {
+ CALL_GL_API(glGetnUniformfvEXT, program, location, bufSize, params);
+}
+void API_ENTRY(glGetnUniformivEXT)(GLuint program, GLint location, GLsizei bufSize, GLint *params) {
+ CALL_GL_API(glGetnUniformivEXT, program, location, bufSize, params);
+}
+void API_ENTRY(glTexStorage1DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
+ CALL_GL_API(glTexStorage1DEXT, target, levels, internalformat, width);
+}
+void API_ENTRY(glTexStorage2DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glTexStorage2DEXT, target, levels, internalformat, width, height);
+}
+void API_ENTRY(glTexStorage3DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
+ CALL_GL_API(glTexStorage3DEXT, target, levels, internalformat, width, height, depth);
+}
+void API_ENTRY(glTextureStorage1DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
+ CALL_GL_API(glTextureStorage1DEXT, texture, target, levels, internalformat, width);
+}
+void API_ENTRY(glTextureStorage2DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glTextureStorage2DEXT, texture, target, levels, internalformat, width, height);
+}
+void API_ENTRY(glTextureStorage3DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
+ CALL_GL_API(glTextureStorage3DEXT, texture, target, levels, internalformat, width, height, depth);
+}
void API_ENTRY(glClipPlanefIMG)(GLenum p, const GLfloat *eqn) {
CALL_GL_API(glClipPlanefIMG, p, eqn);
}
diff --git a/opengl/libs/GLES_trace/gltrace.proto b/opengl/libs/GLES_trace/gltrace.proto
index 7dde69f55831..11cf24f5900b 100644
--- a/opengl/libs/GLES_trace/gltrace.proto
+++ b/opengl/libs/GLES_trace/gltrace.proto
@@ -400,6 +400,68 @@ message GLMessage {
glViewport = 374;
glWeightPointerOES = 375;
+ glActiveShaderProgramEXT = 502;
+ glAlphaFuncQCOM = 503;
+ glBeginQueryEXT = 504;
+ glBindProgramPipelineEXT = 505;
+ glBlitFramebufferANGLE = 506;
+ glCreateShaderProgramvEXT = 507;
+ glDeleteProgramPipelinesEXT = 508;
+ glDeleteQueriesEXT = 509;
+ glDrawBuffersNV = 510;
+ glEndQueryEXT = 511;
+ glFramebufferTexture2DMultisampleEXT = 512;
+ glGenProgramPipelinesEXT = 513;
+ glGenQueriesEXT = 514;
+ glGetGraphicsResetStatusEXT = 515;
+ glGetObjectLabelEXT = 516;
+ glGetProgramPipelineInfoLogEXT = 517;
+ glGetProgramPipelineivEXT = 518;
+ glGetQueryObjectuivEXT = 519;
+ glGetQueryivEXT = 520;
+ glGetnUniformfvEXT = 521;
+ glGetnUniformivEXT = 521;
+ glInsertEventMarkerEXT = 522;
+ glIsProgramPipelineEXT = 523;
+ glIsQueryEXT = 524;
+ glLabelObjectEXT = 525;
+ glPopGroupMarkerEXT = 526;
+ glProgramParameteriEXT = 527;
+ glProgramUniform1fEXT = 528;
+ glProgramUniform1fvEXT = 529;
+ glProgramUniform1iEXT = 530;
+ glProgramUniform1ivEXT = 531;
+ glProgramUniform2fEXT = 532;
+ glProgramUniform2fvEXT = 533;
+ glProgramUniform2iEXT = 534;
+ glProgramUniform2ivEXT = 535;
+ glProgramUniform3fEXT = 536;
+ glProgramUniform3fvEXT = 537;
+ glProgramUniform3iEXT = 538;
+ glProgramUniform3ivEXT = 539;
+ glProgramUniform4fEXT = 540;
+ glProgramUniform4fvEXT = 541;
+ glProgramUniform4iEXT = 542;
+ glProgramUniform4ivEXT = 543;
+ glProgramUniformMatrix2fvEXT = 544;
+ glProgramUniformMatrix3fvEXT = 545;
+ glProgramUniformMatrix4fvEXT = 546;
+ glPushGroupMarkerEXT = 547;
+ glReadBufferNV = 548;
+ glReadnPixelsEXT = 549;
+ glRenderbufferStorageMultisampleANGLE = 550;
+ glRenderbufferStorageMultisampleAPPLE = 551;
+ glRenderbufferStorageMultisampleEXT = 552;
+ glResolveMultisampleFramebufferAPPLE = 553;
+ glTexStorage1DEXT = 554;
+ glTexStorage2DEXT = 555;
+ glTexStorage3DEXT = 556;
+ glTextureStorage1DEXT = 557;
+ glTextureStorage2DEXT = 558;
+ glTextureStorage3DEXT = 559;
+ glUseProgramStagesEXT = 560;
+ glValidateProgramPipelineEXT = 561;
+
eglGetDisplay = 2000;
eglInitialize = 2001;
eglTerminate = 2002;
diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.cpp b/opengl/libs/GLES_trace/src/gltrace.pb.cpp
index 9a90603e01a1..bb9d4a70e829 100644
--- a/opengl/libs/GLES_trace/src/gltrace.pb.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace.pb.cpp
@@ -419,6 +419,66 @@ bool GLMessage_Function_IsValid(int value) {
case 373:
case 374:
case 375:
+ case 502:
+ case 503:
+ case 504:
+ case 505:
+ case 506:
+ case 507:
+ case 508:
+ case 509:
+ case 510:
+ case 511:
+ case 512:
+ case 513:
+ case 514:
+ case 515:
+ case 516:
+ case 517:
+ case 518:
+ case 519:
+ case 520:
+ case 521:
+ case 522:
+ case 523:
+ case 524:
+ case 525:
+ case 526:
+ case 527:
+ case 528:
+ case 529:
+ case 530:
+ case 531:
+ case 532:
+ case 533:
+ case 534:
+ case 535:
+ case 536:
+ case 537:
+ case 538:
+ case 539:
+ case 540:
+ case 541:
+ case 542:
+ case 543:
+ case 544:
+ case 545:
+ case 546:
+ case 547:
+ case 548:
+ case 549:
+ case 550:
+ case 551:
+ case 552:
+ case 553:
+ case 554:
+ case 555:
+ case 556:
+ case 557:
+ case 558:
+ case 559:
+ case 560:
+ case 561:
case 2000:
case 2001:
case 2002:
@@ -850,6 +910,67 @@ const GLMessage_Function GLMessage::glVertexAttribPointer;
const GLMessage_Function GLMessage::glVertexPointer;
const GLMessage_Function GLMessage::glViewport;
const GLMessage_Function GLMessage::glWeightPointerOES;
+const GLMessage_Function GLMessage::glActiveShaderProgramEXT;
+const GLMessage_Function GLMessage::glAlphaFuncQCOM;
+const GLMessage_Function GLMessage::glBeginQueryEXT;
+const GLMessage_Function GLMessage::glBindProgramPipelineEXT;
+const GLMessage_Function GLMessage::glBlitFramebufferANGLE;
+const GLMessage_Function GLMessage::glCreateShaderProgramvEXT;
+const GLMessage_Function GLMessage::glDeleteProgramPipelinesEXT;
+const GLMessage_Function GLMessage::glDeleteQueriesEXT;
+const GLMessage_Function GLMessage::glDrawBuffersNV;
+const GLMessage_Function GLMessage::glEndQueryEXT;
+const GLMessage_Function GLMessage::glFramebufferTexture2DMultisampleEXT;
+const GLMessage_Function GLMessage::glGenProgramPipelinesEXT;
+const GLMessage_Function GLMessage::glGenQueriesEXT;
+const GLMessage_Function GLMessage::glGetGraphicsResetStatusEXT;
+const GLMessage_Function GLMessage::glGetObjectLabelEXT;
+const GLMessage_Function GLMessage::glGetProgramPipelineInfoLogEXT;
+const GLMessage_Function GLMessage::glGetProgramPipelineivEXT;
+const GLMessage_Function GLMessage::glGetQueryObjectuivEXT;
+const GLMessage_Function GLMessage::glGetQueryivEXT;
+const GLMessage_Function GLMessage::glGetnUniformfvEXT;
+const GLMessage_Function GLMessage::glGetnUniformivEXT;
+const GLMessage_Function GLMessage::glInsertEventMarkerEXT;
+const GLMessage_Function GLMessage::glIsProgramPipelineEXT;
+const GLMessage_Function GLMessage::glIsQueryEXT;
+const GLMessage_Function GLMessage::glLabelObjectEXT;
+const GLMessage_Function GLMessage::glPopGroupMarkerEXT;
+const GLMessage_Function GLMessage::glProgramParameteriEXT;
+const GLMessage_Function GLMessage::glProgramUniform1fEXT;
+const GLMessage_Function GLMessage::glProgramUniform1fvEXT;
+const GLMessage_Function GLMessage::glProgramUniform1iEXT;
+const GLMessage_Function GLMessage::glProgramUniform1ivEXT;
+const GLMessage_Function GLMessage::glProgramUniform2fEXT;
+const GLMessage_Function GLMessage::glProgramUniform2fvEXT;
+const GLMessage_Function GLMessage::glProgramUniform2iEXT;
+const GLMessage_Function GLMessage::glProgramUniform2ivEXT;
+const GLMessage_Function GLMessage::glProgramUniform3fEXT;
+const GLMessage_Function GLMessage::glProgramUniform3fvEXT;
+const GLMessage_Function GLMessage::glProgramUniform3iEXT;
+const GLMessage_Function GLMessage::glProgramUniform3ivEXT;
+const GLMessage_Function GLMessage::glProgramUniform4fEXT;
+const GLMessage_Function GLMessage::glProgramUniform4fvEXT;
+const GLMessage_Function GLMessage::glProgramUniform4iEXT;
+const GLMessage_Function GLMessage::glProgramUniform4ivEXT;
+const GLMessage_Function GLMessage::glProgramUniformMatrix2fvEXT;
+const GLMessage_Function GLMessage::glProgramUniformMatrix3fvEXT;
+const GLMessage_Function GLMessage::glProgramUniformMatrix4fvEXT;
+const GLMessage_Function GLMessage::glPushGroupMarkerEXT;
+const GLMessage_Function GLMessage::glReadBufferNV;
+const GLMessage_Function GLMessage::glReadnPixelsEXT;
+const GLMessage_Function GLMessage::glRenderbufferStorageMultisampleANGLE;
+const GLMessage_Function GLMessage::glRenderbufferStorageMultisampleAPPLE;
+const GLMessage_Function GLMessage::glRenderbufferStorageMultisampleEXT;
+const GLMessage_Function GLMessage::glResolveMultisampleFramebufferAPPLE;
+const GLMessage_Function GLMessage::glTexStorage1DEXT;
+const GLMessage_Function GLMessage::glTexStorage2DEXT;
+const GLMessage_Function GLMessage::glTexStorage3DEXT;
+const GLMessage_Function GLMessage::glTextureStorage1DEXT;
+const GLMessage_Function GLMessage::glTextureStorage2DEXT;
+const GLMessage_Function GLMessage::glTextureStorage3DEXT;
+const GLMessage_Function GLMessage::glUseProgramStagesEXT;
+const GLMessage_Function GLMessage::glValidateProgramPipelineEXT;
const GLMessage_Function GLMessage::eglGetDisplay;
const GLMessage_Function GLMessage::eglInitialize;
const GLMessage_Function GLMessage::eglTerminate;
diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.h b/opengl/libs/GLES_trace/src/gltrace.pb.h
index 5a7a16f1487a..e3b8990faee7 100644
--- a/opengl/libs/GLES_trace/src/gltrace.pb.h
+++ b/opengl/libs/GLES_trace/src/gltrace.pb.h
@@ -427,6 +427,67 @@ enum GLMessage_Function {
GLMessage_Function_glVertexPointer = 373,
GLMessage_Function_glViewport = 374,
GLMessage_Function_glWeightPointerOES = 375,
+ GLMessage_Function_glActiveShaderProgramEXT = 502,
+ GLMessage_Function_glAlphaFuncQCOM = 503,
+ GLMessage_Function_glBeginQueryEXT = 504,
+ GLMessage_Function_glBindProgramPipelineEXT = 505,
+ GLMessage_Function_glBlitFramebufferANGLE = 506,
+ GLMessage_Function_glCreateShaderProgramvEXT = 507,
+ GLMessage_Function_glDeleteProgramPipelinesEXT = 508,
+ GLMessage_Function_glDeleteQueriesEXT = 509,
+ GLMessage_Function_glDrawBuffersNV = 510,
+ GLMessage_Function_glEndQueryEXT = 511,
+ GLMessage_Function_glFramebufferTexture2DMultisampleEXT = 512,
+ GLMessage_Function_glGenProgramPipelinesEXT = 513,
+ GLMessage_Function_glGenQueriesEXT = 514,
+ GLMessage_Function_glGetGraphicsResetStatusEXT = 515,
+ GLMessage_Function_glGetObjectLabelEXT = 516,
+ GLMessage_Function_glGetProgramPipelineInfoLogEXT = 517,
+ GLMessage_Function_glGetProgramPipelineivEXT = 518,
+ GLMessage_Function_glGetQueryObjectuivEXT = 519,
+ GLMessage_Function_glGetQueryivEXT = 520,
+ GLMessage_Function_glGetnUniformfvEXT = 521,
+ GLMessage_Function_glGetnUniformivEXT = 521,
+ GLMessage_Function_glInsertEventMarkerEXT = 522,
+ GLMessage_Function_glIsProgramPipelineEXT = 523,
+ GLMessage_Function_glIsQueryEXT = 524,
+ GLMessage_Function_glLabelObjectEXT = 525,
+ GLMessage_Function_glPopGroupMarkerEXT = 526,
+ GLMessage_Function_glProgramParameteriEXT = 527,
+ GLMessage_Function_glProgramUniform1fEXT = 528,
+ GLMessage_Function_glProgramUniform1fvEXT = 529,
+ GLMessage_Function_glProgramUniform1iEXT = 530,
+ GLMessage_Function_glProgramUniform1ivEXT = 531,
+ GLMessage_Function_glProgramUniform2fEXT = 532,
+ GLMessage_Function_glProgramUniform2fvEXT = 533,
+ GLMessage_Function_glProgramUniform2iEXT = 534,
+ GLMessage_Function_glProgramUniform2ivEXT = 535,
+ GLMessage_Function_glProgramUniform3fEXT = 536,
+ GLMessage_Function_glProgramUniform3fvEXT = 537,
+ GLMessage_Function_glProgramUniform3iEXT = 538,
+ GLMessage_Function_glProgramUniform3ivEXT = 539,
+ GLMessage_Function_glProgramUniform4fEXT = 540,
+ GLMessage_Function_glProgramUniform4fvEXT = 541,
+ GLMessage_Function_glProgramUniform4iEXT = 542,
+ GLMessage_Function_glProgramUniform4ivEXT = 543,
+ GLMessage_Function_glProgramUniformMatrix2fvEXT = 544,
+ GLMessage_Function_glProgramUniformMatrix3fvEXT = 545,
+ GLMessage_Function_glProgramUniformMatrix4fvEXT = 546,
+ GLMessage_Function_glPushGroupMarkerEXT = 547,
+ GLMessage_Function_glReadBufferNV = 548,
+ GLMessage_Function_glReadnPixelsEXT = 549,
+ GLMessage_Function_glRenderbufferStorageMultisampleANGLE = 550,
+ GLMessage_Function_glRenderbufferStorageMultisampleAPPLE = 551,
+ GLMessage_Function_glRenderbufferStorageMultisampleEXT = 552,
+ GLMessage_Function_glResolveMultisampleFramebufferAPPLE = 553,
+ GLMessage_Function_glTexStorage1DEXT = 554,
+ GLMessage_Function_glTexStorage2DEXT = 555,
+ GLMessage_Function_glTexStorage3DEXT = 556,
+ GLMessage_Function_glTextureStorage1DEXT = 557,
+ GLMessage_Function_glTextureStorage2DEXT = 558,
+ GLMessage_Function_glTextureStorage3DEXT = 559,
+ GLMessage_Function_glUseProgramStagesEXT = 560,
+ GLMessage_Function_glValidateProgramPipelineEXT = 561,
GLMessage_Function_eglGetDisplay = 2000,
GLMessage_Function_eglInitialize = 2001,
GLMessage_Function_eglTerminate = 2002,
@@ -1182,6 +1243,67 @@ class GLMessage : public ::google::protobuf::MessageLite {
static const Function glVertexPointer = GLMessage_Function_glVertexPointer;
static const Function glViewport = GLMessage_Function_glViewport;
static const Function glWeightPointerOES = GLMessage_Function_glWeightPointerOES;
+ static const Function glActiveShaderProgramEXT = GLMessage_Function_glActiveShaderProgramEXT;
+ static const Function glAlphaFuncQCOM = GLMessage_Function_glAlphaFuncQCOM;
+ static const Function glBeginQueryEXT = GLMessage_Function_glBeginQueryEXT;
+ static const Function glBindProgramPipelineEXT = GLMessage_Function_glBindProgramPipelineEXT;
+ static const Function glBlitFramebufferANGLE = GLMessage_Function_glBlitFramebufferANGLE;
+ static const Function glCreateShaderProgramvEXT = GLMessage_Function_glCreateShaderProgramvEXT;
+ static const Function glDeleteProgramPipelinesEXT = GLMessage_Function_glDeleteProgramPipelinesEXT;
+ static const Function glDeleteQueriesEXT = GLMessage_Function_glDeleteQueriesEXT;
+ static const Function glDrawBuffersNV = GLMessage_Function_glDrawBuffersNV;
+ static const Function glEndQueryEXT = GLMessage_Function_glEndQueryEXT;
+ static const Function glFramebufferTexture2DMultisampleEXT = GLMessage_Function_glFramebufferTexture2DMultisampleEXT;
+ static const Function glGenProgramPipelinesEXT = GLMessage_Function_glGenProgramPipelinesEXT;
+ static const Function glGenQueriesEXT = GLMessage_Function_glGenQueriesEXT;
+ static const Function glGetGraphicsResetStatusEXT = GLMessage_Function_glGetGraphicsResetStatusEXT;
+ static const Function glGetObjectLabelEXT = GLMessage_Function_glGetObjectLabelEXT;
+ static const Function glGetProgramPipelineInfoLogEXT = GLMessage_Function_glGetProgramPipelineInfoLogEXT;
+ static const Function glGetProgramPipelineivEXT = GLMessage_Function_glGetProgramPipelineivEXT;
+ static const Function glGetQueryObjectuivEXT = GLMessage_Function_glGetQueryObjectuivEXT;
+ static const Function glGetQueryivEXT = GLMessage_Function_glGetQueryivEXT;
+ static const Function glGetnUniformfvEXT = GLMessage_Function_glGetnUniformfvEXT;
+ static const Function glGetnUniformivEXT = GLMessage_Function_glGetnUniformivEXT;
+ static const Function glInsertEventMarkerEXT = GLMessage_Function_glInsertEventMarkerEXT;
+ static const Function glIsProgramPipelineEXT = GLMessage_Function_glIsProgramPipelineEXT;
+ static const Function glIsQueryEXT = GLMessage_Function_glIsQueryEXT;
+ static const Function glLabelObjectEXT = GLMessage_Function_glLabelObjectEXT;
+ static const Function glPopGroupMarkerEXT = GLMessage_Function_glPopGroupMarkerEXT;
+ static const Function glProgramParameteriEXT = GLMessage_Function_glProgramParameteriEXT;
+ static const Function glProgramUniform1fEXT = GLMessage_Function_glProgramUniform1fEXT;
+ static const Function glProgramUniform1fvEXT = GLMessage_Function_glProgramUniform1fvEXT;
+ static const Function glProgramUniform1iEXT = GLMessage_Function_glProgramUniform1iEXT;
+ static const Function glProgramUniform1ivEXT = GLMessage_Function_glProgramUniform1ivEXT;
+ static const Function glProgramUniform2fEXT = GLMessage_Function_glProgramUniform2fEXT;
+ static const Function glProgramUniform2fvEXT = GLMessage_Function_glProgramUniform2fvEXT;
+ static const Function glProgramUniform2iEXT = GLMessage_Function_glProgramUniform2iEXT;
+ static const Function glProgramUniform2ivEXT = GLMessage_Function_glProgramUniform2ivEXT;
+ static const Function glProgramUniform3fEXT = GLMessage_Function_glProgramUniform3fEXT;
+ static const Function glProgramUniform3fvEXT = GLMessage_Function_glProgramUniform3fvEXT;
+ static const Function glProgramUniform3iEXT = GLMessage_Function_glProgramUniform3iEXT;
+ static const Function glProgramUniform3ivEXT = GLMessage_Function_glProgramUniform3ivEXT;
+ static const Function glProgramUniform4fEXT = GLMessage_Function_glProgramUniform4fEXT;
+ static const Function glProgramUniform4fvEXT = GLMessage_Function_glProgramUniform4fvEXT;
+ static const Function glProgramUniform4iEXT = GLMessage_Function_glProgramUniform4iEXT;
+ static const Function glProgramUniform4ivEXT = GLMessage_Function_glProgramUniform4ivEXT;
+ static const Function glProgramUniformMatrix2fvEXT = GLMessage_Function_glProgramUniformMatrix2fvEXT;
+ static const Function glProgramUniformMatrix3fvEXT = GLMessage_Function_glProgramUniformMatrix3fvEXT;
+ static const Function glProgramUniformMatrix4fvEXT = GLMessage_Function_glProgramUniformMatrix4fvEXT;
+ static const Function glPushGroupMarkerEXT = GLMessage_Function_glPushGroupMarkerEXT;
+ static const Function glReadBufferNV = GLMessage_Function_glReadBufferNV;
+ static const Function glReadnPixelsEXT = GLMessage_Function_glReadnPixelsEXT;
+ static const Function glRenderbufferStorageMultisampleANGLE = GLMessage_Function_glRenderbufferStorageMultisampleANGLE;
+ static const Function glRenderbufferStorageMultisampleAPPLE = GLMessage_Function_glRenderbufferStorageMultisampleAPPLE;
+ static const Function glRenderbufferStorageMultisampleEXT = GLMessage_Function_glRenderbufferStorageMultisampleEXT;
+ static const Function glResolveMultisampleFramebufferAPPLE = GLMessage_Function_glResolveMultisampleFramebufferAPPLE;
+ static const Function glTexStorage1DEXT = GLMessage_Function_glTexStorage1DEXT;
+ static const Function glTexStorage2DEXT = GLMessage_Function_glTexStorage2DEXT;
+ static const Function glTexStorage3DEXT = GLMessage_Function_glTexStorage3DEXT;
+ static const Function glTextureStorage1DEXT = GLMessage_Function_glTextureStorage1DEXT;
+ static const Function glTextureStorage2DEXT = GLMessage_Function_glTextureStorage2DEXT;
+ static const Function glTextureStorage3DEXT = GLMessage_Function_glTextureStorage3DEXT;
+ static const Function glUseProgramStagesEXT = GLMessage_Function_glUseProgramStagesEXT;
+ static const Function glValidateProgramPipelineEXT = GLMessage_Function_glValidateProgramPipelineEXT;
static const Function eglGetDisplay = GLMessage_Function_eglGetDisplay;
static const Function eglInitialize = GLMessage_Function_eglInitialize;
static const Function eglTerminate = GLMessage_Function_eglTerminate;
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.cpp b/opengl/libs/GLES_trace/src/gltrace_api.cpp
index c8e820d82315..a2366ac9b95a 100644
--- a/opengl/libs/GLES_trace/src/gltrace_api.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_api.cpp
@@ -5809,6 +5809,339 @@ void GLTrace_glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsize
glContext->traceGLMessage(&glmsg);
}
+void GLTrace_glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glBlitFramebufferANGLE);
+
+ // copy argument srcX0
+ GLMessage_DataType *arg_srcX0 = glmsg.add_args();
+ arg_srcX0->set_isarray(false);
+ arg_srcX0->set_type(GLMessage::DataType::INT);
+ arg_srcX0->add_intvalue(srcX0);
+
+ // copy argument srcY0
+ GLMessage_DataType *arg_srcY0 = glmsg.add_args();
+ arg_srcY0->set_isarray(false);
+ arg_srcY0->set_type(GLMessage::DataType::INT);
+ arg_srcY0->add_intvalue(srcY0);
+
+ // copy argument srcX1
+ GLMessage_DataType *arg_srcX1 = glmsg.add_args();
+ arg_srcX1->set_isarray(false);
+ arg_srcX1->set_type(GLMessage::DataType::INT);
+ arg_srcX1->add_intvalue(srcX1);
+
+ // copy argument srcY1
+ GLMessage_DataType *arg_srcY1 = glmsg.add_args();
+ arg_srcY1->set_isarray(false);
+ arg_srcY1->set_type(GLMessage::DataType::INT);
+ arg_srcY1->add_intvalue(srcY1);
+
+ // copy argument dstX0
+ GLMessage_DataType *arg_dstX0 = glmsg.add_args();
+ arg_dstX0->set_isarray(false);
+ arg_dstX0->set_type(GLMessage::DataType::INT);
+ arg_dstX0->add_intvalue(dstX0);
+
+ // copy argument dstY0
+ GLMessage_DataType *arg_dstY0 = glmsg.add_args();
+ arg_dstY0->set_isarray(false);
+ arg_dstY0->set_type(GLMessage::DataType::INT);
+ arg_dstY0->add_intvalue(dstY0);
+
+ // copy argument dstX1
+ GLMessage_DataType *arg_dstX1 = glmsg.add_args();
+ arg_dstX1->set_isarray(false);
+ arg_dstX1->set_type(GLMessage::DataType::INT);
+ arg_dstX1->add_intvalue(dstX1);
+
+ // copy argument dstY1
+ GLMessage_DataType *arg_dstY1 = glmsg.add_args();
+ arg_dstY1->set_isarray(false);
+ arg_dstY1->set_type(GLMessage::DataType::INT);
+ arg_dstY1->add_intvalue(dstY1);
+
+ // copy argument mask
+ GLMessage_DataType *arg_mask = glmsg.add_args();
+ arg_mask->set_isarray(false);
+ arg_mask->set_type(GLMessage::DataType::INT);
+ arg_mask->add_intvalue(mask);
+
+ // copy argument filter
+ GLMessage_DataType *arg_filter = glmsg.add_args();
+ arg_filter->set_isarray(false);
+ arg_filter->set_type(GLMessage::DataType::ENUM);
+ arg_filter->add_intvalue((int)filter);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glBlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glRenderbufferStorageMultisampleANGLE);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument samples
+ GLMessage_DataType *arg_samples = glmsg.add_args();
+ arg_samples->set_isarray(false);
+ arg_samples->set_type(GLMessage::DataType::INT);
+ arg_samples->add_intvalue(samples);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glRenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRenderbufferStorageMultisampleAPPLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glRenderbufferStorageMultisampleAPPLE);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument samples
+ GLMessage_DataType *arg_samples = glmsg.add_args();
+ arg_samples->set_isarray(false);
+ arg_samples->set_type(GLMessage::DataType::INT);
+ arg_samples->add_intvalue(samples);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glRenderbufferStorageMultisampleAPPLE(target, samples, internalformat, width, height);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glResolveMultisampleFramebufferAPPLE(void) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glResolveMultisampleFramebufferAPPLE);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glResolveMultisampleFramebufferAPPLE();
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLabelObjectEXT(GLenum type, GLuint object, GLsizei length, const GLchar *label) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glLabelObjectEXT);
+
+ // copy argument type
+ GLMessage_DataType *arg_type = glmsg.add_args();
+ arg_type->set_isarray(false);
+ arg_type->set_type(GLMessage::DataType::ENUM);
+ arg_type->add_intvalue((int)type);
+
+ // copy argument object
+ GLMessage_DataType *arg_object = glmsg.add_args();
+ arg_object->set_isarray(false);
+ arg_object->set_type(GLMessage::DataType::INT);
+ arg_object->add_intvalue(object);
+
+ // copy argument length
+ GLMessage_DataType *arg_length = glmsg.add_args();
+ arg_length->set_isarray(false);
+ arg_length->set_type(GLMessage::DataType::INT);
+ arg_length->add_intvalue(length);
+
+ // copy argument label
+ GLMessage_DataType *arg_label = glmsg.add_args();
+ arg_label->set_isarray(false);
+ arg_label->set_type(GLMessage::DataType::INT);
+ arg_label->add_intvalue((int)label);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glLabelObjectEXT(type, object, length, label);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetObjectLabelEXT);
+
+ // copy argument type
+ GLMessage_DataType *arg_type = glmsg.add_args();
+ arg_type->set_isarray(false);
+ arg_type->set_type(GLMessage::DataType::ENUM);
+ arg_type->add_intvalue((int)type);
+
+ // copy argument object
+ GLMessage_DataType *arg_object = glmsg.add_args();
+ arg_object->set_isarray(false);
+ arg_object->set_type(GLMessage::DataType::INT);
+ arg_object->add_intvalue(object);
+
+ // copy argument bufSize
+ GLMessage_DataType *arg_bufSize = glmsg.add_args();
+ arg_bufSize->set_isarray(false);
+ arg_bufSize->set_type(GLMessage::DataType::INT);
+ arg_bufSize->add_intvalue(bufSize);
+
+ // copy argument length
+ GLMessage_DataType *arg_length = glmsg.add_args();
+ arg_length->set_isarray(false);
+ arg_length->set_type(GLMessage::DataType::INT);
+ arg_length->add_intvalue((int)length);
+
+ // copy argument label
+ GLMessage_DataType *arg_label = glmsg.add_args();
+ arg_label->set_isarray(false);
+ arg_label->set_type(GLMessage::DataType::INT);
+ arg_label->add_intvalue((int)label);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetObjectLabelEXT(type, object, bufSize, length, label);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glInsertEventMarkerEXT(GLsizei length, const GLchar *marker) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glInsertEventMarkerEXT);
+
+ // copy argument length
+ GLMessage_DataType *arg_length = glmsg.add_args();
+ arg_length->set_isarray(false);
+ arg_length->set_type(GLMessage::DataType::INT);
+ arg_length->add_intvalue(length);
+
+ // copy argument marker
+ GLMessage_DataType *arg_marker = glmsg.add_args();
+ arg_marker->set_isarray(false);
+ arg_marker->set_type(GLMessage::DataType::INT);
+ arg_marker->add_intvalue((int)marker);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glInsertEventMarkerEXT(length, marker);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glPushGroupMarkerEXT);
+
+ // copy argument length
+ GLMessage_DataType *arg_length = glmsg.add_args();
+ arg_length->set_isarray(false);
+ arg_length->set_type(GLMessage::DataType::INT);
+ arg_length->add_intvalue(length);
+
+ // copy argument marker
+ GLMessage_DataType *arg_marker = glmsg.add_args();
+ arg_marker->set_isarray(false);
+ arg_marker->set_type(GLMessage::DataType::INT);
+ arg_marker->add_intvalue((int)marker);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glPushGroupMarkerEXT(length, marker);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPopGroupMarkerEXT(void) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glPopGroupMarkerEXT);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glPopGroupMarkerEXT();
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
void GLTrace_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
GLMessage glmsg;
GLTraceContext *glContext = getGLTraceContext();
@@ -5842,6 +6175,102 @@ void GLTrace_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, cons
glContext->traceGLMessage(&glmsg);
}
+void GLTrace_glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glRenderbufferStorageMultisampleEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument samples
+ GLMessage_DataType *arg_samples = glmsg.add_args();
+ arg_samples->set_isarray(false);
+ arg_samples->set_type(GLMessage::DataType::INT);
+ arg_samples->add_intvalue(samples);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glFramebufferTexture2DMultisampleEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument attachment
+ GLMessage_DataType *arg_attachment = glmsg.add_args();
+ arg_attachment->set_isarray(false);
+ arg_attachment->set_type(GLMessage::DataType::ENUM);
+ arg_attachment->add_intvalue((int)attachment);
+
+ // copy argument textarget
+ GLMessage_DataType *arg_textarget = glmsg.add_args();
+ arg_textarget->set_isarray(false);
+ arg_textarget->set_type(GLMessage::DataType::ENUM);
+ arg_textarget->add_intvalue((int)textarget);
+
+ // copy argument texture
+ GLMessage_DataType *arg_texture = glmsg.add_args();
+ arg_texture->set_isarray(false);
+ arg_texture->set_type(GLMessage::DataType::INT);
+ arg_texture->add_intvalue(texture);
+
+ // copy argument level
+ GLMessage_DataType *arg_level = glmsg.add_args();
+ arg_level->set_isarray(false);
+ arg_level->set_type(GLMessage::DataType::INT);
+ arg_level->add_intvalue(level);
+
+ // copy argument samples
+ GLMessage_DataType *arg_samples = glmsg.add_args();
+ arg_samples->set_isarray(false);
+ arg_samples->set_type(GLMessage::DataType::INT);
+ arg_samples->add_intvalue(samples);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
void GLTrace_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
GLMessage glmsg;
GLTraceContext *glContext = getGLTraceContext();
@@ -5926,6 +6355,1769 @@ void GLTrace_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum ty
glContext->traceGLMessage(&glmsg);
}
+void GLTrace_glGenQueriesEXT(GLsizei n, GLuint *ids) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGenQueriesEXT);
+
+ // copy argument n
+ GLMessage_DataType *arg_n = glmsg.add_args();
+ arg_n->set_isarray(false);
+ arg_n->set_type(GLMessage::DataType::INT);
+ arg_n->add_intvalue(n);
+
+ // copy argument ids
+ GLMessage_DataType *arg_ids = glmsg.add_args();
+ arg_ids->set_isarray(false);
+ arg_ids->set_type(GLMessage::DataType::INT);
+ arg_ids->add_intvalue((int)ids);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGenQueriesEXT(n, ids);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteQueriesEXT(GLsizei n, const GLuint *ids) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glDeleteQueriesEXT);
+
+ // copy argument n
+ GLMessage_DataType *arg_n = glmsg.add_args();
+ arg_n->set_isarray(false);
+ arg_n->set_type(GLMessage::DataType::INT);
+ arg_n->add_intvalue(n);
+
+ // copy argument ids
+ GLMessage_DataType *arg_ids = glmsg.add_args();
+ arg_ids->set_isarray(false);
+ arg_ids->set_type(GLMessage::DataType::INT);
+ arg_ids->add_intvalue((int)ids);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glDeleteQueriesEXT(n, ids);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsQueryEXT(GLuint id) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glIsQueryEXT);
+
+ // copy argument id
+ GLMessage_DataType *arg_id = glmsg.add_args();
+ arg_id->set_isarray(false);
+ arg_id->set_type(GLMessage::DataType::INT);
+ arg_id->add_intvalue(id);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ GLboolean retValue = glContext->hooks->gl.glIsQueryEXT(id);
+ nsecs_t end_time = systemTime();
+
+ // set return value
+ GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+ rt->set_isarray(false);
+ rt->set_type(GLMessage::DataType::BOOL);
+ rt->add_boolvalue(retValue);
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+
+ return retValue;
+}
+
+void GLTrace_glBeginQueryEXT(GLenum target, GLuint id) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glBeginQueryEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument id
+ GLMessage_DataType *arg_id = glmsg.add_args();
+ arg_id->set_isarray(false);
+ arg_id->set_type(GLMessage::DataType::INT);
+ arg_id->add_intvalue(id);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glBeginQueryEXT(target, id);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEndQueryEXT(GLenum target) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glEndQueryEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glEndQueryEXT(target);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetQueryivEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument pname
+ GLMessage_DataType *arg_pname = glmsg.add_args();
+ arg_pname->set_isarray(false);
+ arg_pname->set_type(GLMessage::DataType::ENUM);
+ arg_pname->add_intvalue((int)pname);
+
+ // copy argument params
+ GLMessage_DataType *arg_params = glmsg.add_args();
+ arg_params->set_isarray(false);
+ arg_params->set_type(GLMessage::DataType::INT);
+ arg_params->add_intvalue((int)params);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetQueryivEXT(target, pname, params);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetQueryObjectuivEXT);
+
+ // copy argument id
+ GLMessage_DataType *arg_id = glmsg.add_args();
+ arg_id->set_isarray(false);
+ arg_id->set_type(GLMessage::DataType::INT);
+ arg_id->add_intvalue(id);
+
+ // copy argument pname
+ GLMessage_DataType *arg_pname = glmsg.add_args();
+ arg_pname->set_isarray(false);
+ arg_pname->set_type(GLMessage::DataType::ENUM);
+ arg_pname->add_intvalue((int)pname);
+
+ // copy argument params
+ GLMessage_DataType *arg_params = glmsg.add_args();
+ arg_params->set_isarray(false);
+ arg_params->set_type(GLMessage::DataType::INT);
+ arg_params->add_intvalue((int)params);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetQueryObjectuivEXT(id, pname, params);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+GLenum GLTrace_glGetGraphicsResetStatusEXT(void) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetGraphicsResetStatusEXT);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ GLenum retValue = glContext->hooks->gl.glGetGraphicsResetStatusEXT();
+ nsecs_t end_time = systemTime();
+
+ // set return value
+ GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+ rt->set_isarray(false);
+ rt->set_type(GLMessage::DataType::ENUM);
+ rt->add_intvalue((int)retValue);
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+
+ return retValue;
+}
+
+void GLTrace_glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glReadnPixelsEXT);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::INT);
+ arg_x->add_intvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::INT);
+ arg_y->add_intvalue(y);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // copy argument format
+ GLMessage_DataType *arg_format = glmsg.add_args();
+ arg_format->set_isarray(false);
+ arg_format->set_type(GLMessage::DataType::ENUM);
+ arg_format->add_intvalue((int)format);
+
+ // copy argument type
+ GLMessage_DataType *arg_type = glmsg.add_args();
+ arg_type->set_isarray(false);
+ arg_type->set_type(GLMessage::DataType::ENUM);
+ arg_type->add_intvalue((int)type);
+
+ // copy argument bufSize
+ GLMessage_DataType *arg_bufSize = glmsg.add_args();
+ arg_bufSize->set_isarray(false);
+ arg_bufSize->set_type(GLMessage::DataType::INT);
+ arg_bufSize->add_intvalue(bufSize);
+
+ // copy argument data
+ GLMessage_DataType *arg_data = glmsg.add_args();
+ arg_data->set_isarray(false);
+ arg_data->set_type(GLMessage::DataType::INT);
+ arg_data->add_intvalue((int)data);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, float *params) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetnUniformfvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument bufSize
+ GLMessage_DataType *arg_bufSize = glmsg.add_args();
+ arg_bufSize->set_isarray(false);
+ arg_bufSize->set_type(GLMessage::DataType::INT);
+ arg_bufSize->add_intvalue(bufSize);
+
+ // copy argument params
+ GLMessage_DataType *arg_params = glmsg.add_args();
+ arg_params->set_isarray(false);
+ arg_params->set_type(GLMessage::DataType::INT);
+ arg_params->add_intvalue((int)params);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetnUniformfvEXT(program, location, bufSize, params);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetnUniformivEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument bufSize
+ GLMessage_DataType *arg_bufSize = glmsg.add_args();
+ arg_bufSize->set_isarray(false);
+ arg_bufSize->set_type(GLMessage::DataType::INT);
+ arg_bufSize->add_intvalue(bufSize);
+
+ // copy argument params
+ GLMessage_DataType *arg_params = glmsg.add_args();
+ arg_params->set_isarray(false);
+ arg_params->set_type(GLMessage::DataType::INT);
+ arg_params->add_intvalue((int)params);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetnUniformivEXT(program, location, bufSize, params);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUseProgramStagesEXT(GLuint pipeline, GLbitfield stages, GLuint program) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glUseProgramStagesEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // copy argument stages
+ GLMessage_DataType *arg_stages = glmsg.add_args();
+ arg_stages->set_isarray(false);
+ arg_stages->set_type(GLMessage::DataType::INT);
+ arg_stages->add_intvalue(stages);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glUseProgramStagesEXT(pipeline, stages, program);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glActiveShaderProgramEXT(GLuint pipeline, GLuint program) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glActiveShaderProgramEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glActiveShaderProgramEXT(pipeline, program);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+GLuint GLTrace_glCreateShaderProgramvEXT(GLenum type, GLsizei count, const GLchar **strings) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glCreateShaderProgramvEXT);
+
+ // copy argument type
+ GLMessage_DataType *arg_type = glmsg.add_args();
+ arg_type->set_isarray(false);
+ arg_type->set_type(GLMessage::DataType::ENUM);
+ arg_type->add_intvalue((int)type);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument strings
+ GLMessage_DataType *arg_strings = glmsg.add_args();
+ arg_strings->set_isarray(false);
+ arg_strings->set_type(GLMessage::DataType::INT);
+ arg_strings->add_intvalue((int)strings);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ GLuint retValue = glContext->hooks->gl.glCreateShaderProgramvEXT(type, count, strings);
+ nsecs_t end_time = systemTime();
+
+ // set return value
+ GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+ rt->set_isarray(false);
+ rt->set_type(GLMessage::DataType::INT);
+ rt->add_intvalue(retValue);
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+
+ return retValue;
+}
+
+void GLTrace_glBindProgramPipelineEXT(GLuint pipeline) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glBindProgramPipelineEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glBindProgramPipelineEXT(pipeline);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glDeleteProgramPipelinesEXT);
+
+ // copy argument n
+ GLMessage_DataType *arg_n = glmsg.add_args();
+ arg_n->set_isarray(false);
+ arg_n->set_type(GLMessage::DataType::INT);
+ arg_n->add_intvalue(n);
+
+ // copy argument pipelines
+ GLMessage_DataType *arg_pipelines = glmsg.add_args();
+ arg_pipelines->set_isarray(false);
+ arg_pipelines->set_type(GLMessage::DataType::INT);
+ arg_pipelines->add_intvalue((int)pipelines);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glDeleteProgramPipelinesEXT(n, pipelines);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenProgramPipelinesEXT(GLsizei n, GLuint *pipelines) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGenProgramPipelinesEXT);
+
+ // copy argument n
+ GLMessage_DataType *arg_n = glmsg.add_args();
+ arg_n->set_isarray(false);
+ arg_n->set_type(GLMessage::DataType::INT);
+ arg_n->add_intvalue(n);
+
+ // copy argument pipelines
+ GLMessage_DataType *arg_pipelines = glmsg.add_args();
+ arg_pipelines->set_isarray(false);
+ arg_pipelines->set_type(GLMessage::DataType::INT);
+ arg_pipelines->add_intvalue((int)pipelines);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGenProgramPipelinesEXT(n, pipelines);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsProgramPipelineEXT(GLuint pipeline) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glIsProgramPipelineEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ GLboolean retValue = glContext->hooks->gl.glIsProgramPipelineEXT(pipeline);
+ nsecs_t end_time = systemTime();
+
+ // set return value
+ GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+ rt->set_isarray(false);
+ rt->set_type(GLMessage::DataType::BOOL);
+ rt->add_boolvalue(retValue);
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+
+ return retValue;
+}
+
+void GLTrace_glProgramParameteriEXT(GLuint program, GLenum pname, GLint value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramParameteriEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument pname
+ GLMessage_DataType *arg_pname = glmsg.add_args();
+ arg_pname->set_isarray(false);
+ arg_pname->set_type(GLMessage::DataType::ENUM);
+ arg_pname->add_intvalue((int)pname);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue(value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramParameteriEXT(program, pname, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetProgramPipelineivEXT(GLuint pipeline, GLenum pname, GLint *params) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetProgramPipelineivEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // copy argument pname
+ GLMessage_DataType *arg_pname = glmsg.add_args();
+ arg_pname->set_isarray(false);
+ arg_pname->set_type(GLMessage::DataType::ENUM);
+ arg_pname->add_intvalue((int)pname);
+
+ // copy argument params
+ GLMessage_DataType *arg_params = glmsg.add_args();
+ arg_params->set_isarray(false);
+ arg_params->set_type(GLMessage::DataType::INT);
+ arg_params->add_intvalue((int)params);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetProgramPipelineivEXT(pipeline, pname, params);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform1iEXT(GLuint program, GLint location, GLint x) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform1iEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::INT);
+ arg_x->add_intvalue(x);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform1iEXT(program, location, x);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform2iEXT(GLuint program, GLint location, GLint x, GLint y) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform2iEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::INT);
+ arg_x->add_intvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::INT);
+ arg_y->add_intvalue(y);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform2iEXT(program, location, x, y);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform3iEXT(GLuint program, GLint location, GLint x, GLint y, GLint z) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform3iEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::INT);
+ arg_x->add_intvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::INT);
+ arg_y->add_intvalue(y);
+
+ // copy argument z
+ GLMessage_DataType *arg_z = glmsg.add_args();
+ arg_z->set_isarray(false);
+ arg_z->set_type(GLMessage::DataType::INT);
+ arg_z->add_intvalue(z);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform3iEXT(program, location, x, y, z);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform4iEXT(GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform4iEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::INT);
+ arg_x->add_intvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::INT);
+ arg_y->add_intvalue(y);
+
+ // copy argument z
+ GLMessage_DataType *arg_z = glmsg.add_args();
+ arg_z->set_isarray(false);
+ arg_z->set_type(GLMessage::DataType::INT);
+ arg_z->add_intvalue(z);
+
+ // copy argument w
+ GLMessage_DataType *arg_w = glmsg.add_args();
+ arg_w->set_isarray(false);
+ arg_w->set_type(GLMessage::DataType::INT);
+ arg_w->add_intvalue(w);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform4iEXT(program, location, x, y, z, w);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform1fEXT(GLuint program, GLint location, GLfloat x) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform1fEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::FLOAT);
+ arg_x->add_floatvalue(x);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform1fEXT(program, location, x);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform2fEXT(GLuint program, GLint location, GLfloat x, GLfloat y) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform2fEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::FLOAT);
+ arg_x->add_floatvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::FLOAT);
+ arg_y->add_floatvalue(y);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform2fEXT(program, location, x, y);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform3fEXT(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform3fEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::FLOAT);
+ arg_x->add_floatvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::FLOAT);
+ arg_y->add_floatvalue(y);
+
+ // copy argument z
+ GLMessage_DataType *arg_z = glmsg.add_args();
+ arg_z->set_isarray(false);
+ arg_z->set_type(GLMessage::DataType::FLOAT);
+ arg_z->add_floatvalue(z);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform3fEXT(program, location, x, y, z);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform4fEXT(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform4fEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument x
+ GLMessage_DataType *arg_x = glmsg.add_args();
+ arg_x->set_isarray(false);
+ arg_x->set_type(GLMessage::DataType::FLOAT);
+ arg_x->add_floatvalue(x);
+
+ // copy argument y
+ GLMessage_DataType *arg_y = glmsg.add_args();
+ arg_y->set_isarray(false);
+ arg_y->set_type(GLMessage::DataType::FLOAT);
+ arg_y->add_floatvalue(y);
+
+ // copy argument z
+ GLMessage_DataType *arg_z = glmsg.add_args();
+ arg_z->set_isarray(false);
+ arg_z->set_type(GLMessage::DataType::FLOAT);
+ arg_z->add_floatvalue(z);
+
+ // copy argument w
+ GLMessage_DataType *arg_w = glmsg.add_args();
+ arg_w->set_isarray(false);
+ arg_w->set_type(GLMessage::DataType::FLOAT);
+ arg_w->add_floatvalue(w);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform4fEXT(program, location, x, y, z, w);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform1ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform1ivEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform1ivEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform2ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform2ivEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform2ivEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform3ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform3ivEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform3ivEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform4ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform4ivEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform4ivEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform1fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform1fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform1fvEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform2fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform2fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform2fvEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform3fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform3fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform3fvEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniform4fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniform4fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniform4fvEXT(program, location, count, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniformMatrix2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniformMatrix2fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument transpose
+ GLMessage_DataType *arg_transpose = glmsg.add_args();
+ arg_transpose->set_isarray(false);
+ arg_transpose->set_type(GLMessage::DataType::BOOL);
+ arg_transpose->add_boolvalue(transpose);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniformMatrix2fvEXT(program, location, count, transpose, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniformMatrix3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniformMatrix3fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument transpose
+ GLMessage_DataType *arg_transpose = glmsg.add_args();
+ arg_transpose->set_isarray(false);
+ arg_transpose->set_type(GLMessage::DataType::BOOL);
+ arg_transpose->add_boolvalue(transpose);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniformMatrix3fvEXT(program, location, count, transpose, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramUniformMatrix4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glProgramUniformMatrix4fvEXT);
+
+ // copy argument program
+ GLMessage_DataType *arg_program = glmsg.add_args();
+ arg_program->set_isarray(false);
+ arg_program->set_type(GLMessage::DataType::INT);
+ arg_program->add_intvalue(program);
+
+ // copy argument location
+ GLMessage_DataType *arg_location = glmsg.add_args();
+ arg_location->set_isarray(false);
+ arg_location->set_type(GLMessage::DataType::INT);
+ arg_location->add_intvalue(location);
+
+ // copy argument count
+ GLMessage_DataType *arg_count = glmsg.add_args();
+ arg_count->set_isarray(false);
+ arg_count->set_type(GLMessage::DataType::INT);
+ arg_count->add_intvalue(count);
+
+ // copy argument transpose
+ GLMessage_DataType *arg_transpose = glmsg.add_args();
+ arg_transpose->set_isarray(false);
+ arg_transpose->set_type(GLMessage::DataType::BOOL);
+ arg_transpose->add_boolvalue(transpose);
+
+ // copy argument value
+ GLMessage_DataType *arg_value = glmsg.add_args();
+ arg_value->set_isarray(false);
+ arg_value->set_type(GLMessage::DataType::INT);
+ arg_value->add_intvalue((int)value);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glProgramUniformMatrix4fvEXT(program, location, count, transpose, value);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glValidateProgramPipelineEXT(GLuint pipeline) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glValidateProgramPipelineEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glValidateProgramPipelineEXT(pipeline);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetProgramPipelineInfoLogEXT(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glGetProgramPipelineInfoLogEXT);
+
+ // copy argument pipeline
+ GLMessage_DataType *arg_pipeline = glmsg.add_args();
+ arg_pipeline->set_isarray(false);
+ arg_pipeline->set_type(GLMessage::DataType::INT);
+ arg_pipeline->add_intvalue(pipeline);
+
+ // copy argument bufSize
+ GLMessage_DataType *arg_bufSize = glmsg.add_args();
+ arg_bufSize->set_isarray(false);
+ arg_bufSize->set_type(GLMessage::DataType::INT);
+ arg_bufSize->add_intvalue(bufSize);
+
+ // copy argument length
+ GLMessage_DataType *arg_length = glmsg.add_args();
+ arg_length->set_isarray(false);
+ arg_length->set_type(GLMessage::DataType::INT);
+ arg_length->add_intvalue((int)length);
+
+ // copy argument infoLog
+ GLMessage_DataType *arg_infoLog = glmsg.add_args();
+ arg_infoLog->set_isarray(false);
+ arg_infoLog->set_type(GLMessage::DataType::INT);
+ arg_infoLog->add_intvalue((int)infoLog);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glGetProgramPipelineInfoLogEXT(pipeline, bufSize, length, infoLog);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexStorage1DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glTexStorage1DEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument levels
+ GLMessage_DataType *arg_levels = glmsg.add_args();
+ arg_levels->set_isarray(false);
+ arg_levels->set_type(GLMessage::DataType::INT);
+ arg_levels->add_intvalue(levels);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glTexStorage1DEXT(target, levels, internalformat, width);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glTexStorage2DEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument levels
+ GLMessage_DataType *arg_levels = glmsg.add_args();
+ arg_levels->set_isarray(false);
+ arg_levels->set_type(GLMessage::DataType::INT);
+ arg_levels->add_intvalue(levels);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glTexStorage2DEXT(target, levels, internalformat, width, height);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexStorage3DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glTexStorage3DEXT);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument levels
+ GLMessage_DataType *arg_levels = glmsg.add_args();
+ arg_levels->set_isarray(false);
+ arg_levels->set_type(GLMessage::DataType::INT);
+ arg_levels->add_intvalue(levels);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // copy argument depth
+ GLMessage_DataType *arg_depth = glmsg.add_args();
+ arg_depth->set_isarray(false);
+ arg_depth->set_type(GLMessage::DataType::INT);
+ arg_depth->add_intvalue(depth);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glTexStorage3DEXT(target, levels, internalformat, width, height, depth);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glTextureStorage1DEXT);
+
+ // copy argument texture
+ GLMessage_DataType *arg_texture = glmsg.add_args();
+ arg_texture->set_isarray(false);
+ arg_texture->set_type(GLMessage::DataType::INT);
+ arg_texture->add_intvalue(texture);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument levels
+ GLMessage_DataType *arg_levels = glmsg.add_args();
+ arg_levels->set_isarray(false);
+ arg_levels->set_type(GLMessage::DataType::INT);
+ arg_levels->add_intvalue(levels);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glTextureStorage1DEXT(texture, target, levels, internalformat, width);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glTextureStorage2DEXT);
+
+ // copy argument texture
+ GLMessage_DataType *arg_texture = glmsg.add_args();
+ arg_texture->set_isarray(false);
+ arg_texture->set_type(GLMessage::DataType::INT);
+ arg_texture->add_intvalue(texture);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument levels
+ GLMessage_DataType *arg_levels = glmsg.add_args();
+ arg_levels->set_isarray(false);
+ arg_levels->set_type(GLMessage::DataType::INT);
+ arg_levels->add_intvalue(levels);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glTextureStorage2DEXT(texture, target, levels, internalformat, width, height);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glTextureStorage3DEXT);
+
+ // copy argument texture
+ GLMessage_DataType *arg_texture = glmsg.add_args();
+ arg_texture->set_isarray(false);
+ arg_texture->set_type(GLMessage::DataType::INT);
+ arg_texture->add_intvalue(texture);
+
+ // copy argument target
+ GLMessage_DataType *arg_target = glmsg.add_args();
+ arg_target->set_isarray(false);
+ arg_target->set_type(GLMessage::DataType::ENUM);
+ arg_target->add_intvalue((int)target);
+
+ // copy argument levels
+ GLMessage_DataType *arg_levels = glmsg.add_args();
+ arg_levels->set_isarray(false);
+ arg_levels->set_type(GLMessage::DataType::INT);
+ arg_levels->add_intvalue(levels);
+
+ // copy argument internalformat
+ GLMessage_DataType *arg_internalformat = glmsg.add_args();
+ arg_internalformat->set_isarray(false);
+ arg_internalformat->set_type(GLMessage::DataType::ENUM);
+ arg_internalformat->add_intvalue((int)internalformat);
+
+ // copy argument width
+ GLMessage_DataType *arg_width = glmsg.add_args();
+ arg_width->set_isarray(false);
+ arg_width->set_type(GLMessage::DataType::INT);
+ arg_width->add_intvalue(width);
+
+ // copy argument height
+ GLMessage_DataType *arg_height = glmsg.add_args();
+ arg_height->set_isarray(false);
+ arg_height->set_type(GLMessage::DataType::INT);
+ arg_height->add_intvalue(height);
+
+ // copy argument depth
+ GLMessage_DataType *arg_depth = glmsg.add_args();
+ arg_depth->set_isarray(false);
+ arg_depth->set_type(GLMessage::DataType::INT);
+ arg_depth->add_intvalue(depth);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glTextureStorage3DEXT(texture, target, levels, internalformat, width, height, depth);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
void GLTrace_glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
GLMessage glmsg;
GLTraceContext *glContext = getGLTraceContext();
@@ -6022,6 +8214,75 @@ void GLTrace_glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachme
glContext->traceGLMessage(&glmsg);
}
+void GLTrace_glCoverageMaskNV(GLboolean mask) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glCoverageMaskNV);
+
+ // copy argument mask
+ GLMessage_DataType *arg_mask = glmsg.add_args();
+ arg_mask->set_isarray(false);
+ arg_mask->set_type(GLMessage::DataType::BOOL);
+ arg_mask->add_boolvalue(mask);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glCoverageMaskNV(mask);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCoverageOperationNV(GLenum operation) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glCoverageOperationNV);
+
+ // copy argument operation
+ GLMessage_DataType *arg_operation = glmsg.add_args();
+ arg_operation->set_isarray(false);
+ arg_operation->set_type(GLMessage::DataType::ENUM);
+ arg_operation->add_intvalue((int)operation);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glCoverageOperationNV(operation);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawBuffersNV(GLsizei n, const GLenum *bufs) {
+ GLMessage glmsg;
+ GLTraceContext *glContext = getGLTraceContext();
+
+ glmsg.set_function(GLMessage::glDrawBuffersNV);
+
+ // copy argument n
+ GLMessage_DataType *arg_n = glmsg.add_args();
+ arg_n->set_isarray(false);
+ arg_n->set_type(GLMessage::DataType::INT);
+ arg_n->add_intvalue(n);
+
+ // copy argument bufs
+ GLMessage_DataType *arg_bufs = glmsg.add_args();
+ arg_bufs->set_isarray(false);
+ arg_bufs->set_type(GLMessage::DataType::INT);
+ arg_bufs->add_intvalue((int)bufs);
+
+ // call function
+ nsecs_t start_time = systemTime();
+ glContext->hooks->gl.glDrawBuffersNV(n, bufs);
+ nsecs_t end_time = systemTime();
+
+ fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ glContext->traceGLMessage(&glmsg);
+}
+
void GLTrace_glDeleteFencesNV(GLsizei n, const GLuint *fences) {
GLMessage glmsg;
GLTraceContext *glContext = getGLTraceContext();
@@ -6215,42 +8476,48 @@ void GLTrace_glSetFenceNV(GLuint fence, GLenum condition) {
glContext->traceGLMessage(&glmsg);
}
-void GLTrace_glCoverageMaskNV(GLboolean mask) {
+void GLTrace_glReadBufferNV(GLenum mode) {
GLMessage glmsg;
GLTraceContext *glContext = getGLTraceContext();
- glmsg.set_function(GLMessage::glCoverageMaskNV);
+ glmsg.set_function(GLMessage::glReadBufferNV);
- // copy argument mask
- GLMessage_DataType *arg_mask = glmsg.add_args();
- arg_mask->set_isarray(false);
- arg_mask->set_type(GLMessage::DataType::BOOL);
- arg_mask->add_boolvalue(mask);
+ // copy argument mode
+ GLMessage_DataType *arg_mode = glmsg.add_args();
+ arg_mode->set_isarray(false);
+ arg_mode->set_type(GLMessage::DataType::ENUM);
+ arg_mode->add_intvalue((int)mode);
// call function
nsecs_t start_time = systemTime();
- glContext->hooks->gl.glCoverageMaskNV(mask);
+ glContext->hooks->gl.glReadBufferNV(mode);
nsecs_t end_time = systemTime();
fixupGLMessage(glContext, start_time, end_time, &glmsg);
glContext->traceGLMessage(&glmsg);
}
-void GLTrace_glCoverageOperationNV(GLenum operation) {
+void GLTrace_glAlphaFuncQCOM(GLenum func, GLclampf ref) {
GLMessage glmsg;
GLTraceContext *glContext = getGLTraceContext();
- glmsg.set_function(GLMessage::glCoverageOperationNV);
+ glmsg.set_function(GLMessage::glAlphaFuncQCOM);
- // copy argument operation
- GLMessage_DataType *arg_operation = glmsg.add_args();
- arg_operation->set_isarray(false);
- arg_operation->set_type(GLMessage::DataType::ENUM);
- arg_operation->add_intvalue((int)operation);
+ // copy argument func
+ GLMessage_DataType *arg_func = glmsg.add_args();
+ arg_func->set_isarray(false);
+ arg_func->set_type(GLMessage::DataType::ENUM);
+ arg_func->add_intvalue((int)func);
+
+ // copy argument ref
+ GLMessage_DataType *arg_ref = glmsg.add_args();
+ arg_ref->set_isarray(false);
+ arg_ref->set_type(GLMessage::DataType::FLOAT);
+ arg_ref->add_floatvalue(ref);
// call function
nsecs_t start_time = systemTime();
- glContext->hooks->gl.glCoverageOperationNV(operation);
+ glContext->hooks->gl.glAlphaFuncQCOM(func, ref);
nsecs_t end_time = systemTime();
fixupGLMessage(glContext, start_time, end_time, &glmsg);
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.h b/opengl/libs/GLES_trace/src/gltrace_api.h
index 71b5a5849f7d..debcac0ac4d4 100644
--- a/opengl/libs/GLES_trace/src/gltrace_api.h
+++ b/opengl/libs/GLES_trace/src/gltrace_api.h
@@ -194,11 +194,72 @@ void GLTrace_glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GL
void GLTrace_glBeginPerfMonitorAMD(GLuint monitor);
void GLTrace_glEndPerfMonitorAMD(GLuint monitor);
void GLTrace_glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+void GLTrace_glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+void GLTrace_glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glRenderbufferStorageMultisampleAPPLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glResolveMultisampleFramebufferAPPLE(void);
+void GLTrace_glLabelObjectEXT(GLenum type, GLuint object, GLsizei length, const GLchar *label);
+void GLTrace_glGetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+void GLTrace_glInsertEventMarkerEXT(GLsizei length, const GLchar *marker);
+void GLTrace_glPushGroupMarkerEXT(GLsizei length, const GLchar *marker);
+void GLTrace_glPopGroupMarkerEXT(void);
void GLTrace_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments);
+void GLTrace_glRenderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glFramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
void GLTrace_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
void GLTrace_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+void GLTrace_glGenQueriesEXT(GLsizei n, GLuint *ids);
+void GLTrace_glDeleteQueriesEXT(GLsizei n, const GLuint *ids);
+GLboolean GLTrace_glIsQueryEXT(GLuint id);
+void GLTrace_glBeginQueryEXT(GLenum target, GLuint id);
+void GLTrace_glEndQueryEXT(GLenum target);
+void GLTrace_glGetQueryivEXT(GLenum target, GLenum pname, GLint *params);
+void GLTrace_glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params);
+GLenum GLTrace_glGetGraphicsResetStatusEXT(void);
+void GLTrace_glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data);
+void GLTrace_glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, float *params);
+void GLTrace_glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params);
+void GLTrace_glUseProgramStagesEXT(GLuint pipeline, GLbitfield stages, GLuint program);
+void GLTrace_glActiveShaderProgramEXT(GLuint pipeline, GLuint program);
+GLuint GLTrace_glCreateShaderProgramvEXT(GLenum type, GLsizei count, const GLchar **strings);
+void GLTrace_glBindProgramPipelineEXT(GLuint pipeline);
+void GLTrace_glDeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines);
+void GLTrace_glGenProgramPipelinesEXT(GLsizei n, GLuint *pipelines);
+GLboolean GLTrace_glIsProgramPipelineEXT(GLuint pipeline);
+void GLTrace_glProgramParameteriEXT(GLuint program, GLenum pname, GLint value);
+void GLTrace_glGetProgramPipelineivEXT(GLuint pipeline, GLenum pname, GLint *params);
+void GLTrace_glProgramUniform1iEXT(GLuint program, GLint location, GLint x);
+void GLTrace_glProgramUniform2iEXT(GLuint program, GLint location, GLint x, GLint y);
+void GLTrace_glProgramUniform3iEXT(GLuint program, GLint location, GLint x, GLint y, GLint z);
+void GLTrace_glProgramUniform4iEXT(GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w);
+void GLTrace_glProgramUniform1fEXT(GLuint program, GLint location, GLfloat x);
+void GLTrace_glProgramUniform2fEXT(GLuint program, GLint location, GLfloat x, GLfloat y);
+void GLTrace_glProgramUniform3fEXT(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z);
+void GLTrace_glProgramUniform4fEXT(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void GLTrace_glProgramUniform1ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value);
+void GLTrace_glProgramUniform2ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value);
+void GLTrace_glProgramUniform3ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value);
+void GLTrace_glProgramUniform4ivEXT(GLuint program, GLint location, GLsizei count, const GLint *value);
+void GLTrace_glProgramUniform1fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+void GLTrace_glProgramUniform2fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+void GLTrace_glProgramUniform3fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+void GLTrace_glProgramUniform4fvEXT(GLuint program, GLint location, GLsizei count, const GLfloat *value);
+void GLTrace_glProgramUniformMatrix2fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+void GLTrace_glProgramUniformMatrix3fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+void GLTrace_glProgramUniformMatrix4fvEXT(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+void GLTrace_glValidateProgramPipelineEXT(GLuint pipeline);
+void GLTrace_glGetProgramPipelineInfoLogEXT(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+void GLTrace_glTexStorage1DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+void GLTrace_glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glTexStorage3DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+void GLTrace_glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
+void GLTrace_glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
void GLTrace_glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
void GLTrace_glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+void GLTrace_glCoverageMaskNV(GLboolean mask);
+void GLTrace_glCoverageOperationNV(GLenum operation);
+void GLTrace_glDrawBuffersNV(GLsizei n, const GLenum *bufs);
void GLTrace_glDeleteFencesNV(GLsizei n, const GLuint *fences);
void GLTrace_glGenFencesNV(GLsizei n, GLuint *fences);
GLboolean GLTrace_glIsFenceNV(GLuint fence);
@@ -206,8 +267,8 @@ GLboolean GLTrace_glTestFenceNV(GLuint fence);
void GLTrace_glGetFenceivNV(GLuint fence, GLenum pname, GLint *params);
void GLTrace_glFinishFenceNV(GLuint fence);
void GLTrace_glSetFenceNV(GLuint fence, GLenum condition);
-void GLTrace_glCoverageMaskNV(GLboolean mask);
-void GLTrace_glCoverageOperationNV(GLenum operation);
+void GLTrace_glReadBufferNV(GLenum mode);
+void GLTrace_glAlphaFuncQCOM(GLenum func, GLclampf ref);
void GLTrace_glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls);
void GLTrace_glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
void GLTrace_glEnableDriverControlQCOM(GLuint driverControl);
diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
index c237d75fcd4f..c442153794a3 100644
--- a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
@@ -77,12 +77,10 @@ static void *commandReceiveTask(void *arg) {
}
void GLTrace_start() {
- char value[PROPERTY_VALUE_MAX];
+ char udsName[PROPERTY_VALUE_MAX];
- property_get("debug.egl.debug_port", value, "5039");
- const unsigned short port = (unsigned short)atoi(value);
-
- int clientSocket = gltrace::acceptClientConnection(port);
+ property_get("debug.egl.debug_portname", udsName, "gltrace");
+ int clientSocket = gltrace::acceptClientConnection(udsName);
if (clientSocket < 0) {
ALOGE("Error creating GLTrace server socket. Quitting application.");
exit(-1);
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index daba3ff53082..871b5dc720b8 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -358,6 +358,14 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessa
fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB);
}
break;
+ case GLMessage::glPushGroupMarkerEXT:
+ /* void PushGroupMarkerEXT(sizei length, const char *marker); */
+ fixup_CStringPtr(1, glmsg);
+ break;
+ case GLMessage::glInsertEventMarkerEXT:
+ /* void InsertEventMarkerEXT(sizei length, const char *marker); */
+ fixup_CStringPtr(1, glmsg);
+ break;
default:
break;
}
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.cpp b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
index ce3fae59a11e..5251b12ce009 100644
--- a/opengl/libs/GLES_trace/src/gltrace_transport.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
@@ -17,9 +17,10 @@
#include <stdlib.h>
#include <unistd.h>
+#include <unistd.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netinet/in.h>
-#include <arpa/inet.h>
#include <cutils/log.h>
@@ -28,22 +29,24 @@
namespace android {
namespace gltrace {
-int acceptClientConnection(int serverPort) {
- int serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+int acceptClientConnection(char *sockname) {
+ int serverSocket = socket(AF_LOCAL, SOCK_STREAM, 0);
if (serverSocket < 0) {
ALOGE("Error (%d) while creating socket. Check if app has network permissions.",
serverSocket);
return -1;
}
- struct sockaddr_in server, client;
+ struct sockaddr_un server, client;
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = htonl(INADDR_ANY);
- server.sin_port = htons(serverPort);
+ memset(&server, 0, sizeof server);
+ server.sun_family = AF_UNIX;
+ // the first byte of sun_path should be '\0' for abstract namespace
+ strcpy(server.sun_path + 1, sockname);
- socklen_t sockaddr_len = sizeof(sockaddr_in);
- if (bind(serverSocket, (struct sockaddr *) &server, sizeof(server)) < 0) {
+ // note that sockaddr_len should be set to the exact size of the buffer that is used.
+ socklen_t sockaddr_len = sizeof(server.sun_family) + strlen(sockname) + 1;
+ if (bind(serverSocket, (struct sockaddr *) &server, sockaddr_len) < 0) {
close(serverSocket);
ALOGE("Failed to bind the server socket");
return -1;
@@ -55,7 +58,7 @@ int acceptClientConnection(int serverPort) {
return -1;
}
- ALOGD("gltrace::waitForClientConnection: server listening @ port %d", serverPort);
+ ALOGD("gltrace::waitForClientConnection: server listening @ path %s", sockname);
int clientSocket = accept(serverSocket, (struct sockaddr *)&client, &sockaddr_len);
if (clientSocket < 0) {
@@ -64,7 +67,7 @@ int acceptClientConnection(int serverPort) {
return -1;
}
- ALOGD("gltrace::waitForClientConnection: client connected: %s", inet_ntoa(client.sin_addr));
+ ALOGD("gltrace::waitForClientConnection: client connected.");
// do not accept any more incoming connections
close(serverSocket);
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.h b/opengl/libs/GLES_trace/src/gltrace_transport.h
index d31df7b73993..36650355a16d 100644
--- a/opengl/libs/GLES_trace/src/gltrace_transport.h
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.h
@@ -76,10 +76,11 @@ public:
};
/**
- * Utility method: start a server at @serverPort, and wait for a client
- * connection. Returns the connected client socket on success, or -1 on failure.
+ * Utility method: start a server listening at @sockName (unix domain socket,
+ * abstract namespace path), and wait for a client connection.
+ * Returns the connected client socket on success, or -1 on failure.
*/
-int acceptClientConnection(int serverPort);
+int acceptClientConnection(char *sockName);
};
};
diff --git a/opengl/libs/GLES_trace/tools/genapi.py b/opengl/libs/GLES_trace/tools/genapi.py
index 9b7a1cfe459c..557e4076dba3 100755
--- a/opengl/libs/GLES_trace/tools/genapi.py
+++ b/opengl/libs/GLES_trace/tools/genapi.py
@@ -26,11 +26,11 @@
# module. The only reason to use pyratemp is that it is extremly
# simple to install:
# $ wget http://www.simple-is-better.org/template/pyratemp-current/pyratemp.py
-# Put the file in the GLES2_trace/tools folder, or update PYTHONPATH
+# Put the file in the GLES_trace/tools folder, or update PYTHONPATH
# to point to wherever it was downloaded.
#
# USAGE
-# $ cd GLES2_trace - run the program from GLES2_trace folder
+# $ cd GLES_trace - run the program from GLES2_trace folder
# $ ./tools/genapi.py - generates a .cpp and .h file
# $ mv *.cpp *.h src/ - move the generated files into the src folder
diff --git a/opengl/libs/GLES_trace/tools/testgenapi.py b/opengl/libs/GLES_trace/tools/testgenapi.py
index 58a12a8e5ad9..fe14954f2fdc 100644
--- a/opengl/libs/GLES_trace/tools/testgenapi.py
+++ b/opengl/libs/GLES_trace/tools/testgenapi.py
@@ -15,7 +15,7 @@
# limitations under the License.
#
# USAGE
-# $ cd GLES2_trace/tools
+# $ cd GLES_trace/tools
# $ python testgenapi.py
import unittest
@@ -45,9 +45,9 @@ class TestApiCall(unittest.TestCase):
glext_apis = getApis('../../GLES_CM/glext_api.in', 'GL1Ext')
self.assertEqual(len(gl2_apis), 142)
- self.assertEqual(len(gl2ext_apis), 60)
+ self.assertEqual(len(gl2ext_apis), 121)
self.assertEqual(len(gl_apis), 145)
- self.assertEqual(len(glext_apis), 126)
+ self.assertEqual(len(glext_apis), 140)
def test_parseArgs(self):
args = parseArgs("void")
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index a8093168e079..8ff51eca4b7a 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -29,6 +29,7 @@
namespace android {
// ----------------------------------------------------------------------------
+EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name);
EGLAPI EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image);
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/entries.in b/opengl/libs/entries.in
index 61acb5f09eed..6316d7898325 100644
--- a/opengl/libs/entries.in
+++ b/opengl/libs/entries.in
@@ -1,13 +1,17 @@
+GL_ENTRY(void, glActiveShaderProgramEXT, GLuint pipeline, GLuint program)
GL_ENTRY(void, glActiveTexture, GLenum texture)
GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref)
+GL_ENTRY(void, glAlphaFuncQCOM, GLenum func, GLclampf ref)
GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref)
GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glBeginQueryEXT, GLenum target, GLuint id)
GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name)
GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
+GL_ENTRY(void, glBindProgramPipelineEXT, GLuint pipeline)
GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
@@ -20,6 +24,7 @@ GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha)
GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+GL_ENTRY(void, glBlitFramebufferANGLE, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target)
@@ -58,6 +63,7 @@ GL_ENTRY(void, glCoverageMaskNV, GLboolean mask)
GL_ENTRY(void, glCoverageOperationNV, GLenum operation)
GL_ENTRY(GLuint, glCreateProgram, void)
GL_ENTRY(GLuint, glCreateShader, GLenum type)
+GL_ENTRY(GLuint, glCreateShaderProgramvEXT, GLenum type, GLsizei count, const GLchar **strings)
GL_ENTRY(void, glCullFace, GLenum mode)
GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex)
GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers)
@@ -66,6 +72,8 @@ GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers)
GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers)
GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors)
GL_ENTRY(void, glDeleteProgram, GLuint program)
+GL_ENTRY(void, glDeleteProgramPipelinesEXT, GLsizei n, const GLuint *pipelines)
+GL_ENTRY(void, glDeleteQueriesEXT, GLsizei n, const GLuint *ids)
GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers)
GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers)
GL_ENTRY(void, glDeleteShader, GLuint shader)
@@ -84,6 +92,7 @@ GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl)
GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments)
GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
+GL_ENTRY(void, glDrawBuffersNV, GLsizei n, const GLenum *bufs)
GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords)
@@ -100,6 +109,7 @@ GL_ENTRY(void, glEnableClientState, GLenum array)
GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl)
GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glEndQueryEXT, GLenum target)
GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask)
GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoid **params)
GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
@@ -125,6 +135,7 @@ GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params)
GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glFramebufferTexture2DMultisampleEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
@@ -138,6 +149,8 @@ GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences)
GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers)
GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers)
GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors)
+GL_ENTRY(void, glGenProgramPipelinesEXT, GLsizei n, GLuint *pipelines)
+GL_ENTRY(void, glGenQueriesEXT, GLsizei n, GLuint *ids)
GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers)
GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers)
GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
@@ -164,6 +177,7 @@ GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params)
GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params)
GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params)
GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params)
+GL_ENTRY(GLenum, glGetGraphicsResetStatusEXT, void)
GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params)
GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params)
GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params)
@@ -171,6 +185,7 @@ GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params)
GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params)
GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params)
GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetObjectLabelEXT, GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label)
GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten)
GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, GLvoid *data)
GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString)
@@ -180,7 +195,11 @@ GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize,
GL_ENTRY(void, glGetPointerv, GLenum pname, GLvoid **params)
GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+GL_ENTRY(void, glGetProgramPipelineInfoLogEXT, GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
+GL_ENTRY(void, glGetProgramPipelineivEXT, GLuint pipeline, GLenum pname, GLint *params)
GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetQueryObjectuivEXT, GLuint id, GLenum pname, GLuint *params)
+GL_ENTRY(void, glGetQueryivEXT, GLenum target, GLenum pname, GLint *params)
GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params)
GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params)
GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
@@ -205,18 +224,24 @@ GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params)
GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params)
GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetnUniformfvEXT, GLuint program, GLint location, GLsizei bufSize, float *params)
+GL_ENTRY(void, glGetnUniformivEXT, GLuint program, GLint location, GLsizei bufSize, GLint *params)
GL_ENTRY(void, glHint, GLenum target, GLenum mode)
+GL_ENTRY(void, glInsertEventMarkerEXT, GLsizei length, const GLchar *marker)
GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer)
GL_ENTRY(GLboolean, glIsEnabled, GLenum cap)
GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence)
GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer)
GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer)
GL_ENTRY(GLboolean, glIsProgram, GLuint program)
+GL_ENTRY(GLboolean, glIsProgramPipelineEXT, GLuint pipeline)
+GL_ENTRY(GLboolean, glIsQueryEXT, GLuint id)
GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer)
GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer)
GL_ENTRY(GLboolean, glIsShader, GLuint shader)
GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array)
+GL_ENTRY(void, glLabelObjectEXT, GLenum type, GLuint object, GLsizei length, const GLchar *label)
GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param)
GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params)
GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param)
@@ -278,15 +303,43 @@ GL_ENTRY(void, glPointSizexOES, GLfixed size)
GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units)
+GL_ENTRY(void, glPopGroupMarkerEXT, void)
GL_ENTRY(void, glPopMatrix, void)
GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
+GL_ENTRY(void, glProgramParameteriEXT, GLuint program, GLenum pname, GLint value)
+GL_ENTRY(void, glProgramUniform1fEXT, GLuint program, GLint location, GLfloat x)
+GL_ENTRY(void, glProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
+GL_ENTRY(void, glProgramUniform1iEXT, GLuint program, GLint location, GLint x)
+GL_ENTRY(void, glProgramUniform1ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
+GL_ENTRY(void, glProgramUniform2fEXT, GLuint program, GLint location, GLfloat x, GLfloat y)
+GL_ENTRY(void, glProgramUniform2fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
+GL_ENTRY(void, glProgramUniform2iEXT, GLuint program, GLint location, GLint x, GLint y)
+GL_ENTRY(void, glProgramUniform2ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
+GL_ENTRY(void, glProgramUniform3fEXT, GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glProgramUniform3fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
+GL_ENTRY(void, glProgramUniform3iEXT, GLuint program, GLint location, GLint x, GLint y, GLint z)
+GL_ENTRY(void, glProgramUniform3ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
+GL_ENTRY(void, glProgramUniform4fEXT, GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+GL_ENTRY(void, glProgramUniform4fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
+GL_ENTRY(void, glProgramUniform4iEXT, GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w)
+GL_ENTRY(void, glProgramUniform4ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
+GL_ENTRY(void, glProgramUniformMatrix2fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+GL_ENTRY(void, glProgramUniformMatrix3fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+GL_ENTRY(void, glProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+GL_ENTRY(void, glPushGroupMarkerEXT, GLsizei length, const GLchar *marker)
GL_ENTRY(void, glPushMatrix, void)
GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16])
+GL_ENTRY(void, glReadBufferNV, GLenum mode)
GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+GL_ENTRY(void, glReadnPixelsEXT, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data)
GL_ENTRY(void, glReleaseShaderCompiler, void)
GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageMultisampleANGLE, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageMultisampleAPPLE, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glResolveMultisampleFramebufferAPPLE, void)
GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
@@ -335,8 +388,14 @@ GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param)
GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param)
GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params)
GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexStorage1DEXT, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
+GL_ENTRY(void, glTexStorage2DEXT, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glTexStorage3DEXT, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
+GL_ENTRY(void, glTextureStorage1DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
+GL_ENTRY(void, glTextureStorage2DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glTextureStorage3DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z)
GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z)
GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z)
@@ -361,7 +420,9 @@ GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean tran
GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target)
GL_ENTRY(void, glUseProgram, GLuint program)
+GL_ENTRY(void, glUseProgramStagesEXT, GLuint pipeline, GLbitfield stages, GLuint program)
GL_ENTRY(void, glValidateProgram, GLuint program)
+GL_ENTRY(void, glValidateProgramPipelineEXT, GLuint pipeline)
GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x)
GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values)
GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y)
diff --git a/opengl/libs/enums.in b/opengl/libs/enums.in
index f9752c24ae7e..bfbc8668f760 100644
--- a/opengl/libs/enums.in
+++ b/opengl/libs/enums.in
@@ -1,4 +1,6 @@
GL_ENUM(0x0000,GL_POINTS)
+GL_ENUM(0x00000001,GL_VERTEX_SHADER_BIT_EXT)
+GL_ENUM(0x00000002,GL_FRAGMENT_SHADER_BIT_EXT)
GL_ENUM(0x0001,GL_LINES)
GL_ENUM(0x0002,GL_LINE_LOOP)
GL_ENUM(0x0003,GL_LINE_STRIP)
@@ -92,6 +94,7 @@ GL_ENUM(0x0BE1,GL_BLEND_SRC)
GL_ENUM(0x0BE2,GL_BLEND)
GL_ENUM(0x0BF0,GL_LOGIC_OP_MODE)
GL_ENUM(0x0BF2,GL_COLOR_LOGIC_OP)
+GL_ENUM(0x0C02,GL_READ_BUFFER_NV)
GL_ENUM(0x0C10,GL_SCISSOR_BOX)
GL_ENUM(0x0C11,GL_SCISSOR_TEST)
GL_ENUM(0x0C22,GL_COLOR_CLEAR_VALUE)
@@ -100,6 +103,9 @@ GL_ENUM(0x0C50,GL_PERSPECTIVE_CORRECTION_HINT)
GL_ENUM(0x0C51,GL_POINT_SMOOTH_HINT)
GL_ENUM(0x0C52,GL_LINE_SMOOTH_HINT)
GL_ENUM(0x0C54,GL_FOG_HINT)
+GL_ENUM(0x0CF2,GL_UNPACK_ROW_LENGTH)
+GL_ENUM(0x0CF3,GL_UNPACK_SKIP_ROWS)
+GL_ENUM(0x0CF4,GL_UNPACK_SKIP_PIXELS)
GL_ENUM(0x0CF5,GL_UNPACK_ALIGNMENT)
GL_ENUM(0x0D05,GL_PACK_ALIGNMENT)
GL_ENUM(0x0D1C,GL_ALPHA_SCALE)
@@ -166,6 +172,7 @@ GL_ENUM(0x1801,GL_DEPTH_EXT)
GL_ENUM(0x1802,GL_STENCIL_EXT)
GL_ENUM(0x1901,GL_STENCIL_INDEX)
GL_ENUM(0x1902,GL_DEPTH_COMPONENT)
+GL_ENUM(0x1903,GL_RED_EXT)
GL_ENUM(0x1906,GL_ALPHA)
GL_ENUM(0x1907,GL_RGB)
GL_ENUM(0x1908,GL_RGBA)
@@ -230,10 +237,15 @@ GL_ENUM(0x8034,GL_UNSIGNED_SHORT_5_5_5_1)
GL_ENUM(0x8037,GL_POLYGON_OFFSET_FILL)
GL_ENUM(0x8038,GL_POLYGON_OFFSET_FACTOR)
GL_ENUM(0x803A,GL_RESCALE_NORMAL)
+GL_ENUM(0x803C,GL_ALPHA8_EXT)
+GL_ENUM(0x8040,GL_LUMINANCE8_EXT)
+GL_ENUM(0x8045,GL_LUMINANCE8_ALPHA8_EXT)
GL_ENUM(0x8051,GL_RGB8_OES)
+GL_ENUM(0x8052,GL_RGB10_EXT)
GL_ENUM(0x8056,GL_RGBA4_OES)
GL_ENUM(0x8057,GL_RGB5_A1_OES)
GL_ENUM(0x8058,GL_RGBA8_OES)
+GL_ENUM(0x8059,GL_RGB10_A2_EXT)
GL_ENUM(0x8069,GL_TEXTURE_BINDING_2D)
GL_ENUM(0x806A,GL_TEXTURE_BINDING_3D_OES)
GL_ENUM(0x806F,GL_TEXTURE_3D_OES)
@@ -276,11 +288,28 @@ GL_ENUM(0x8127,GL_POINT_SIZE_MAX)
GL_ENUM(0x8128,GL_POINT_FADE_THRESHOLD_SIZE)
GL_ENUM(0x8129,GL_POINT_DISTANCE_ATTENUATION)
GL_ENUM(0x812F,GL_CLAMP_TO_EDGE)
+GL_ENUM(0x813D,GL_TEXTURE_MAX_LEVEL_APPLE)
GL_ENUM(0x8191,GL_GENERATE_MIPMAP)
GL_ENUM(0x8192,GL_GENERATE_MIPMAP_HINT)
GL_ENUM(0x81A5,GL_DEPTH_COMPONENT16_OES)
GL_ENUM(0x81A6,GL_DEPTH_COMPONENT24_OES)
GL_ENUM(0x81A7,GL_DEPTH_COMPONENT32_OES)
+GL_ENUM(0x8210,GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)
+GL_ENUM(0x8211,GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT)
+GL_ENUM(0x8227,GL_RG_EXT)
+GL_ENUM(0x8229,GL_R8_EXT)
+GL_ENUM(0x822B,GL_RG8_EXT)
+GL_ENUM(0x822D,GL_R16F_EXT)
+GL_ENUM(0x822F,GL_RG16F_EXT)
+GL_ENUM(0x8252,GL_LOSE_CONTEXT_ON_RESET_EXT)
+GL_ENUM(0x8253,GL_GUILTY_CONTEXT_RESET_EXT)
+GL_ENUM(0x8254,GL_INNOCENT_CONTEXT_RESET_EXT)
+GL_ENUM(0x8255,GL_UNKNOWN_CONTEXT_RESET_EXT)
+GL_ENUM(0x8256,GL_RESET_NOTIFICATION_STRATEGY_EXT)
+GL_ENUM(0x8258,GL_PROGRAM_SEPARABLE_EXT)
+GL_ENUM(0x8259,GL_ACTIVE_PROGRAM_EXT)
+GL_ENUM(0x825A,GL_PROGRAM_PIPELINE_BINDING_EXT)
+GL_ENUM(0x8261,GL_NO_RESET_NOTIFICATION_EXT)
GL_ENUM(0x8363,GL_UNSIGNED_SHORT_5_6_5)
GL_ENUM(0x8365,GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT)
GL_ENUM(0x8366,GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
@@ -372,6 +401,8 @@ GL_ENUM(0x8598,GL_OPERAND0_ALPHA)
GL_ENUM(0x8599,GL_OPERAND1_ALPHA)
GL_ENUM(0x859A,GL_OPERAND2_ALPHA)
GL_ENUM(0x85B5,GL_VERTEX_ARRAY_BINDING_OES)
+GL_ENUM(0x85BA,GL_UNSIGNED_SHORT_8_8_APPLE)
+GL_ENUM(0x85BB,GL_UNSIGNED_SHORT_8_8_REV_APPLE)
GL_ENUM(0x8622,GL_VERTEX_ATTRIB_ARRAY_ENABLED)
GL_ENUM(0x8623,GL_VERTEX_ATTRIB_ARRAY_SIZE)
GL_ENUM(0x8624,GL_VERTEX_ATTRIB_ARRAY_STRIDE)
@@ -401,7 +432,34 @@ GL_ENUM(0x8800,GL_STENCIL_BACK_FUNC)
GL_ENUM(0x8801,GL_STENCIL_BACK_FAIL)
GL_ENUM(0x8802,GL_STENCIL_BACK_PASS_DEPTH_FAIL)
GL_ENUM(0x8803,GL_STENCIL_BACK_PASS_DEPTH_PASS)
+GL_ENUM(0x8814,GL_RGBA32F_EXT)
+GL_ENUM(0x8815,GL_RGB32F_EXT)
+GL_ENUM(0x8816,GL_ALPHA32F_EXT)
+GL_ENUM(0x8818,GL_LUMINANCE32F_EXT)
+GL_ENUM(0x8819,GL_LUMINANCE_ALPHA32F_EXT)
+GL_ENUM(0x881A,GL_RGBA16F_EXT)
+GL_ENUM(0x881B,GL_RGB16F_EXT)
+GL_ENUM(0x881C,GL_ALPHA16F_EXT)
+GL_ENUM(0x881E,GL_LUMINANCE16F_EXT)
+GL_ENUM(0x881F,GL_LUMINANCE_ALPHA16F_EXT)
GL_ENUM(0x8823,GL_WRITEONLY_RENDERING_QCOM)
+GL_ENUM(0x8824,GL_MAX_DRAW_BUFFERS_NV)
+GL_ENUM(0x8825,GL_DRAW_BUFFER0_NV)
+GL_ENUM(0x8826,GL_DRAW_BUFFER1_NV)
+GL_ENUM(0x8827,GL_DRAW_BUFFER2_NV)
+GL_ENUM(0x8828,GL_DRAW_BUFFER3_NV)
+GL_ENUM(0x8829,GL_DRAW_BUFFER4_NV)
+GL_ENUM(0x882A,GL_DRAW_BUFFER5_NV)
+GL_ENUM(0x882B,GL_DRAW_BUFFER6_NV)
+GL_ENUM(0x882C,GL_DRAW_BUFFER7_NV)
+GL_ENUM(0x882D,GL_DRAW_BUFFER8_NV)
+GL_ENUM(0x882E,GL_DRAW_BUFFER9_NV)
+GL_ENUM(0x882F,GL_DRAW_BUFFER10_NV)
+GL_ENUM(0x8830,GL_DRAW_BUFFER11_NV)
+GL_ENUM(0x8831,GL_DRAW_BUFFER12_NV)
+GL_ENUM(0x8832,GL_DRAW_BUFFER13_NV)
+GL_ENUM(0x8833,GL_DRAW_BUFFER14_NV)
+GL_ENUM(0x8834,GL_DRAW_BUFFER15_NV)
GL_ENUM(0x883D,GL_BLEND_EQUATION_ALPHA_OES)
GL_ENUM(0x8840,GL_MATRIX_PALETTE_OES)
GL_ENUM(0x8842,GL_MAX_PALETTE_MATRICES_OES)
@@ -411,8 +469,14 @@ GL_ENUM(0x8846,GL_MATRIX_INDEX_ARRAY_SIZE_OES)
GL_ENUM(0x8847,GL_MATRIX_INDEX_ARRAY_TYPE_OES)
GL_ENUM(0x8848,GL_MATRIX_INDEX_ARRAY_STRIDE_OES)
GL_ENUM(0x8849,GL_MATRIX_INDEX_ARRAY_POINTER_OES)
+GL_ENUM(0x884C,GL_TEXTURE_COMPARE_MODE_EXT)
+GL_ENUM(0x884D,GL_TEXTURE_COMPARE_FUNC_EXT)
+GL_ENUM(0x884E,GL_COMPARE_REF_TO_TEXTURE_EXT)
GL_ENUM(0x8861,GL_POINT_SPRITE_OES)
GL_ENUM(0x8862,GL_COORD_REPLACE_OES)
+GL_ENUM(0x8865,GL_CURRENT_QUERY_EXT)
+GL_ENUM(0x8866,GL_QUERY_RESULT_EXT)
+GL_ENUM(0x8867,GL_QUERY_RESULT_AVAILABLE_EXT)
GL_ENUM(0x8869,GL_MAX_VERTEX_ATTRIBS)
GL_ENUM(0x886A,GL_VERTEX_ATTRIB_ARRAY_NORMALIZED)
GL_ENUM(0x8872,GL_MAX_TEXTURE_IMAGE_UNITS)
@@ -440,8 +504,12 @@ GL_ENUM(0x898C,GL_POINT_SIZE_ARRAY_POINTER_OES)
GL_ENUM(0x898D,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES)
GL_ENUM(0x898E,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES)
GL_ENUM(0x898F,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES)
+GL_ENUM(0x8A1F,GL_RGB_422_APPLE)
+GL_ENUM(0x8A4F,GL_PROGRAM_PIPELINE_OBJECT_EXT)
GL_ENUM(0x8B30,GL_FRAGMENT_SHADER)
GL_ENUM(0x8B31,GL_VERTEX_SHADER)
+GL_ENUM(0x8B40,GL_PROGRAM_OBJECT_EXT)
+GL_ENUM(0x8B48,GL_SHADER_OBJECT_EXT)
GL_ENUM(0x8B4C,GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
GL_ENUM(0x8B4D,GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
GL_ENUM(0x8B4F,GL_SHADER_TYPE)
@@ -461,6 +529,7 @@ GL_ENUM(0x8B5C,GL_FLOAT_MAT4)
GL_ENUM(0x8B5E,GL_SAMPLER_2D)
GL_ENUM(0x8B5F,GL_SAMPLER_3D_OES)
GL_ENUM(0x8B60,GL_SAMPLER_CUBE)
+GL_ENUM(0x8B62,GL_SAMPLER_2D_SHADOW_EXT)
GL_ENUM(0x8B80,GL_DELETE_STATUS)
GL_ENUM(0x8B81,GL_COMPILE_STATUS)
GL_ENUM(0x8B82,GL_LINK_STATUS)
@@ -520,6 +589,11 @@ GL_ENUM(0x8C07,GL_FACTOR_ALPHA_MODULATE_IMG)
GL_ENUM(0x8C08,GL_FRAGMENT_ALPHA_MODULATE_IMG)
GL_ENUM(0x8C09,GL_ADD_BLEND_IMG)
GL_ENUM(0x8C0A,GL_SGX_BINARY_IMG)
+GL_ENUM(0x8C17,GL_UNSIGNED_NORMALIZED_EXT)
+GL_ENUM(0x8C2F,GL_ANY_SAMPLES_PASSED_EXT)
+GL_ENUM(0x8C40,GL_SRGB_EXT)
+GL_ENUM(0x8C42,GL_SRGB_ALPHA_EXT)
+GL_ENUM(0x8C43,GL_SRGB8_ALPHA8_EXT)
GL_ENUM(0x8C92,GL_ATC_RGB_AMD)
GL_ENUM(0x8C93,GL_ATC_RGBA_EXPLICIT_ALPHA_AMD)
GL_ENUM(0x8CA3,GL_STENCIL_BACK_REF)
@@ -527,6 +601,10 @@ GL_ENUM(0x8CA4,GL_STENCIL_BACK_VALUE_MASK)
GL_ENUM(0x8CA5,GL_STENCIL_BACK_WRITEMASK)
GL_ENUM(0x8CA6,GL_FRAMEBUFFER_BINDING_OES)
GL_ENUM(0x8CA7,GL_RENDERBUFFER_BINDING_OES)
+GL_ENUM(0x8CA8,GL_READ_FRAMEBUFFER_APPLE)
+GL_ENUM(0x8CA9,GL_DRAW_FRAMEBUFFER_APPLE)
+GL_ENUM(0x8CAA,GL_READ_FRAMEBUFFER_BINDING_APPLE)
+GL_ENUM(0x8CAB,GL_RENDERBUFFER_SAMPLES_APPLE)
GL_ENUM(0x8CD0,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES)
GL_ENUM(0x8CD1,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES)
GL_ENUM(0x8CD2,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES)
@@ -538,7 +616,23 @@ GL_ENUM(0x8CD7,GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES)
GL_ENUM(0x8CD9,GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES)
GL_ENUM(0x8CDA,GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES)
GL_ENUM(0x8CDD,GL_FRAMEBUFFER_UNSUPPORTED_OES)
+GL_ENUM(0x8CDF,GL_MAX_COLOR_ATTACHMENTS_NV)
GL_ENUM(0x8CE0,GL_COLOR_ATTACHMENT0_OES)
+GL_ENUM(0x8CE1,GL_COLOR_ATTACHMENT1_NV)
+GL_ENUM(0x8CE2,GL_COLOR_ATTACHMENT2_NV)
+GL_ENUM(0x8CE3,GL_COLOR_ATTACHMENT3_NV)
+GL_ENUM(0x8CE4,GL_COLOR_ATTACHMENT4_NV)
+GL_ENUM(0x8CE5,GL_COLOR_ATTACHMENT5_NV)
+GL_ENUM(0x8CE6,GL_COLOR_ATTACHMENT6_NV)
+GL_ENUM(0x8CE7,GL_COLOR_ATTACHMENT7_NV)
+GL_ENUM(0x8CE8,GL_COLOR_ATTACHMENT8_NV)
+GL_ENUM(0x8CE9,GL_COLOR_ATTACHMENT9_NV)
+GL_ENUM(0x8CEA,GL_COLOR_ATTACHMENT10_NV)
+GL_ENUM(0x8CEB,GL_COLOR_ATTACHMENT11_NV)
+GL_ENUM(0x8CEC,GL_COLOR_ATTACHMENT12_NV)
+GL_ENUM(0x8CED,GL_COLOR_ATTACHMENT13_NV)
+GL_ENUM(0x8CEE,GL_COLOR_ATTACHMENT14_NV)
+GL_ENUM(0x8CEF,GL_COLOR_ATTACHMENT15_NV)
GL_ENUM(0x8D00,GL_DEPTH_ATTACHMENT_OES)
GL_ENUM(0x8D20,GL_STENCIL_ATTACHMENT_OES)
GL_ENUM(0x8D40,GL_FRAMEBUFFER_OES)
@@ -555,6 +649,8 @@ GL_ENUM(0x8D52,GL_RENDERBUFFER_BLUE_SIZE_OES)
GL_ENUM(0x8D53,GL_RENDERBUFFER_ALPHA_SIZE_OES)
GL_ENUM(0x8D54,GL_RENDERBUFFER_DEPTH_SIZE_OES)
GL_ENUM(0x8D55,GL_RENDERBUFFER_STENCIL_SIZE_OES)
+GL_ENUM(0x8D56,GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE)
+GL_ENUM(0x8D57,GL_MAX_SAMPLES_APPLE)
GL_ENUM(0x8D60,GL_TEXTURE_GEN_STR_OES)
GL_ENUM(0x8D61,GL_HALF_FLOAT_OES)
GL_ENUM(0x8D62,GL_RGB565_OES)
@@ -563,6 +659,8 @@ GL_ENUM(0x8D65,GL_TEXTURE_EXTERNAL_OES)
GL_ENUM(0x8D66,GL_SAMPLER_EXTERNAL_OES)
GL_ENUM(0x8D67,GL_TEXTURE_BINDING_EXTERNAL_OES)
GL_ENUM(0x8D68,GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES)
+GL_ENUM(0x8D6A,GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT)
+GL_ENUM(0x8D6C,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)
GL_ENUM(0x8DF0,GL_LOW_FLOAT)
GL_ENUM(0x8DF1,GL_MEDIUM_FLOAT)
GL_ENUM(0x8DF2,GL_HIGH_FLOAT)
@@ -586,9 +684,19 @@ GL_ENUM(0x8ED4,GL_COVERAGE_SAMPLES_NV)
GL_ENUM(0x8ED5,GL_COVERAGE_ALL_FRAGMENTS_NV)
GL_ENUM(0x8ED6,GL_COVERAGE_EDGE_FRAGMENTS_NV)
GL_ENUM(0x8ED7,GL_COVERAGE_AUTOMATIC_NV)
+GL_ENUM(0x8F60,GL_MALI_SHADER_BINARY_ARM)
GL_ENUM(0x8FA0,GL_PERFMON_GLOBAL_MODE_QCOM)
+GL_ENUM(0x8FC4,GL_SHADER_BINARY_VIV)
+GL_ENUM(0x90F3,GL_CONTEXT_ROBUST_ACCESS_EXT)
+GL_ENUM(0x912F,GL_TEXTURE_IMMUTABLE_FORMAT_EXT)
GL_ENUM(0x9130,GL_SGX_PROGRAM_BINARY_IMG)
-GL_ENUM(0x9133,GL_RENDERBUFFER_SAMPLES_IMG)
-GL_ENUM(0x9134,GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG)
-GL_ENUM(0x9135,GL_MAX_SAMPLES_IMG)
+GL_ENUM(0x9133,GL_RENDERBUFFER_SAMPLES_EXT)
+GL_ENUM(0x9134,GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT)
+GL_ENUM(0x9135,GL_MAX_SAMPLES_EXT)
GL_ENUM(0x9136,GL_TEXTURE_SAMPLES_IMG)
+GL_ENUM(0x9151,GL_BUFFER_OBJECT_EXT)
+GL_ENUM(0x9153,GL_QUERY_OBJECT_EXT)
+GL_ENUM(0x9154,GL_VERTEX_ARRAY_OBJECT_EXT)
+GL_ENUM(0x9250,GL_SHADER_BINARY_DMP)
+GL_ENUM(0x93A1,GL_BGRA8_EXT)
+GL_ENUM(0xFFFFFFFF,GL_ALL_SHADER_BITS_EXT)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index 7ac88cdb7ed5..8b1b3898f678 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -37,7 +37,12 @@
#endif
#undef NELEM
#define NELEM(x) (sizeof(x)/sizeof(*(x)))
-#define MAX_NUMBER_OF_GL_EXTENSIONS 64
+
+// maximum number of GL extensions that can be used simultaneously in
+// a given process. this limitation exists because we need to have
+// a static function for each extension and currently these static functions
+// are generated at compile time.
+#define MAX_NUMBER_OF_GL_EXTENSIONS 256
#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen
index bd8dda362561..9be40cf67d48 100755
--- a/opengl/libs/tools/glapigen
+++ b/opengl/libs/tools/glapigen
@@ -43,6 +43,9 @@ while (my $line = <>) {
if ($name eq "glEGLImageTargetRenderbufferStorageOES") {
$prefix = "__";
}
+ if ($name eq "glGetString") {
+ $prefix = "__";
+ }
printf("%s API_ENTRY(%s%s)(%s)", $type, $prefix, $name, $args);
diff --git a/opengl/libs/trace.in b/opengl/libs/trace.in
index 3d492af4ee93..a5c5c8438118 100644
--- a/opengl/libs/trace.in
+++ b/opengl/libs/trace.in
@@ -1,13 +1,17 @@
+TRACE_GL_VOID(glActiveShaderProgramEXT, (GLuint pipeline, GLuint program), (pipeline, program), 2, "GLuint", pipeline, "GLuint", program)
TRACE_GL_VOID(glActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture)
TRACE_GL_VOID(glAlphaFunc, (GLenum func, GLclampf ref), (func, ref), 2, "GLenum", func, "GLclampf", ref)
+TRACE_GL_VOID(glAlphaFuncQCOM, (GLenum func, GLclampf ref), (func, ref), 2, "GLenum", func, "GLclampf", ref)
TRACE_GL_VOID(glAlphaFuncx, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref)
TRACE_GL_VOID(glAlphaFuncxOES, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref)
TRACE_GL_VOID(glAttachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader)
TRACE_GL_VOID(glBeginPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor)
+TRACE_GL_VOID(glBeginQueryEXT, (GLenum target, GLuint id), (target, id), 2, "GLenum", target, "GLuint", id)
TRACE_GL_VOID(glBindAttribLocation, (GLuint program, GLuint index, const GLchar* name), (program, index, name), 3, "GLuint", program, "GLuint", index, "const GLchar*", name)
TRACE_GL_VOID(glBindBuffer, (GLenum target, GLuint buffer), (target, buffer), 2, "GLenum", target, "GLuint", buffer)
TRACE_GL_VOID(glBindFramebuffer, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer)
TRACE_GL_VOID(glBindFramebufferOES, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer)
+TRACE_GL_VOID(glBindProgramPipelineEXT, (GLuint pipeline), (pipeline), 1, "GLuint", pipeline)
TRACE_GL_VOID(glBindRenderbuffer, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer)
TRACE_GL_VOID(glBindRenderbufferOES, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer)
TRACE_GL_VOID(glBindTexture, (GLenum target, GLuint texture), (target, texture), 2, "GLenum", target, "GLuint", texture)
@@ -20,6 +24,7 @@ TRACE_GL_VOID(glBlendEquationSeparateOES, (GLenum modeRGB, GLenum modeAlpha), (m
TRACE_GL_VOID(glBlendFunc, (GLenum sfactor, GLenum dfactor), (sfactor, dfactor), 2, "GLenum", sfactor, "GLenum", dfactor)
TRACE_GL_VOID(glBlendFuncSeparate, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha)
TRACE_GL_VOID(glBlendFuncSeparateOES, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha)
+TRACE_GL_VOID(glBlitFramebufferANGLE, (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter), (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter), 10, "GLint", srcX0, "GLint", srcY0, "GLint", srcX1, "GLint", srcY1, "GLint", dstX0, "GLint", dstY0, "GLint", dstX1, "GLint", dstY1, "GLbitfield", mask, "GLenum", filter)
TRACE_GL_VOID(glBufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage), (target, size, data, usage), 4, "GLenum", target, "GLsizeiptr", size, "const GLvoid *", data, "GLenum", usage)
TRACE_GL_VOID(glBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data), (target, offset, size, data), 4, "GLenum", target, "GLintptr", offset, "GLsizeiptr", size, "const GLvoid *", data)
TRACE_GL(GLenum, glCheckFramebufferStatus, (GLenum target), (target), 1, "GLenum", target)
@@ -58,6 +63,7 @@ TRACE_GL_VOID(glCoverageMaskNV, (GLboolean mask), (mask), 1, "GLboolean", mask)
TRACE_GL_VOID(glCoverageOperationNV, (GLenum operation), (operation), 1, "GLenum", operation)
TRACE_GL(GLuint, glCreateProgram, (void), (), 0)
TRACE_GL(GLuint, glCreateShader, (GLenum type), (type), 1, "GLenum", type)
+TRACE_GL(GLuint, glCreateShaderProgramvEXT, (GLenum type, GLsizei count, const GLchar **strings), (type, count, strings), 3, "GLenum", type, "GLsizei", count, "const GLchar **", strings)
TRACE_GL_VOID(glCullFace, (GLenum mode), (mode), 1, "GLenum", mode)
TRACE_GL_VOID(glCurrentPaletteMatrixOES, (GLuint matrixpaletteindex), (matrixpaletteindex), 1, "GLuint", matrixpaletteindex)
TRACE_GL_VOID(glDeleteBuffers, (GLsizei n, const GLuint *buffers), (n, buffers), 2, "GLsizei", n, "const GLuint *", buffers)
@@ -66,6 +72,8 @@ TRACE_GL_VOID(glDeleteFramebuffers, (GLsizei n, const GLuint* framebuffers), (n,
TRACE_GL_VOID(glDeleteFramebuffersOES, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers)
TRACE_GL_VOID(glDeletePerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors)
TRACE_GL_VOID(glDeleteProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glDeleteProgramPipelinesEXT, (GLsizei n, const GLuint *pipelines), (n, pipelines), 2, "GLsizei", n, "const GLuint *", pipelines)
+TRACE_GL_VOID(glDeleteQueriesEXT, (GLsizei n, const GLuint *ids), (n, ids), 2, "GLsizei", n, "const GLuint *", ids)
TRACE_GL_VOID(glDeleteRenderbuffers, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers)
TRACE_GL_VOID(glDeleteRenderbuffersOES, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers)
TRACE_GL_VOID(glDeleteShader, (GLuint shader), (shader), 1, "GLuint", shader)
@@ -84,6 +92,7 @@ TRACE_GL_VOID(glDisableDriverControlQCOM, (GLuint driverControl), (driverControl
TRACE_GL_VOID(glDisableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index)
TRACE_GL_VOID(glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum *attachments), (target, numAttachments, attachments), 3, "GLenum", target, "GLsizei", numAttachments, "const GLenum *", attachments)
TRACE_GL_VOID(glDrawArrays, (GLenum mode, GLint first, GLsizei count), (mode, first, count), 3, "GLenum", mode, "GLint", first, "GLsizei", count)
+TRACE_GL_VOID(glDrawBuffersNV, (GLsizei n, const GLenum *bufs), (n, bufs), 2, "GLsizei", n, "const GLenum *", bufs)
TRACE_GL_VOID(glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices), (mode, count, type, indices), 4, "GLenum", mode, "GLsizei", count, "GLenum", type, "const GLvoid *", indices)
TRACE_GL_VOID(glDrawTexfOES, (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height), (x, y, z, width, height), 5, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", width, "GLfloat", height)
TRACE_GL_VOID(glDrawTexfvOES, (const GLfloat *coords), (coords), 1, "const GLfloat *", coords)
@@ -100,6 +109,7 @@ TRACE_GL_VOID(glEnableClientState, (GLenum array), (array), 1, "GLenum", array)
TRACE_GL_VOID(glEnableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl)
TRACE_GL_VOID(glEnableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index)
TRACE_GL_VOID(glEndPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor)
+TRACE_GL_VOID(glEndQueryEXT, (GLenum target), (target), 1, "GLenum", target)
TRACE_GL_VOID(glEndTilingQCOM, (GLbitfield preserveMask), (preserveMask), 1, "GLbitfield", preserveMask)
TRACE_GL_VOID(glExtGetBufferPointervQCOM, (GLenum target, GLvoid **params), (target, params), 2, "GLenum", target, "GLvoid **", params)
TRACE_GL_VOID(glExtGetBuffersQCOM, (GLuint *buffers, GLint maxBuffers, GLint *numBuffers), (buffers, maxBuffers, numBuffers), 3, "GLuint *", buffers, "GLint", maxBuffers, "GLint *", numBuffers)
@@ -125,6 +135,7 @@ TRACE_GL_VOID(glFogxvOES, (GLenum pname, const GLfixed *params), (pname, params)
TRACE_GL_VOID(glFramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer)
TRACE_GL_VOID(glFramebufferRenderbufferOES, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer)
TRACE_GL_VOID(glFramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level)
+TRACE_GL_VOID(glFramebufferTexture2DMultisampleEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples), (target, attachment, textarget, texture, level, samples), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLsizei", samples)
TRACE_GL_VOID(glFramebufferTexture2DMultisampleIMG, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples), (target, attachment, textarget, texture, level, samples), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLsizei", samples)
TRACE_GL_VOID(glFramebufferTexture2DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level)
TRACE_GL_VOID(glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset), (target, attachment, textarget, texture, level, zoffset), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLint", zoffset)
@@ -138,6 +149,8 @@ TRACE_GL_VOID(glGenFencesNV, (GLsizei n, GLuint *fences), (n, fences), 2, "GLsiz
TRACE_GL_VOID(glGenFramebuffers, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers)
TRACE_GL_VOID(glGenFramebuffersOES, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers)
TRACE_GL_VOID(glGenPerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors)
+TRACE_GL_VOID(glGenProgramPipelinesEXT, (GLsizei n, GLuint *pipelines), (n, pipelines), 2, "GLsizei", n, "GLuint *", pipelines)
+TRACE_GL_VOID(glGenQueriesEXT, (GLsizei n, GLuint *ids), (n, ids), 2, "GLsizei", n, "GLuint *", ids)
TRACE_GL_VOID(glGenRenderbuffers, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers)
TRACE_GL_VOID(glGenRenderbuffersOES, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers)
TRACE_GL_VOID(glGenTextures, (GLsizei n, GLuint *textures), (n, textures), 2, "GLsizei", n, "GLuint *", textures)
@@ -164,6 +177,7 @@ TRACE_GL_VOID(glGetFixedvOES, (GLenum pname, GLfixed *params), (pname, params),
TRACE_GL_VOID(glGetFloatv, (GLenum pname, GLfloat *params), (pname, params), 2, "GLenum", pname, "GLfloat *", params)
TRACE_GL_VOID(glGetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params)
TRACE_GL_VOID(glGetFramebufferAttachmentParameterivOES, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params)
+TRACE_GL(GLenum, glGetGraphicsResetStatusEXT, (void), (), 0)
TRACE_GL_VOID(glGetIntegerv, (GLenum pname, GLint *params), (pname, params), 2, "GLenum", pname, "GLint *", params)
TRACE_GL_VOID(glGetLightfv, (GLenum light, GLenum pname, GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfloat *", params)
TRACE_GL_VOID(glGetLightxv, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params)
@@ -171,6 +185,7 @@ TRACE_GL_VOID(glGetLightxvOES, (GLenum light, GLenum pname, GLfixed *params), (l
TRACE_GL_VOID(glGetMaterialfv, (GLenum face, GLenum pname, GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfloat *", params)
TRACE_GL_VOID(glGetMaterialxv, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params)
TRACE_GL_VOID(glGetMaterialxvOES, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params)
+TRACE_GL_VOID(glGetObjectLabelEXT, (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label), (type, object, bufSize, length, label), 5, "GLenum", type, "GLuint", object, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", label)
TRACE_GL_VOID(glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten), (monitor, pname, dataSize, data, bytesWritten), 5, "GLuint", monitor, "GLenum", pname, "GLsizei", dataSize, "GLuint *", data, "GLint *", bytesWritten)
TRACE_GL_VOID(glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, GLvoid *data), (group, counter, pname, data), 4, "GLuint", group, "GLuint", counter, "GLenum", pname, "GLvoid *", data)
TRACE_GL_VOID(glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString), (group, counter, bufSize, length, counterString), 5, "GLuint", group, "GLuint", counter, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", counterString)
@@ -180,7 +195,11 @@ TRACE_GL_VOID(glGetPerfMonitorGroupsAMD, (GLint *numGroups, GLsizei groupsSize,
TRACE_GL_VOID(glGetPointerv, (GLenum pname, GLvoid **params), (pname, params), 2, "GLenum", pname, "GLvoid **", params)
TRACE_GL_VOID(glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary), (program, bufSize, length, binaryFormat, binary), 5, "GLuint", program, "GLsizei", bufSize, "GLsizei *", length, "GLenum *", binaryFormat, "GLvoid *", binary)
TRACE_GL_VOID(glGetProgramInfoLog, (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog), (program, bufsize, length, infolog), 4, "GLuint", program, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog)
+TRACE_GL_VOID(glGetProgramPipelineInfoLogEXT, (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog), (pipeline, bufSize, length, infoLog), 4, "GLuint", pipeline, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", infoLog)
+TRACE_GL_VOID(glGetProgramPipelineivEXT, (GLuint pipeline, GLenum pname, GLint *params), (pipeline, pname, params), 3, "GLuint", pipeline, "GLenum", pname, "GLint *", params)
TRACE_GL_VOID(glGetProgramiv, (GLuint program, GLenum pname, GLint* params), (program, pname, params), 3, "GLuint", program, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetQueryObjectuivEXT, (GLuint id, GLenum pname, GLuint *params), (id, pname, params), 3, "GLuint", id, "GLenum", pname, "GLuint *", params)
+TRACE_GL_VOID(glGetQueryivEXT, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params)
TRACE_GL_VOID(glGetRenderbufferParameteriv, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params)
TRACE_GL_VOID(glGetRenderbufferParameterivOES, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params)
TRACE_GL_VOID(glGetShaderInfoLog, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog), (shader, bufsize, length, infolog), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog)
@@ -205,18 +224,24 @@ TRACE_GL_VOID(glGetUniformiv, (GLuint program, GLint location, GLint* params), (
TRACE_GL_VOID(glGetVertexAttribPointerv, (GLuint index, GLenum pname, GLvoid** pointer), (index, pname, pointer), 3, "GLuint", index, "GLenum", pname, "GLvoid**", pointer)
TRACE_GL_VOID(glGetVertexAttribfv, (GLuint index, GLenum pname, GLfloat* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLfloat*", params)
TRACE_GL_VOID(glGetVertexAttribiv, (GLuint index, GLenum pname, GLint* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLint*", params)
+TRACE_GL_VOID(glGetnUniformfvEXT, (GLuint program, GLint location, GLsizei bufSize, float *params), (program, location, bufSize, params), 4, "GLuint", program, "GLint", location, "GLsizei", bufSize, "float *", params)
+TRACE_GL_VOID(glGetnUniformivEXT, (GLuint program, GLint location, GLsizei bufSize, GLint *params), (program, location, bufSize, params), 4, "GLuint", program, "GLint", location, "GLsizei", bufSize, "GLint *", params)
TRACE_GL_VOID(glHint, (GLenum target, GLenum mode), (target, mode), 2, "GLenum", target, "GLenum", mode)
+TRACE_GL_VOID(glInsertEventMarkerEXT, (GLsizei length, const GLchar *marker), (length, marker), 2, "GLsizei", length, "const GLchar *", marker)
TRACE_GL(GLboolean, glIsBuffer, (GLuint buffer), (buffer), 1, "GLuint", buffer)
TRACE_GL(GLboolean, glIsEnabled, (GLenum cap), (cap), 1, "GLenum", cap)
TRACE_GL(GLboolean, glIsFenceNV, (GLuint fence), (fence), 1, "GLuint", fence)
TRACE_GL(GLboolean, glIsFramebuffer, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer)
TRACE_GL(GLboolean, glIsFramebufferOES, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer)
TRACE_GL(GLboolean, glIsProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL(GLboolean, glIsProgramPipelineEXT, (GLuint pipeline), (pipeline), 1, "GLuint", pipeline)
+TRACE_GL(GLboolean, glIsQueryEXT, (GLuint id), (id), 1, "GLuint", id)
TRACE_GL(GLboolean, glIsRenderbuffer, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer)
TRACE_GL(GLboolean, glIsRenderbufferOES, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer)
TRACE_GL(GLboolean, glIsShader, (GLuint shader), (shader), 1, "GLuint", shader)
TRACE_GL(GLboolean, glIsTexture, (GLuint texture), (texture), 1, "GLuint", texture)
TRACE_GL(GLboolean, glIsVertexArrayOES, (GLuint array), (array), 1, "GLuint", array)
+TRACE_GL_VOID(glLabelObjectEXT, (GLenum type, GLuint object, GLsizei length, const GLchar *label), (type, object, length, label), 4, "GLenum", type, "GLuint", object, "GLsizei", length, "const GLchar *", label)
TRACE_GL_VOID(glLightModelf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param)
TRACE_GL_VOID(glLightModelfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params)
TRACE_GL_VOID(glLightModelx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param)
@@ -278,15 +303,43 @@ TRACE_GL_VOID(glPointSizexOES, (GLfixed size), (size), 1, "GLfixed", size)
TRACE_GL_VOID(glPolygonOffset, (GLfloat factor, GLfloat units), (factor, units), 2, "GLfloat", factor, "GLfloat", units)
TRACE_GL_VOID(glPolygonOffsetx, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units)
TRACE_GL_VOID(glPolygonOffsetxOES, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units)
+TRACE_GL_VOID(glPopGroupMarkerEXT, (void), (), 0)
TRACE_GL_VOID(glPopMatrix, (void), (), 0)
TRACE_GL_VOID(glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length), (program, binaryFormat, binary, length), 4, "GLuint", program, "GLenum", binaryFormat, "const GLvoid *", binary, "GLint", length)
+TRACE_GL_VOID(glProgramParameteriEXT, (GLuint program, GLenum pname, GLint value), (program, pname, value), 3, "GLuint", program, "GLenum", pname, "GLint", value)
+TRACE_GL_VOID(glProgramUniform1fEXT, (GLuint program, GLint location, GLfloat x), (program, location, x), 3, "GLuint", program, "GLint", location, "GLfloat", x)
+TRACE_GL_VOID(glProgramUniform1fvEXT, (GLuint program, GLint location, GLsizei count, const GLfloat *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLfloat *", value)
+TRACE_GL_VOID(glProgramUniform1iEXT, (GLuint program, GLint location, GLint x), (program, location, x), 3, "GLuint", program, "GLint", location, "GLint", x)
+TRACE_GL_VOID(glProgramUniform1ivEXT, (GLuint program, GLint location, GLsizei count, const GLint *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLint *", value)
+TRACE_GL_VOID(glProgramUniform2fEXT, (GLuint program, GLint location, GLfloat x, GLfloat y), (program, location, x, y), 4, "GLuint", program, "GLint", location, "GLfloat", x, "GLfloat", y)
+TRACE_GL_VOID(glProgramUniform2fvEXT, (GLuint program, GLint location, GLsizei count, const GLfloat *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLfloat *", value)
+TRACE_GL_VOID(glProgramUniform2iEXT, (GLuint program, GLint location, GLint x, GLint y), (program, location, x, y), 4, "GLuint", program, "GLint", location, "GLint", x, "GLint", y)
+TRACE_GL_VOID(glProgramUniform2ivEXT, (GLuint program, GLint location, GLsizei count, const GLint *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLint *", value)
+TRACE_GL_VOID(glProgramUniform3fEXT, (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z), (program, location, x, y, z), 5, "GLuint", program, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z)
+TRACE_GL_VOID(glProgramUniform3fvEXT, (GLuint program, GLint location, GLsizei count, const GLfloat *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLfloat *", value)
+TRACE_GL_VOID(glProgramUniform3iEXT, (GLuint program, GLint location, GLint x, GLint y, GLint z), (program, location, x, y, z), 5, "GLuint", program, "GLint", location, "GLint", x, "GLint", y, "GLint", z)
+TRACE_GL_VOID(glProgramUniform3ivEXT, (GLuint program, GLint location, GLsizei count, const GLint *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLint *", value)
+TRACE_GL_VOID(glProgramUniform4fEXT, (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (program, location, x, y, z, w), 6, "GLuint", program, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w)
+TRACE_GL_VOID(glProgramUniform4fvEXT, (GLuint program, GLint location, GLsizei count, const GLfloat *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLfloat *", value)
+TRACE_GL_VOID(glProgramUniform4iEXT, (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w), (program, location, x, y, z, w), 6, "GLuint", program, "GLint", location, "GLint", x, "GLint", y, "GLint", z, "GLint", w)
+TRACE_GL_VOID(glProgramUniform4ivEXT, (GLuint program, GLint location, GLsizei count, const GLint *value), (program, location, count, value), 4, "GLuint", program, "GLint", location, "GLsizei", count, "const GLint *", value)
+TRACE_GL_VOID(glProgramUniformMatrix2fvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value), (program, location, count, transpose, value), 5, "GLuint", program, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat *", value)
+TRACE_GL_VOID(glProgramUniformMatrix3fvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value), (program, location, count, transpose, value), 5, "GLuint", program, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat *", value)
+TRACE_GL_VOID(glProgramUniformMatrix4fvEXT, (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value), (program, location, count, transpose, value), 5, "GLuint", program, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat *", value)
+TRACE_GL_VOID(glPushGroupMarkerEXT, (GLsizei length, const GLchar *marker), (length, marker), 2, "GLsizei", length, "const GLchar *", marker)
TRACE_GL_VOID(glPushMatrix, (void), (), 0)
TRACE_GL(GLbitfield, glQueryMatrixxOES, (GLfixed mantissa[16], GLint exponent[16]), (mantissa, exponent), 2, "GLfixed", mantissa, "GLint", exponent)
+TRACE_GL_VOID(glReadBufferNV, (GLenum mode), (mode), 1, "GLenum", mode)
TRACE_GL_VOID(glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels), (x, y, width, height, format, type, pixels), 7, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "GLvoid *", pixels)
+TRACE_GL_VOID(glReadnPixelsEXT, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data), (x, y, width, height, format, type, bufSize, data), 8, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "GLsizei", bufSize, "void *", data)
TRACE_GL_VOID(glReleaseShaderCompiler, (void), (), 0)
TRACE_GL_VOID(glRenderbufferStorage, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRenderbufferStorageMultisampleANGLE, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRenderbufferStorageMultisampleAPPLE, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glRenderbufferStorageMultisampleEXT, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
TRACE_GL_VOID(glRenderbufferStorageMultisampleIMG, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
TRACE_GL_VOID(glRenderbufferStorageOES, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glResolveMultisampleFramebufferAPPLE, (void), (), 0)
TRACE_GL_VOID(glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z), (angle, x, y, z), 4, "GLfloat", angle, "GLfloat", x, "GLfloat", y, "GLfloat", z)
TRACE_GL_VOID(glRotatex, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z)
TRACE_GL_VOID(glRotatexOES, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z)
@@ -335,8 +388,14 @@ TRACE_GL_VOID(glTexParameterx, (GLenum target, GLenum pname, GLfixed param), (ta
TRACE_GL_VOID(glTexParameterxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param)
TRACE_GL_VOID(glTexParameterxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
TRACE_GL_VOID(glTexParameterxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params)
+TRACE_GL_VOID(glTexStorage1DEXT, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width), (target, levels, internalformat, width), 4, "GLenum", target, "GLsizei", levels, "GLenum", internalformat, "GLsizei", width)
+TRACE_GL_VOID(glTexStorage2DEXT, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height), (target, levels, internalformat, width, height), 5, "GLenum", target, "GLsizei", levels, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glTexStorage3DEXT, (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth), (target, levels, internalformat, width, height, depth), 6, "GLenum", target, "GLsizei", levels, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth)
TRACE_GL_VOID(glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels), (target, level, xoffset, yoffset, width, height, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "const GLvoid *", pixels)
TRACE_GL_VOID(glTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "const GLvoid*", pixels)
+TRACE_GL_VOID(glTextureStorage1DEXT, (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width), (texture, target, levels, internalformat, width), 5, "GLuint", texture, "GLenum", target, "GLsizei", levels, "GLenum", internalformat, "GLsizei", width)
+TRACE_GL_VOID(glTextureStorage2DEXT, (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height), (texture, target, levels, internalformat, width, height), 6, "GLuint", texture, "GLenum", target, "GLsizei", levels, "GLenum", internalformat, "GLsizei", width, "GLsizei", height)
+TRACE_GL_VOID(glTextureStorage3DEXT, (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth), (texture, target, levels, internalformat, width, height, depth), 7, "GLuint", texture, "GLenum", target, "GLsizei", levels, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth)
TRACE_GL_VOID(glTranslatef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z)
TRACE_GL_VOID(glTranslatex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
TRACE_GL_VOID(glTranslatexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z)
@@ -361,7 +420,9 @@ TRACE_GL_VOID(glUniformMatrix3fv, (GLint location, GLsizei count, GLboolean tran
TRACE_GL_VOID(glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value)
TRACE_GL(GLboolean, glUnmapBufferOES, (GLenum target), (target), 1, "GLenum", target)
TRACE_GL_VOID(glUseProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glUseProgramStagesEXT, (GLuint pipeline, GLbitfield stages, GLuint program), (pipeline, stages, program), 3, "GLuint", pipeline, "GLbitfield", stages, "GLuint", program)
TRACE_GL_VOID(glValidateProgram, (GLuint program), (program), 1, "GLuint", program)
+TRACE_GL_VOID(glValidateProgramPipelineEXT, (GLuint pipeline), (pipeline), 1, "GLuint", pipeline)
TRACE_GL_VOID(glVertexAttrib1f, (GLuint indx, GLfloat x), (indx, x), 2, "GLuint", indx, "GLfloat", x)
TRACE_GL_VOID(glVertexAttrib1fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values)
TRACE_GL_VOID(glVertexAttrib2f, (GLuint indx, GLfloat x, GLfloat y), (indx, x, y), 3, "GLuint", indx, "GLfloat", x, "GLfloat", y)
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
index ef959360130d..b985aaf81ba1 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
@@ -63,6 +63,7 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
+ android:paddingRight="6dp"
>
<ImageView
@@ -87,7 +88,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="12dp"
- android:paddingLeft="6dp"
android:singleLine="true"
android:ellipsize="end"
android:text="@string/status_bar_settings_settings_button"
@@ -99,6 +99,7 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
+ android:paddingRight="6dp"
>
<ImageView
@@ -122,7 +123,6 @@
android:layout_gravity="left|center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingLeft="6dp"
android:paddingRight="12dp"
android:singleLine="true"
android:ellipsize="end"
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index a6c64ade3e80..d083467e90ad 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -101,7 +101,12 @@
<string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi, адзiн слупок."</string>
<string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi, два слупкi."</string>
<string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi, тры слупкi."</string>
- <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"Моцны сiгнал Wi-Fi."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Поўны сігнал Wi-Fi."</string>
+ <string name="accessibility_no_wimax" msgid="4329180129727630368">"Няма сiгналу WiMAX."</string>
+ <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Адзiн слупок сiгналу WiMAX."</string>
+ <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Два слупкi сiгналу WiMAX."</string>
+ <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Тры слупкi сiгналу WiMAX."</string>
+ <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Моцны сiгнал WiMAX."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -135,4 +140,5 @@
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Пошук GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"Месца задана праз GPS"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</string>
+ <string name="dreams_dock_launcher" msgid="3541196417659166245">"Актывацыя экраннай застаўкі"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index e84f40f964ec..ab4eeb49886a 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -133,7 +133,7 @@
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Mobile Daten deaktiviert"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Daten deaktiviert"</string>
- <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Sie haben die angegebenen Grenze für die Datennutzung erreicht."\n\n"Wenn Sie die Datennutzung erneut aktivieren, berechnet Ihr Mobilfunkanbieter unter Umständen zusätzliche Gebühren."</string>
+ <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Sie haben die angegebenen Grenze für den Datenverbrauch erreicht."\n\n"Wenn Sie die Datennutzung erneut aktivieren, berechnet Ihr Mobilfunkanbieter unter Umständen zusätzliche Gebühren."</string>
<string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Daten erneut aktivieren"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Keine Internetverbindung"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"WLAN verbunden"</string>
diff --git a/packages/SystemUI/res/values-es-rUS-large/strings.xml b/packages/SystemUI/res/values-es-rUS-large/strings.xml
index 3f96e87fce1d..dd44b28fb214 100644
--- a/packages/SystemUI/res/values-es-rUS-large/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS-large/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="status_bar_clear_all_button" msgid="4661583896803349732">"Borrar todas"</string>
+ <string name="status_bar_clear_all_button" msgid="4661583896803349732">"Eliminar todas"</string>
<string name="notifications_off_title" msgid="1860117696034775851">"Notificaciones desactivadas"</string>
<string name="notifications_off_text" msgid="1439152806320786912">"Toca aquí para volver a activar las notificaciones."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 85818ae6ee3b..a70090847bc3 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -20,7 +20,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="7164937344850004466">"IU del sistema"</string>
- <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Eliminar"</string>
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"No molestar"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Mostrar notificaciones"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Eliminar de la lista"</string>
@@ -122,7 +122,7 @@
<skip />
<string name="accessibility_settings_button" msgid="799583911231893380">"Configuración del sistema"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
- <string name="accessibility_remove_notification" msgid="3603099514902182350">"Borrar notificación"</string>
+ <string name="accessibility_remove_notification" msgid="3603099514902182350">"Eliminar notificación"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS habilitado"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Adquisición de GPS"</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter habilitado"</string>
@@ -133,12 +133,12 @@
<string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos de 4G inhabilitados"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Se inhabilitaron los datos móviles"</string>
<string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Datos inhabilitados"</string>
- <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Alcanzaste el límite de uso de datos especificado."\n\n"Puede que tu operador te cobre por volver a habilitar datos."</string>
- <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Volver a habilitar datos"</string>
+ <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Alcanzaste el límite de uso de datos especificado."\n\n"Puede que tu operador te cobre por volver a activar datos."</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Volver a activar datos"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Sin conexión a Internet"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi conectado"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"Buscando GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
- <string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Activar el protector de pantalla"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 943b8ca4484c..a5bfb4a25359 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -101,7 +101,12 @@
<string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"WiFi signaal: üks post."</string>
<string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WiFi signaal: kaks posti."</string>
<string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WiFi signaal: kolm posti."</string>
- <string name="accessibility_wifi_signal_full" msgid="4826278754383492058">"WiFi signaal on täis."</string>
+ <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi-signaal on tugev."</string>
+ <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX-i pole."</string>
+ <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX-i on üks riba."</string>
+ <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-i on kaks riba."</string>
+ <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-i on kolm riba."</string>
+ <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-i signaal on tugev."</string>
<string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
<string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
<string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
@@ -133,4 +138,5 @@
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS-i otsimine"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-i määratud asukoht"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
+ <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiveeri ekraanisäästja"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 545d54eab8c8..dec4def6fbb5 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -115,7 +115,7 @@
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Sem SIM."</string>
- <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Vínculo Bluetooth."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Modo de avião."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 2106b892da7c..983df47e88ea 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -39,8 +39,10 @@
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nagins avis"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actual"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Avis"</string>
- <!-- outdated translation 7923774589611311406 --> <string name="battery_low_title" msgid="2783104807551211639">"Connectar il chargiabattarias"</string>
- <!-- outdated translation 7388781709819722764 --> <string name="battery_low_subtitle" msgid="1752040062087829196">"L\'accu è prest vid."</string>
+ <!-- no translation found for battery_low_title (2783104807551211639) -->
+ <skip />
+ <!-- no translation found for battery_low_subtitle (1752040062087829196) -->
+ <skip />
<!-- no translation found for battery_low_percent_format (1077244949318261761) -->
<skip />
<!-- no translation found for invalid_charger (4549105996740522523) -->
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 17330b1e9a7b..963976dcc185 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -36,7 +36,7 @@
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"Уведомления"</string>
<string name="battery_low_title" msgid="2783104807551211639">"Подключите зарядное устройство"</string>
<string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея разряжена."</string>
- <string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось: <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
+ <string name="battery_low_percent_format" msgid="1077244949318261761">"Осталось <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
<string name="invalid_charger" msgid="4549105996740522523">"Зарядка через порт USB не поддерживается."\n"Используйте только зарядное устройство из комплекта поставки."</string>
<string name="battery_low_why" msgid="7279169609518386372">"Расход заряда батареи"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Настройки"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3843ea96a8ec..70e29ebe28a0 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -26,7 +26,7 @@
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ondoa kwenye orodha"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Taarifa za programu-matumizi"</string>
<string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Hakuna programu za sasa"</string>
- <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha programu za hivi karibuni"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha prog za hivi karibuni"</string>
<!-- String.format failed for translation -->
<!-- no translation found for status_bar_accessibility_recent_apps:other (1040784359794890744) -->
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Hakuna arifa"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index dcda9c28bfaf..4145fc46c04c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -68,22 +68,13 @@ public class RecentTasksLoader {
// get the icon size we want -- on tablets, we use bigger icons
boolean isTablet = res.getBoolean(R.bool.config_recents_interface_for_tablets);
- int density = res.getDisplayMetrics().densityDpi;
if (isTablet) {
- if (density == DisplayMetrics.DENSITY_LOW) {
- mIconDpi = DisplayMetrics.DENSITY_MEDIUM;
- } else if (density == DisplayMetrics.DENSITY_MEDIUM) {
- mIconDpi = DisplayMetrics.DENSITY_HIGH;
- } else if (density == DisplayMetrics.DENSITY_HIGH) {
- mIconDpi = DisplayMetrics.DENSITY_XHIGH;
- } else if (density == DisplayMetrics.DENSITY_XHIGH) {
- // We'll need to use a denser icon, or some sort of a mipmap
- mIconDpi = DisplayMetrics.DENSITY_XHIGH;
- }
+ ActivityManager activityManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ mIconDpi = activityManager.getLauncherLargeIconDensity();
} else {
mIconDpi = res.getDisplayMetrics().densityDpi;
}
- mIconDpi = isTablet ? DisplayMetrics.DENSITY_HIGH : res.getDisplayMetrics().densityDpi;
// Render the default thumbnail background
int width = (int) res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 69a247d69c9f..d33ed3fb41da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -23,6 +23,8 @@ import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
+import android.os.Handler;
+import android.os.Message;
import android.os.ServiceManager;
import android.util.AttributeSet;
import android.util.Slog;
@@ -66,6 +68,35 @@ public class NavigationBarView extends LinearLayout {
int mDisabledFlags = 0;
int mNavigationIconHints = 0;
+ // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
+ final static boolean WORKAROUND_INVALID_LAYOUT = true;
+ final static int MSG_CHECK_INVALID_LAYOUT = 8686;
+
+ private class H extends Handler {
+ public void handleMessage(Message m) {
+ switch (m.what) {
+ case MSG_CHECK_INVALID_LAYOUT:
+ final String how = "" + m.obj;
+ final int w = getWidth();
+ final int h = getHeight();
+ final int vw = mCurrentView.getWidth();
+ final int vh = mCurrentView.getHeight();
+
+ if (h != vh || w != vw) {
+ Slog.w(TAG, String.format(
+ "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
+ how, w, h, vw, vh));
+ if (WORKAROUND_INVALID_LAYOUT) {
+ requestLayout();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private H mHandler = new H();
+
public View getRecentsButton() {
return mCurrentView.findViewById(R.id.recent_apps);
}
@@ -275,6 +306,36 @@ public class NavigationBarView extends LinearLayout {
}
}
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ if (DEBUG) Slog.d(TAG, String.format(
+ "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
+ postCheckForInvalidLayout("sizeChanged");
+ super.onSizeChanged(w, h, oldw, oldh);
+ }
+
+ /*
+ @Override
+ protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
+ if (DEBUG) Slog.d(TAG, String.format(
+ "onLayout: %s (%d,%d,%d,%d)",
+ changed?"changed":"notchanged", left, top, right, bottom));
+ super.onLayout(changed, left, top, right, bottom);
+ }
+
+ // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
+ // fails, any touch on the display will fix the layout.
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (DEBUG) Slog.d(TAG, "onInterceptTouchEvent: " + ev.toString());
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ postCheckForInvalidLayout("touch");
+ }
+ return super.onInterceptTouchEvent(ev);
+ }
+ */
+
+
private String getResourceName(int resId) {
if (resId != 0) {
final android.content.res.Resources res = mContext.getResources();
@@ -288,6 +349,10 @@ public class NavigationBarView extends LinearLayout {
}
}
+ private void postCheckForInvalidLayout(final String how) {
+ mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
+ }
+
private static String visibilityToString(int vis) {
switch (vis) {
case View.INVISIBLE:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index d09e68050402..d787e105c2f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -588,8 +588,12 @@ public class NetworkController extends BroadcastReceiver {
}
}
- if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) {
- mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
+ if (isCdma()) {
+ if (isCdmaEri()) {
+ mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
+ }
+ } else if (mPhone.isNetworkRoaming()) {
+ mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
}
}
@@ -850,8 +854,10 @@ public class NetworkController extends BroadcastReceiver {
Slog.d(TAG, "updateConnectivity: intent=" + intent);
}
- NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra(
- ConnectivityManager.EXTRA_NETWORK_INFO));
+ final ConnectivityManager connManager = (ConnectivityManager) mContext
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ final NetworkInfo info = connManager.getActiveNetworkInfo();
+
int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
if (CHATTY) {
@@ -890,34 +896,51 @@ public class NetworkController extends BroadcastReceiver {
if (!mHasMobileDataFeature) {
mDataSignalIconId = mPhoneSignalIconId = 0;
- } else if (mDataConnected) {
- mobileLabel = mNetworkName;
- if (DEBUG) {
- mobileLabel += "yyyyYYYYyyyyYYYY";
- }
- combinedSignalIconId = mDataSignalIconId;
- switch (mDataActivity) {
- case TelephonyManager.DATA_ACTIVITY_IN:
- mMobileActivityIconId = R.drawable.stat_sys_signal_in;
- break;
- case TelephonyManager.DATA_ACTIVITY_OUT:
- mMobileActivityIconId = R.drawable.stat_sys_signal_out;
- break;
- case TelephonyManager.DATA_ACTIVITY_INOUT:
- mMobileActivityIconId = R.drawable.stat_sys_signal_inout;
- break;
- default:
- mMobileActivityIconId = 0;
- break;
+ mobileLabel = "";
+ } else {
+ // We want to show the carrier name if in service and either:
+ // - We are connected to mobile data, or
+ // - We are not connected to mobile data, as long as the *reason* packets are not
+ // being routed over that link is that we have better connectivity via wifi.
+ // If data is disconnected for some other reason but wifi is connected, we show nothing.
+ // Otherwise (nothing connected) we show "No internet connection".
+
+ if (mDataConnected) {
+ mobileLabel = mNetworkName;
+ } else if (mWifiConnected) {
+ if (hasService()) {
+ mobileLabel = mNetworkName;
+ } else {
+ mobileLabel = "";
+ }
+ } else {
+ mobileLabel
+ = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
}
- combinedLabel = mobileLabel;
- combinedActivityIconId = mMobileActivityIconId;
- combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
- mContentDescriptionCombinedSignal = mContentDescriptionDataType;
- } else {
- mobileLabel = mHasMobileDataFeature ?
- context.getString(R.string.status_bar_settings_signal_meter_disconnected) : "";
+ // Now for things that should only be shown when actually using mobile data.
+ if (mDataConnected) {
+ combinedSignalIconId = mDataSignalIconId;
+ switch (mDataActivity) {
+ case TelephonyManager.DATA_ACTIVITY_IN:
+ mMobileActivityIconId = R.drawable.stat_sys_signal_in;
+ break;
+ case TelephonyManager.DATA_ACTIVITY_OUT:
+ mMobileActivityIconId = R.drawable.stat_sys_signal_out;
+ break;
+ case TelephonyManager.DATA_ACTIVITY_INOUT:
+ mMobileActivityIconId = R.drawable.stat_sys_signal_inout;
+ break;
+ default:
+ mMobileActivityIconId = 0;
+ break;
+ }
+
+ combinedLabel = mobileLabel;
+ combinedActivityIconId = mMobileActivityIconId;
+ combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
+ mContentDescriptionCombinedSignal = mContentDescriptionDataType;
+ }
}
if (mWifiConnected) {
@@ -949,6 +972,12 @@ public class NetworkController extends BroadcastReceiver {
combinedLabel = wifiLabel;
combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
mContentDescriptionCombinedSignal = mContentDescriptionWifi;
+ } else {
+ if (mHasMobileDataFeature) {
+ wifiLabel = "";
+ } else {
+ wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+ }
}
if (mBluetoothTethered) {
@@ -969,9 +998,17 @@ public class NetworkController extends BroadcastReceiver {
mDataTypeIconId = 0;
// combined values from connected wifi take precedence over airplane mode
- if (!mWifiConnected) {
- wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
- combinedLabel = wifiLabel;
+ if (mWifiConnected) {
+ // Suppress "No internet connection." from mobile if wifi connected.
+ mobileLabel = "";
+ } else {
+ if (mHasMobileDataFeature) {
+ // let the mobile icon show "No internet connection."
+ wifiLabel = "";
+ } else {
+ wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+ combinedLabel = wifiLabel;
+ }
mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal;
combinedSignalIconId = mDataSignalIconId;
}
@@ -986,10 +1023,13 @@ public class NetworkController extends BroadcastReceiver {
mContentDescriptionCombinedSignal = mHasMobileDataFeature
? mContentDescriptionDataType : mContentDescriptionWifi;
- if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) {
+ mDataTypeIconId = 0;
+ if (isCdma()) {
+ if (isCdmaEri()) {
+ mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
+ }
+ } else if (mPhone.isNetworkRoaming()) {
mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
- } else {
- mDataTypeIconId = 0;
}
}
diff --git a/packages/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 8e062b7870d2..46c0f83f4c2c 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -5,7 +5,7 @@
<application android:label="VpnDialogs"
android:allowBackup="false" >
<activity android:name=".ConfirmDialog"
- android:theme="@style/transparent">
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
@@ -13,7 +13,7 @@
</activity>
<activity android:name=".ManageDialog"
- android:theme="@style/transparent"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
diff --git a/packages/VpnDialogs/res/values/styles.xml b/packages/VpnDialogs/res/values/styles.xml
index cf105969b49a..e3469ec4f67e 100644
--- a/packages/VpnDialogs/res/values/styles.xml
+++ b/packages/VpnDialogs/res/values/styles.xml
@@ -15,13 +15,6 @@
-->
<resources>
-
- <style name="transparent">
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowIsFloating">true</item>
- </style>
-
<style name="label">
<item name="android:gravity">center_vertical|right</item>
<item name="android:paddingRight">2mm</item>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index c7b4a5fd3862..13d8019cac0e 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -16,8 +16,6 @@
package com.android.vpndialogs;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -32,15 +30,16 @@ import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
-public class ConfirmDialog extends Activity implements CompoundButton.OnCheckedChangeListener,
- DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+import com.android.internal.app.AlertActivity;
+
+public class ConfirmDialog extends AlertActivity implements
+ CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener {
private static final String TAG = "VpnConfirm";
private String mPackage;
private IConnectivityManager mService;
- private AlertDialog mDialog;
private Button mButton;
@Override
@@ -67,18 +66,17 @@ public class ConfirmDialog extends Activity implements CompoundButton.OnCheckedC
getString(R.string.prompt, app.loadLabel(pm)));
((CompoundButton) view.findViewById(R.id.check)).setOnCheckedChangeListener(this);
- mDialog = new AlertDialog.Builder(this)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle(android.R.string.dialog_alert_title)
- .setView(view)
- .setPositiveButton(android.R.string.ok, this)
- .setNegativeButton(android.R.string.cancel, this)
- .setCancelable(false)
- .create();
- mDialog.setOnDismissListener(this);
- mDialog.show();
-
- mButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ mAlertParams.mIconId = android.R.drawable.ic_dialog_alert;
+ mAlertParams.mTitle = getText(android.R.string.dialog_alert_title);
+ mAlertParams.mPositiveButtonText = getText(android.R.string.ok);
+ mAlertParams.mPositiveButtonListener = this;
+ mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
+ mAlertParams.mNegativeButtonListener = this;
+ mAlertParams.mView = view;
+ setupAlert();
+
+ getWindow().setCloseOnTouchOutside(false);
+ mButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
mButton.setEnabled(false);
} catch (Exception e) {
Log.e(TAG, "onResume", e);
@@ -87,12 +85,7 @@ public class ConfirmDialog extends Activity implements CompoundButton.OnCheckedC
}
@Override
- protected void onPause() {
- super.onPause();
- if (mDialog != null) {
- mDialog.setOnDismissListener(null);
- mDialog.dismiss();
- }
+ public void onBackPressed() {
}
@Override
@@ -103,16 +96,11 @@ public class ConfirmDialog extends Activity implements CompoundButton.OnCheckedC
@Override
public void onClick(DialogInterface dialog, int which) {
try {
- if (which == AlertDialog.BUTTON_POSITIVE && mService.prepareVpn(null, mPackage)) {
+ if (which == DialogInterface.BUTTON_POSITIVE && mService.prepareVpn(null, mPackage)) {
setResult(RESULT_OK);
}
} catch (Exception e) {
Log.e(TAG, "onClick", e);
}
}
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- finish();
- }
}
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 7fb141709884..2de02511d681 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -16,8 +16,6 @@
package com.android.vpndialogs;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -35,20 +33,20 @@ import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.internal.app.AlertActivity;
import com.android.internal.net.VpnConfig;
import java.io.DataInputStream;
import java.io.FileInputStream;
-public class ManageDialog extends Activity implements Handler.Callback,
- DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+public class ManageDialog extends AlertActivity implements
+ DialogInterface.OnClickListener, Handler.Callback {
private static final String TAG = "VpnManage";
private VpnConfig mConfig;
private IConnectivityManager mService;
- private AlertDialog mDialog;
private TextView mDuration;
private TextView mDataTransmitted;
private TextView mDataReceived;
@@ -80,31 +78,24 @@ public class ManageDialog extends Activity implements Handler.Callback,
mDataReceived = (TextView) view.findViewById(R.id.data_received);
if (mConfig.user.equals(VpnConfig.LEGACY_VPN)) {
- mDialog = new AlertDialog.Builder(this)
- .setIcon(android.R.drawable.ic_dialog_info)
- .setTitle(R.string.legacy_title)
- .setView(view)
- .setNeutralButton(R.string.disconnect, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
+ mAlertParams.mIconId = android.R.drawable.ic_dialog_info;
+ mAlertParams.mTitle = getText(R.string.legacy_title);
} else {
PackageManager pm = getPackageManager();
ApplicationInfo app = pm.getApplicationInfo(mConfig.user, 0);
- mDialog = new AlertDialog.Builder(this)
- .setIcon(app.loadIcon(pm))
- .setTitle(app.loadLabel(pm))
- .setView(view)
- .setNeutralButton(R.string.disconnect, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
+ mAlertParams.mIcon = app.loadIcon(pm);
+ mAlertParams.mTitle = app.loadLabel(pm);
}
-
if (mConfig.configureIntent != null) {
- mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
- getText(R.string.configure), this);
+ mAlertParams.mPositiveButtonText = getText(R.string.configure);
+ mAlertParams.mPositiveButtonListener = this;
}
- mDialog.setOnDismissListener(this);
- mDialog.show();
+ mAlertParams.mNeutralButtonText = getText(R.string.disconnect);
+ mAlertParams.mNeutralButtonListener = this;
+ mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
+ mAlertParams.mNegativeButtonListener = this;
+ mAlertParams.mView = view;
+ setupAlert();
if (mHandler == null) {
mHandler = new Handler(this);
@@ -119,18 +110,17 @@ public class ManageDialog extends Activity implements Handler.Callback,
@Override
protected void onPause() {
super.onPause();
- if (mDialog != null) {
- mDialog.setOnDismissListener(null);
- mDialog.dismiss();
+ if (!isFinishing()) {
+ finish();
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
try {
- if (which == AlertDialog.BUTTON_POSITIVE) {
+ if (which == DialogInterface.BUTTON_POSITIVE) {
mConfig.configureIntent.send();
- } else if (which == AlertDialog.BUTTON_NEUTRAL) {
+ } else if (which == DialogInterface.BUTTON_NEUTRAL) {
mService.prepareVpn(mConfig.user, VpnConfig.LEGACY_VPN);
}
} catch (Exception e) {
@@ -140,15 +130,10 @@ public class ManageDialog extends Activity implements Handler.Callback,
}
@Override
- public void onDismiss(DialogInterface dialog) {
- finish();
- }
-
- @Override
public boolean handleMessage(Message message) {
mHandler.removeMessages(0);
- if (mDialog.isShowing()) {
+ if (!isFinishing()) {
if (mConfig.startTime != 0) {
long seconds = (SystemClock.elapsedRealtime() - mConfig.startTime) / 1000;
mDuration.setText(String.format("%02d:%02d:%02d",
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index f45556ffe7bb..9f3de699d37a 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -19,6 +19,7 @@ package com.android.internal.policy.impl;
import com.android.internal.R;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccCard.State;
+import com.android.internal.widget.DigitalClock;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.TransportControlView;
import com.android.internal.policy.impl.KeyguardUpdateMonitor.SimStateCallback;
@@ -105,6 +106,7 @@ class KeyguardStatusViewManager implements OnClickListener {
private CharSequence mPlmn;
private CharSequence mSpn;
protected int mPhoneState;
+ private DigitalClock mDigitalClock;
private class TransientTextManager {
private TextView mTextView;
@@ -181,6 +183,7 @@ class KeyguardStatusViewManager implements OnClickListener {
mTransportView = (TransportControlView) findViewById(R.id.transport);
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
mEmergencyCallButtonEnabledInScreen = emergencyButtonEnabledInScreen;
+ mDigitalClock = (DigitalClock) findViewById(R.id.time);
// Hide transport control view until we know we need to show it.
if (mTransportView != null) {
@@ -290,6 +293,12 @@ class KeyguardStatusViewManager implements OnClickListener {
/** {@inheritDoc} */
public void onResume() {
if (DEBUG) Log.v(TAG, "onResume()");
+
+ // First update the clock, if present.
+ if (mDigitalClock != null) {
+ mDigitalClock.updateTime();
+ }
+
mUpdateMonitor.registerInfoCallback(mInfoCallback);
mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
resetStatusInfo();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 0d0461baed7b..1e9784c5cc79 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -855,6 +855,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
case Password:
secure = mLockPatternUtils.isLockPasswordEnabled();
break;
+ case Unknown:
+ // This means no security is set up
+ break;
default:
throw new IllegalStateException("unknown unlock mode " + unlockMode);
}
@@ -877,8 +880,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
// Re-create the unlock screen if necessary. This is primarily required to properly handle
// SIM state changes. This typically happens when this method is called by reset()
- if (mode == Mode.UnlockScreen) {
- final UnlockMode unlockMode = getUnlockMode();
+ final UnlockMode unlockMode = getUnlockMode();
+ if (mode == Mode.UnlockScreen && unlockMode != UnlockMode.Unknown) {
if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
boolean restartFaceLock = stopFaceLockIfRunning();
recreateUnlockScreen(unlockMode);
@@ -1052,11 +1055,15 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
break;
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
- // "forgot pattern" button is only available in the pattern mode...
- if (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) {
- currentMode = UnlockMode.Account;
+ if (mLockPatternUtils.isLockPatternEnabled()) {
+ // "forgot pattern" button is only available in the pattern mode...
+ if (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) {
+ currentMode = UnlockMode.Account;
+ } else {
+ currentMode = UnlockMode.Pattern;
+ }
} else {
- currentMode = UnlockMode.Pattern;
+ currentMode = UnlockMode.Unknown;
}
break;
default:
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 24a2420428d3..33846619857e 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -23,6 +23,8 @@ import com.android.internal.widget.WaveView;
import com.android.internal.widget.multiwaveview.MultiWaveView;
import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -34,6 +36,7 @@ import android.view.ViewGroup;
import android.widget.*;
import android.util.Log;
import android.media.AudioManager;
+import android.os.RemoteException;
import android.provider.MediaStore;
import android.provider.Settings;
@@ -229,8 +232,16 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
// Start the Camera
Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(intent);
- mCallback.goToUnlockScreen();
+ try {
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ Log.w(TAG, "can't dismiss keyguard on launch");
+ }
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Camera application not found");
+ }
} else {
toggleRingMode();
mUnlockWidgetMethods.updateResources();
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 43a34d098a43..2d6e4f8aad1a 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2044,6 +2044,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mTmpNavigationFrame.offset(mNavigationBarWidth, 0);
}
}
+ // Make sure the content and current rectangles are updated to
+ // account for the restrictions from the navigation bar.
+ mContentTop = mCurTop = mDockTop;
+ mContentBottom = mCurBottom = mDockBottom;
+ mContentLeft = mCurLeft = mDockLeft;
+ mContentRight = mCurRight = mDockRight;
// And compute the final frame.
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f5892d4a0e3d..2d856ada405d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1808,7 +1808,7 @@ uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
}
-AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput()
+AudioFlinger::AudioStreamOut* AudioFlinger::PlaybackThread::getOutput() const
{
Mutex::Autolock _l(mLock);
return mOutput;
@@ -1866,7 +1866,7 @@ AudioFlinger::MixerThread::~MixerThread()
bool AudioFlinger::MixerThread::threadLoop()
{
Vector< sp<Track> > tracksToRemove;
- uint32_t mixerStatus = MIXER_IDLE;
+ 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
@@ -1988,11 +1988,14 @@ bool AudioFlinger::MixerThread::threadLoop()
if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
mAudioMixer->process();
- sleepTime = 0;
- // increase sleep time progressively when application underrun condition clears
- if (sleepTimeShift > 0) {
+ // increase sleep time progressively when application underrun condition clears.
+ // Only increase sleep time if the mixer is ready for two consecutive times to avoid
+ // that a steady state of alternating ready/not ready conditions keeps the sleep time
+ // such that we would underrun the audio HAL.
+ if ((sleepTime == 0) && (sleepTimeShift > 0)) {
sleepTimeShift--;
}
+ sleepTime = 0;
standbyTime = systemTime() + kStandbyTimeInNsecs;
//TODO: delay standby when effects have a tail
} else {
@@ -2082,10 +2085,11 @@ bool AudioFlinger::MixerThread::threadLoop()
}
// prepareTracks_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
+AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
+ const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
{
- uint32_t mixerStatus = MIXER_IDLE;
+ mixer_state mixerStatus = MIXER_IDLE;
// find out which tracks need to be processed
size_t count = activeTracks.size();
size_t mixedTracks = 0;
@@ -2609,7 +2613,7 @@ void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t ri
bool AudioFlinger::DirectOutputThread::threadLoop()
{
- uint32_t mixerStatus = MIXER_IDLE;
+ mixer_state mixerStatus = MIXER_IDLE;
sp<Track> trackToRemove;
sp<Track> activeTrack;
nsecs_t standbyTime = systemTime();
@@ -3006,7 +3010,7 @@ AudioFlinger::DuplicatingThread::~DuplicatingThread()
bool AudioFlinger::DuplicatingThread::threadLoop()
{
Vector< sp<Track> > tracksToRemove;
- uint32_t mixerStatus = MIXER_IDLE;
+ mixer_state mixerStatus = MIXER_IDLE;
nsecs_t standbyTime = systemTime();
size_t mixBufferSize = mFrameCount*mFrameSize;
SortedVector< sp<OutputTrack> > outputTracks;
@@ -3546,7 +3550,7 @@ status_t AudioFlinger::PlaybackThread::Track::start()
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
- int state = mState;
+ track_state state = mState;
// here the track could be either new, or restarted
// in both cases "unstop" the track
if (mState == PAUSED) {
@@ -3587,7 +3591,7 @@ void AudioFlinger::PlaybackThread::Track::stop()
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
- int state = mState;
+ track_state state = mState;
if (mState > STOPPED) {
mState = STOPPED;
// If the track is not active (PAUSED and buffers full), flush buffers
@@ -4104,6 +4108,10 @@ AudioFlinger::TrackHandle::~TrackHandle() {
mTrack->destroy();
}
+sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
+ return mTrack->getCblk();
+}
+
status_t AudioFlinger::TrackHandle::start() {
return mTrack->start();
}
@@ -4124,10 +4132,6 @@ void AudioFlinger::TrackHandle::pause() {
mTrack->pause();
}
-sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
- return mTrack->getCblk();
-}
-
status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
{
return mTrack->attachAuxEffect(EffectId);
@@ -4234,6 +4238,10 @@ AudioFlinger::RecordHandle::~RecordHandle() {
stop();
}
+sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
+ return mRecordTrack->getCblk();
+}
+
status_t AudioFlinger::RecordHandle::start() {
ALOGV("RecordHandle::start()");
return mRecordTrack->start();
@@ -4244,10 +4252,6 @@ void AudioFlinger::RecordHandle::stop() {
mRecordTrack->stop();
}
-sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
- return mRecordTrack->getCblk();
-}
-
status_t AudioFlinger::RecordHandle::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -4894,7 +4898,7 @@ AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track()
return mTrack;
}
-AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::getInput()
+AudioFlinger::AudioStreamIn* AudioFlinger::RecordThread::getInput() const
{
Mutex::Autolock _l(mLock);
return mInput;
@@ -5042,6 +5046,7 @@ status_t AudioFlinger::closeOutput(int output)
if (thread->type() != ThreadBase::DUPLICATING) {
AudioStreamOut *out = thread->clearOutput();
+ assert(out != NULL);
// from now on thread->mOutput is NULL
out->hwDev->close_output_stream(out->hwDev, out->stream);
delete out;
@@ -5183,6 +5188,7 @@ status_t AudioFlinger::closeInput(int input)
thread->exit();
AudioStreamIn *in = thread->clearInput();
+ assert(in != NULL);
// from now on thread->mInput is NULL
in->hwDev->close_input_stream(in->hwDev, in->stream);
delete in;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 48edfcd428c4..766ba44343bb 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -375,7 +375,7 @@ private:
void* mBufferEnd;
uint32_t mFrameCount;
// we don't really need a lock for these
- int mState;
+ track_state mState;
int mClientTid;
audio_format_t mFormat;
uint32_t mFlags;
@@ -727,7 +727,7 @@ private:
int sessionId,
status_t *status);
- AudioStreamOut* getOutput();
+ AudioStreamOut* getOutput() const;
AudioStreamOut* clearOutput();
virtual audio_stream_t* stream();
@@ -804,7 +804,7 @@ private:
SortedVector< sp<Track> > mTracks;
// mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by DuplicatingThread
stream_type_t mStreamTypes[AUDIO_STREAM_CNT + 1];
- AudioStreamOut* mOutput;
+ AudioStreamOut *mOutput;
float mMasterVolume;
nsecs_t mLastWriteTime;
int mNumWrites;
@@ -828,7 +828,7 @@ private:
virtual status_t dumpInternals(int fd, const Vector<String16>& args);
protected:
- uint32_t prepareTracks_l(const SortedVector< wp<Track> >& activeTracks,
+ mixer_state prepareTracks_l(const SortedVector< wp<Track> >& activeTracks,
Vector< sp<Track> > *tracksToRemove);
virtual int getTrackName_l();
virtual void deleteTrackName_l(int name);
@@ -836,8 +836,7 @@ private:
virtual uint32_t suspendSleepTimeUs();
AudioMixer* mAudioMixer;
- uint32_t mPrevMixerStatus; // previous status (mixer_state) returned by
- // prepareTracks_l()
+ mixer_state mPrevMixerStatus; // previous status returned by prepareTracks_l()
};
class DirectOutputThread : public PlaybackThread {
@@ -908,12 +907,12 @@ private:
public:
TrackHandle(const sp<PlaybackThread::Track>& track);
virtual ~TrackHandle();
+ virtual sp<IMemory> getCblk() const;
virtual status_t start();
virtual void stop();
virtual void flush();
virtual void mute(bool);
virtual void pause();
- virtual sp<IMemory> getCblk() const;
virtual status_t attachAuxEffect(int effectId);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
@@ -994,7 +993,7 @@ private:
status_t start(RecordTrack* recordTrack);
void stop(RecordTrack* recordTrack);
status_t dump(int fd, const Vector<String16>& args);
- AudioStreamIn* getInput();
+ AudioStreamIn* getInput() const;
AudioStreamIn* clearInput();
virtual audio_stream_t* stream();
@@ -1031,9 +1030,9 @@ private:
public:
RecordHandle(const sp<RecordThread::RecordTrack>& recordTrack);
virtual ~RecordHandle();
+ virtual sp<IMemory> getCblk() const;
virtual status_t start();
virtual void stop();
- virtual sp<IMemory> getCblk() const;
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
private:
@@ -1087,7 +1086,7 @@ private:
void reset_l();
status_t configure();
status_t init();
- uint32_t state() {
+ effect_state state() const {
return mState;
}
uint32_t status() {
@@ -1152,8 +1151,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
effect_config_t mConfig; // input and output audio configuration
effect_handle_t mEffectInterface; // Effect module C API
- status_t mStatus; // initialization status
- uint32_t mState; // current activation state (effect_state)
+ status_t mStatus; // initialization status
+ effect_state mState; // current activation state
Vector< wp<EffectHandle> > mHandles; // list of client handles
uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after
// sending disable command.
@@ -1357,17 +1356,21 @@ mutable Mutex mLock; // mutex for process, commands and handl
KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects;
};
+ // AudioStreamOut and AudioStreamIn are immutable, so their fields are const.
+ // For emphasis, we could also make all pointers to them be "const *",
+ // but that would clutter the code unnecessarily.
+
struct AudioStreamOut {
- audio_hw_device_t *hwDev;
- audio_stream_out_t *stream;
+ audio_hw_device_t* const hwDev;
+ audio_stream_out_t* const stream;
AudioStreamOut(audio_hw_device_t *dev, audio_stream_out_t *out) :
hwDev(dev), stream(out) {}
};
struct AudioStreamIn {
- audio_hw_device_t *hwDev;
- audio_stream_in_t *stream;
+ audio_hw_device_t* const hwDev;
+ audio_stream_in_t* const stream;
AudioStreamIn(audio_hw_device_t *dev, audio_stream_in_t *in) :
hwDev(dev), stream(in) {}
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 28b1c892cca0..2df1385f5237 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -287,7 +287,7 @@ void AudioPolicyService::releaseOutput(audio_io_handle_t output)
mpAudioPolicy->release_output(mpAudioPolicy, output);
}
-audio_io_handle_t AudioPolicyService::getInput(int inputSource,
+audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
uint32_t channels,
@@ -297,6 +297,10 @@ audio_io_handle_t AudioPolicyService::getInput(int inputSource,
if (mpAudioPolicy == NULL) {
return 0;
}
+ // already checked by client, but double-check in case the client wrapper is bypassed
+ if (uint32_t(inputSource) >= AUDIO_SOURCE_CNT) {
+ return 0;
+ }
Mutex::Autolock _l(mLock);
audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
format, channels, acoustics);
@@ -305,7 +309,7 @@ audio_io_handle_t AudioPolicyService::getInput(int inputSource,
return input;
}
// create audio pre processors according to input source
- ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource);
+ ssize_t index = mInputSources.indexOfKey(inputSource);
if (index < 0) {
return input;
}
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 9811670d1755..3c0f5eda06cf 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -74,7 +74,7 @@ public:
audio_stream_type_t stream,
int session = 0);
virtual void releaseOutput(audio_io_handle_t output);
- virtual audio_io_handle_t getInput(int inputSource,
+ virtual audio_io_handle_t getInput(audio_source_t inputSource,
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 1f8cf630bc88..296c95ec937e 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -831,7 +831,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
ALOGV("Opening device: %s", devicePath);
- int fd = open(devicePath, O_RDWR);
+ int fd = open(devicePath, O_RDWR | O_CLOEXEC);
if(fd < 0) {
ALOGE("could not open %s, %s\n", devicePath, strerror(errno));
return -1;
@@ -1063,14 +1063,20 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
return -1;
}
+ // Enable wake-lock behavior on kernels that support it.
+ // TODO: Only need this for devices that can really wake the system.
+ bool usingSuspendBlock = ioctl(fd, EVIOCSSUSPENDBLOCK, 1) == 0;
+
ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
- "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s",
+ "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, "
+ "usingSuspendBlock=%s",
deviceId, fd, devicePath, device->identifier.name.string(),
device->classes,
device->configurationFile.string(),
device->keyMap.keyLayoutFile.string(),
device->keyMap.keyCharacterMapFile.string(),
- toString(mBuiltInKeyboardId == deviceId));
+ toString(mBuiltInKeyboardId == deviceId),
+ toString(usingSuspendBlock));
mDevices.add(deviceId, device);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 9f0906203f84..ad64ccd55f4f 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -238,6 +238,8 @@ void InputDispatcher::dispatchOnce() {
nsecs_t nextWakeupTime = LONG_LONG_MAX;
{ // acquire lock
AutoMutex _l(mLock);
+ mDispatcherIsAliveCondition.broadcast();
+
dispatchOnceInnerLocked(&nextWakeupTime);
if (runCommandsLockedInterruptible()) {
@@ -4086,6 +4088,8 @@ void InputDispatcher::dump(String8& dump) {
void InputDispatcher::monitor() {
// Acquire and release the lock to ensure that the dispatcher has not deadlocked.
mLock.lock();
+ mLooper->wake();
+ mDispatcherIsAliveCondition.wait(mLock);
mLock.unlock();
}
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 1478d67f825f..a1d42e1bfa8d 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -862,6 +862,8 @@ private:
Mutex mLock;
+ Condition mDispatcherIsAliveCondition;
+
sp<Looper> mLooper;
EventEntry* mPendingEvent;
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index fa0b3d8ee1da..4be06e43d112 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -278,17 +278,20 @@ void InputReader::loopOnce() {
{ // acquire lock
AutoMutex _l(mLock);
+ mReaderIsAliveCondition.broadcast();
if (count) {
processEventsLocked(mEventBuffer, count);
}
if (!count || timeoutMillis == 0) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ if (now >= mNextTimeout) {
#if DEBUG_RAW_EVENTS
- ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
+ ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
#endif
- mNextTimeout = LLONG_MAX;
- timeoutExpiredLocked(now);
+ mNextTimeout = LLONG_MAX;
+ timeoutExpiredLocked(now);
+ }
}
} // release lock
@@ -772,6 +775,8 @@ void InputReader::dump(String8& dump) {
void InputReader::monitor() {
// Acquire and release the lock to ensure that the reader has not deadlocked.
mLock.lock();
+ mEventHub->wake();
+ mReaderIsAliveCondition.wait(mLock);
mLock.unlock();
// Check the EventHub
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index a122c970b282..ad89a222293e 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -363,6 +363,8 @@ protected:
private:
Mutex mLock;
+ Condition mReaderIsAliveCondition;
+
sp<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
sp<QueuedInputListener> mQueuedListener;
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index b7dc4a29d4d7..a372fb8e06cf 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -992,11 +992,15 @@ private NetworkStateTracker makeWimaxStateTracker() {
NetworkInfo ni = network.getNetworkInfo();
if (ni.isAvailable() == false) {
- if (DBG) log("special network not available");
if (!TextUtils.equals(feature,Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
+ if (DBG) log("special network not available ni=" + ni.getTypeName());
return Phone.APN_TYPE_NOT_AVAILABLE;
} else {
// else make the attempt anyway - probably giving REQUEST_STARTED below
+ if (DBG) {
+ log("special network not available, but try anyway ni=" +
+ ni.getTypeName());
+ }
}
}
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 4dad2092edba..0bcec2e3b3a5 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -142,5 +142,5 @@ option java_package com.android.server
# ---------------------------
# NetworkStatsService.java
# ---------------------------
-51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3),(dev_history_start|2|3)
-51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3),(dev_history_start|2|3)
+51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 56afe7f51414..8cb9d99be32b 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1962,8 +1962,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} else {
mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
}
- NetworkInfo info =
- (NetworkInfo)intent.getExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
+
+ final ConnectivityManager connManager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ final NetworkInfo info = connManager.getActiveNetworkInfo();
// Notify location providers of current network state
synchronized (mLock) {
diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java
index f7fe39ecfd68..a7d19929133b 100644
--- a/services/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/java/com/android/server/NetworkTimeUpdateService.java
@@ -234,8 +234,9 @@ public class NetworkTimeUpdateService {
String action = intent.getAction();
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
// There is connectivity
- NetworkInfo netInfo = (NetworkInfo)intent.getParcelableExtra(
- ConnectivityManager.EXTRA_NETWORK_INFO);
+ final ConnectivityManager connManager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ final NetworkInfo netInfo = connManager.getActiveNetworkInfo();
if (netInfo != null) {
// Verify that it's a WIFI connection
if (netInfo.getState() == NetworkInfo.State.CONNECTED &&
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 51adebef27e7..a71ccb5e536c 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1573,6 +1573,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private long getTotalBytes(NetworkTemplate template, long start, long end) {
try {
return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes();
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "problem reading network stats: " + e);
+ return 0;
} catch (RemoteException e) {
// ignored; service lives in system_server
return 0;
diff --git a/services/java/com/android/server/net/NetworkStatsCollection.java b/services/java/com/android/server/net/NetworkStatsCollection.java
new file mode 100644
index 000000000000..70038d93ee0e
--- /dev/null
+++ b/services/java/com/android/server/net/NetworkStatsCollection.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStats.UID_ALL;
+import static android.net.TrafficStats.UID_REMOVED;
+
+import android.net.NetworkIdentity;
+import android.net.NetworkStats;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.text.format.DateUtils;
+
+import com.android.internal.os.AtomicFile;
+import com.android.internal.util.FileRotator;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.Objects;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ProtocolException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import libcore.io.IoUtils;
+
+/**
+ * Collection of {@link NetworkStatsHistory}, stored based on combined key of
+ * {@link NetworkIdentitySet}, UID, set, and tag. Knows how to persist itself.
+ */
+public class NetworkStatsCollection implements FileRotator.Reader {
+ private static final String TAG = "NetworkStatsCollection";
+
+ /** File header magic number: "ANET" */
+ private static final int FILE_MAGIC = 0x414E4554;
+
+ private static final int VERSION_NETWORK_INIT = 1;
+
+ private static final int VERSION_UID_INIT = 1;
+ private static final int VERSION_UID_WITH_IDENT = 2;
+ private static final int VERSION_UID_WITH_TAG = 3;
+ private static final int VERSION_UID_WITH_SET = 4;
+
+ private static final int VERSION_UNIFIED_INIT = 16;
+
+ private HashMap<Key, NetworkStatsHistory> mStats = Maps.newHashMap();
+
+ private long mBucketDuration;
+
+ private long mStartMillis;
+ private long mEndMillis;
+ private long mTotalBytes;
+ private boolean mDirty;
+
+ public NetworkStatsCollection(long bucketDuration) {
+ mBucketDuration = bucketDuration;
+ reset();
+ }
+
+ public void reset() {
+ mStats.clear();
+ mStartMillis = Long.MAX_VALUE;
+ mEndMillis = Long.MIN_VALUE;
+ mTotalBytes = 0;
+ mDirty = false;
+ }
+
+ public long getStartMillis() {
+ return mStartMillis;
+ }
+
+ public long getEndMillis() {
+ return mEndMillis;
+ }
+
+ public long getTotalBytes() {
+ return mTotalBytes;
+ }
+
+ public boolean isDirty() {
+ return mDirty;
+ }
+
+ public void clearDirty() {
+ mDirty = false;
+ }
+
+ public boolean isEmpty() {
+ return mStartMillis == Long.MAX_VALUE && mEndMillis == Long.MIN_VALUE;
+ }
+
+ /**
+ * Combine all {@link NetworkStatsHistory} in this collection which match
+ * the requested parameters.
+ */
+ public NetworkStatsHistory getHistory(
+ NetworkTemplate template, int uid, int set, int tag, int fields) {
+ final NetworkStatsHistory combined = new NetworkStatsHistory(
+ mBucketDuration, estimateBuckets(), fields);
+ for (Map.Entry<Key, NetworkStatsHistory> entry : mStats.entrySet()) {
+ final Key key = entry.getKey();
+ final boolean setMatches = set == SET_ALL || key.set == set;
+ if (key.uid == uid && setMatches && key.tag == tag
+ && templateMatches(template, key.ident)) {
+ combined.recordEntireHistory(entry.getValue());
+ }
+ }
+ return combined;
+ }
+
+ /**
+ * Summarize all {@link NetworkStatsHistory} in this collection which match
+ * the requested parameters.
+ */
+ public NetworkStats getSummary(NetworkTemplate template, long start, long end) {
+ final long now = System.currentTimeMillis();
+
+ final NetworkStats stats = new NetworkStats(end - start, 24);
+ final NetworkStats.Entry entry = new NetworkStats.Entry();
+ NetworkStatsHistory.Entry historyEntry = null;
+
+ for (Map.Entry<Key, NetworkStatsHistory> mapEntry : mStats.entrySet()) {
+ final Key key = mapEntry.getKey();
+ if (templateMatches(template, key.ident)) {
+ final NetworkStatsHistory history = mapEntry.getValue();
+ historyEntry = history.getValues(start, end, now, historyEntry);
+
+ entry.iface = IFACE_ALL;
+ entry.uid = key.uid;
+ entry.set = key.set;
+ entry.tag = key.tag;
+ entry.rxBytes = historyEntry.rxBytes;
+ entry.rxPackets = historyEntry.rxPackets;
+ entry.txBytes = historyEntry.txBytes;
+ entry.txPackets = historyEntry.txPackets;
+ entry.operations = historyEntry.operations;
+
+ if (!entry.isEmpty()) {
+ stats.combineValues(entry);
+ }
+ }
+ }
+
+ return stats;
+ }
+
+ /**
+ * Record given {@link NetworkStats.Entry} into this collection.
+ */
+ public void recordData(NetworkIdentitySet ident, int uid, int set, int tag, long start,
+ long end, NetworkStats.Entry entry) {
+ noteRecordedHistory(start, end, entry.rxBytes + entry.txBytes);
+ findOrCreateHistory(ident, uid, set, tag).recordData(start, end, entry);
+ }
+
+ /**
+ * Record given {@link NetworkStatsHistory} into this collection.
+ */
+ private void recordHistory(Key key, NetworkStatsHistory history) {
+ if (history.size() == 0) return;
+ noteRecordedHistory(history.getStart(), history.getEnd(), history.getTotalBytes());
+
+ final NetworkStatsHistory existing = mStats.get(key);
+ if (existing != null) {
+ existing.recordEntireHistory(history);
+ } else {
+ mStats.put(key, history);
+ }
+ }
+
+ /**
+ * Record all {@link NetworkStatsHistory} contained in the given collection
+ * into this collection.
+ */
+ public void recordCollection(NetworkStatsCollection another) {
+ for (Map.Entry<Key, NetworkStatsHistory> entry : another.mStats.entrySet()) {
+ recordHistory(entry.getKey(), entry.getValue());
+ }
+ }
+
+ private NetworkStatsHistory findOrCreateHistory(
+ NetworkIdentitySet ident, int uid, int set, int tag) {
+ final Key key = new Key(ident, uid, set, tag);
+ final NetworkStatsHistory existing = mStats.get(key);
+
+ // update when no existing, or when bucket duration changed
+ NetworkStatsHistory updated = null;
+ if (existing == null) {
+ updated = new NetworkStatsHistory(mBucketDuration, 10);
+ } else if (existing.getBucketDuration() != mBucketDuration) {
+ updated = new NetworkStatsHistory(existing, mBucketDuration);
+ }
+
+ if (updated != null) {
+ mStats.put(key, updated);
+ return updated;
+ } else {
+ return existing;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void read(InputStream in) throws IOException {
+ read(new DataInputStream(in));
+ }
+
+ public void read(DataInputStream in) throws IOException {
+ // verify file magic header intact
+ final int magic = in.readInt();
+ if (magic != FILE_MAGIC) {
+ throw new ProtocolException("unexpected magic: " + magic);
+ }
+
+ final int version = in.readInt();
+ switch (version) {
+ case VERSION_UNIFIED_INIT: {
+ // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
+ final int identSize = in.readInt();
+ for (int i = 0; i < identSize; i++) {
+ final NetworkIdentitySet ident = new NetworkIdentitySet(in);
+
+ final int size = in.readInt();
+ for (int j = 0; j < size; j++) {
+ final int uid = in.readInt();
+ final int set = in.readInt();
+ final int tag = in.readInt();
+
+ final Key key = new Key(ident, uid, set, tag);
+ final NetworkStatsHistory history = new NetworkStatsHistory(in);
+ recordHistory(key, history);
+ }
+ }
+ break;
+ }
+ default: {
+ throw new ProtocolException("unexpected version: " + version);
+ }
+ }
+ }
+
+ public void write(DataOutputStream out) throws IOException {
+ // cluster key lists grouped by ident
+ final HashMap<NetworkIdentitySet, ArrayList<Key>> keysByIdent = Maps.newHashMap();
+ for (Key key : mStats.keySet()) {
+ ArrayList<Key> keys = keysByIdent.get(key.ident);
+ if (keys == null) {
+ keys = Lists.newArrayList();
+ keysByIdent.put(key.ident, keys);
+ }
+ keys.add(key);
+ }
+
+ out.writeInt(FILE_MAGIC);
+ out.writeInt(VERSION_UNIFIED_INIT);
+
+ out.writeInt(keysByIdent.size());
+ for (NetworkIdentitySet ident : keysByIdent.keySet()) {
+ final ArrayList<Key> keys = keysByIdent.get(ident);
+ ident.writeToStream(out);
+
+ out.writeInt(keys.size());
+ for (Key key : keys) {
+ final NetworkStatsHistory history = mStats.get(key);
+ out.writeInt(key.uid);
+ out.writeInt(key.set);
+ out.writeInt(key.tag);
+ history.writeToStream(out);
+ }
+ }
+
+ out.flush();
+ }
+
+ @Deprecated
+ public void readLegacyNetwork(File file) throws IOException {
+ final AtomicFile inputFile = new AtomicFile(file);
+
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
+
+ // verify file magic header intact
+ final int magic = in.readInt();
+ if (magic != FILE_MAGIC) {
+ throw new ProtocolException("unexpected magic: " + magic);
+ }
+
+ final int version = in.readInt();
+ switch (version) {
+ case VERSION_NETWORK_INIT: {
+ // network := size *(NetworkIdentitySet NetworkStatsHistory)
+ final int size = in.readInt();
+ for (int i = 0; i < size; i++) {
+ final NetworkIdentitySet ident = new NetworkIdentitySet(in);
+ final NetworkStatsHistory history = new NetworkStatsHistory(in);
+
+ final Key key = new Key(ident, UID_ALL, SET_ALL, TAG_NONE);
+ recordHistory(key, history);
+ }
+ break;
+ }
+ default: {
+ throw new ProtocolException("unexpected version: " + version);
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // missing stats is okay, probably first boot
+ } finally {
+ IoUtils.closeQuietly(in);
+ }
+ }
+
+ @Deprecated
+ public void readLegacyUid(File file, boolean onlyTags) throws IOException {
+ final AtomicFile inputFile = new AtomicFile(file);
+
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
+
+ // verify file magic header intact
+ final int magic = in.readInt();
+ if (magic != FILE_MAGIC) {
+ throw new ProtocolException("unexpected magic: " + magic);
+ }
+
+ final int version = in.readInt();
+ switch (version) {
+ case VERSION_UID_INIT: {
+ // uid := size *(UID NetworkStatsHistory)
+
+ // drop this data version, since we don't have a good
+ // mapping into NetworkIdentitySet.
+ break;
+ }
+ case VERSION_UID_WITH_IDENT: {
+ // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory))
+
+ // drop this data version, since this version only existed
+ // for a short time.
+ break;
+ }
+ case VERSION_UID_WITH_TAG:
+ case VERSION_UID_WITH_SET: {
+ // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
+ final int identSize = in.readInt();
+ for (int i = 0; i < identSize; i++) {
+ final NetworkIdentitySet ident = new NetworkIdentitySet(in);
+
+ final int size = in.readInt();
+ for (int j = 0; j < size; j++) {
+ final int uid = in.readInt();
+ final int set = (version >= VERSION_UID_WITH_SET) ? in.readInt()
+ : SET_DEFAULT;
+ final int tag = in.readInt();
+
+ final Key key = new Key(ident, uid, set, tag);
+ final NetworkStatsHistory history = new NetworkStatsHistory(in);
+
+ if ((tag == TAG_NONE) != onlyTags) {
+ recordHistory(key, history);
+ }
+ }
+ }
+ break;
+ }
+ default: {
+ throw new ProtocolException("unexpected version: " + version);
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // missing stats is okay, probably first boot
+ } finally {
+ IoUtils.closeQuietly(in);
+ }
+ }
+
+ /**
+ * Remove any {@link NetworkStatsHistory} attributed to the requested UID,
+ * moving any {@link NetworkStats#TAG_NONE} series to
+ * {@link TrafficStats#UID_REMOVED}.
+ */
+ public void removeUid(int uid) {
+ final ArrayList<Key> knownKeys = Lists.newArrayList();
+ knownKeys.addAll(mStats.keySet());
+
+ // migrate all UID stats into special "removed" bucket
+ for (Key key : knownKeys) {
+ if (key.uid == uid) {
+ // only migrate combined TAG_NONE history
+ if (key.tag == TAG_NONE) {
+ final NetworkStatsHistory uidHistory = mStats.get(key);
+ final NetworkStatsHistory removedHistory = findOrCreateHistory(
+ key.ident, UID_REMOVED, SET_DEFAULT, TAG_NONE);
+ removedHistory.recordEntireHistory(uidHistory);
+ }
+ mStats.remove(key);
+ mDirty = true;
+ }
+ }
+ }
+
+ private void noteRecordedHistory(long startMillis, long endMillis, long totalBytes) {
+ if (startMillis < mStartMillis) mStartMillis = startMillis;
+ if (endMillis > mEndMillis) mEndMillis = endMillis;
+ mTotalBytes += totalBytes;
+ mDirty = true;
+ }
+
+ private int estimateBuckets() {
+ return (int) (Math.min(mEndMillis - mStartMillis, DateUtils.WEEK_IN_MILLIS * 5)
+ / mBucketDuration);
+ }
+
+ public void dump(IndentingPrintWriter pw) {
+ final ArrayList<Key> keys = Lists.newArrayList();
+ keys.addAll(mStats.keySet());
+ Collections.sort(keys);
+
+ for (Key key : keys) {
+ pw.print("ident="); pw.print(key.ident.toString());
+ pw.print(" uid="); pw.print(key.uid);
+ pw.print(" set="); pw.print(NetworkStats.setToString(key.set));
+ pw.print(" tag="); pw.println(NetworkStats.tagToString(key.tag));
+
+ final NetworkStatsHistory history = mStats.get(key);
+ pw.increaseIndent();
+ history.dump(pw, true);
+ pw.decreaseIndent();
+ }
+ }
+
+ /**
+ * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity}
+ * in the given {@link NetworkIdentitySet}.
+ */
+ private static boolean templateMatches(NetworkTemplate template, NetworkIdentitySet identSet) {
+ for (NetworkIdentity ident : identSet) {
+ if (template.matches(ident)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static class Key implements Comparable<Key> {
+ public final NetworkIdentitySet ident;
+ public final int uid;
+ public final int set;
+ public final int tag;
+
+ private final int hashCode;
+
+ public Key(NetworkIdentitySet ident, int uid, int set, int tag) {
+ this.ident = ident;
+ this.uid = uid;
+ this.set = set;
+ this.tag = tag;
+ hashCode = Objects.hashCode(ident, uid, set, tag);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Key) {
+ final Key key = (Key) obj;
+ return uid == key.uid && set == key.set && tag == key.tag
+ && Objects.equal(ident, key.ident);
+ }
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ public int compareTo(Key another) {
+ return Integer.compare(uid, another.uid);
+ }
+ }
+}
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
new file mode 100644
index 000000000000..e7ba35888d97
--- /dev/null
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import static android.net.NetworkStats.TAG_NONE;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.net.NetworkStats;
+import android.net.NetworkStats.NonMonotonicObserver;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
+import android.net.TrafficStats;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.util.FileRotator;
+import com.android.internal.util.IndentingPrintWriter;
+import com.google.android.collect.Sets;
+
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Logic to record deltas between periodic {@link NetworkStats} snapshots into
+ * {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
+ * Keeps pending changes in memory until they pass a specific threshold, in
+ * bytes. Uses {@link FileRotator} for persistence logic.
+ * <p>
+ * Not inherently thread safe.
+ */
+public class NetworkStatsRecorder {
+ private static final String TAG = "NetworkStatsRecorder";
+ private static final boolean LOGD = true;
+
+ private final FileRotator mRotator;
+ private final NonMonotonicObserver<String> mObserver;
+ private final String mCookie;
+
+ private final long mBucketDuration;
+ private final long mPersistThresholdBytes;
+ private final boolean mOnlyTags;
+
+ private NetworkStats mLastSnapshot;
+
+ private final NetworkStatsCollection mPending;
+ private final NetworkStatsCollection mSinceBoot;
+
+ private final CombiningRewriter mPendingRewriter;
+
+ private WeakReference<NetworkStatsCollection> mComplete;
+
+ public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
+ String cookie, long bucketDuration, long persistThresholdBytes, boolean onlyTags) {
+ mRotator = checkNotNull(rotator, "missing FileRotator");
+ mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
+ mCookie = cookie;
+
+ mBucketDuration = bucketDuration;
+ mPersistThresholdBytes = persistThresholdBytes;
+ mOnlyTags = onlyTags;
+
+ mPending = new NetworkStatsCollection(bucketDuration);
+ mSinceBoot = new NetworkStatsCollection(bucketDuration);
+
+ mPendingRewriter = new CombiningRewriter(mPending);
+ }
+
+ public void resetLocked() {
+ mLastSnapshot = null;
+ mPending.reset();
+ mSinceBoot.reset();
+ mComplete.clear();
+ }
+
+ public NetworkStats.Entry getTotalSinceBootLocked(NetworkTemplate template) {
+ return mSinceBoot.getSummary(template, Long.MIN_VALUE, Long.MAX_VALUE).getTotal(null);
+ }
+
+ /**
+ * Load complete history represented by {@link FileRotator}. Caches
+ * internally as a {@link WeakReference}, and updated with future
+ * {@link #recordSnapshotLocked(NetworkStats, Map, long)} snapshots as long
+ * as reference is valid.
+ */
+ public NetworkStatsCollection getOrLoadCompleteLocked() {
+ NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
+ if (complete == null) {
+ if (LOGD) Slog.d(TAG, "getOrLoadCompleteLocked() reading from disk for " + mCookie);
+ try {
+ complete = new NetworkStatsCollection(mBucketDuration);
+ mRotator.readMatching(complete, Long.MIN_VALUE, Long.MAX_VALUE);
+ complete.recordCollection(mPending);
+ mComplete = new WeakReference<NetworkStatsCollection>(complete);
+ } catch (IOException e) {
+ Log.wtf(TAG, "problem completely reading network stats", e);
+ }
+ }
+ return complete;
+ }
+
+ /**
+ * Record any delta that occurred since last {@link NetworkStats} snapshot,
+ * using the given {@link Map} to identify network interfaces. First
+ * snapshot is considered bootstrap, and is not counted as delta.
+ */
+ public void recordSnapshotLocked(NetworkStats snapshot,
+ Map<String, NetworkIdentitySet> ifaceIdent, long currentTimeMillis) {
+ final HashSet<String> unknownIfaces = Sets.newHashSet();
+
+ // assume first snapshot is bootstrap and don't record
+ if (mLastSnapshot == null) {
+ mLastSnapshot = snapshot;
+ return;
+ }
+
+ final NetworkStatsCollection complete = mComplete != null ? mComplete.get() : null;
+
+ final NetworkStats delta = NetworkStats.subtract(
+ snapshot, mLastSnapshot, mObserver, mCookie);
+ final long end = currentTimeMillis;
+ final long start = end - delta.getElapsedRealtime();
+
+ NetworkStats.Entry entry = null;
+ for (int i = 0; i < delta.size(); i++) {
+ entry = delta.getValues(i, entry);
+ final NetworkIdentitySet ident = ifaceIdent.get(entry.iface);
+ if (ident == null) {
+ unknownIfaces.add(entry.iface);
+ continue;
+ }
+
+ // skip when no delta occured
+ if (entry.isEmpty()) continue;
+
+ // only record tag data when requested
+ if ((entry.tag == TAG_NONE) != mOnlyTags) {
+ mPending.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
+
+ // also record against boot stats when present
+ if (mSinceBoot != null) {
+ mSinceBoot.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
+ }
+
+ // also record against complete dataset when present
+ if (complete != null) {
+ complete.recordData(ident, entry.uid, entry.set, entry.tag, start, end, entry);
+ }
+ }
+ }
+
+ mLastSnapshot = snapshot;
+
+ if (LOGD && unknownIfaces.size() > 0) {
+ Slog.w(TAG, "unknown interfaces " + unknownIfaces + ", ignoring those stats");
+ }
+ }
+
+ /**
+ * Consider persisting any pending deltas, if they are beyond
+ * {@link #mPersistThresholdBytes}.
+ */
+ public void maybePersistLocked(long currentTimeMillis) {
+ final long pendingBytes = mPending.getTotalBytes();
+ if (pendingBytes >= mPersistThresholdBytes) {
+ forcePersistLocked(currentTimeMillis);
+ } else {
+ mRotator.maybeRotate(currentTimeMillis);
+ }
+ }
+
+ /**
+ * Force persisting any pending deltas.
+ */
+ public void forcePersistLocked(long currentTimeMillis) {
+ if (mPending.isDirty()) {
+ if (LOGD) Slog.d(TAG, "forcePersistLocked() writing for " + mCookie);
+ try {
+ mRotator.rewriteActive(mPendingRewriter, currentTimeMillis);
+ mRotator.maybeRotate(currentTimeMillis);
+ mPending.reset();
+ } catch (IOException e) {
+ Log.wtf(TAG, "problem persisting pending stats", e);
+ }
+ }
+ }
+
+ /**
+ * Remove the given UID from all {@link FileRotator} history, migrating it
+ * to {@link TrafficStats#UID_REMOVED}.
+ */
+ public void removeUidLocked(int uid) {
+ try {
+ // process all existing data to migrate uid
+ mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid));
+ } catch (IOException e) {
+ Log.wtf(TAG, "problem removing UID " + uid, e);
+ }
+
+ // clear UID from current stats snapshot
+ if (mLastSnapshot != null) {
+ mLastSnapshot = mLastSnapshot.withoutUid(uid);
+ }
+ }
+
+ /**
+ * Rewriter that will combine current {@link NetworkStatsCollection} values
+ * with anything read from disk, and write combined set to disk. Clears the
+ * original {@link NetworkStatsCollection} when finished writing.
+ */
+ private static class CombiningRewriter implements FileRotator.Rewriter {
+ private final NetworkStatsCollection mCollection;
+
+ public CombiningRewriter(NetworkStatsCollection collection) {
+ mCollection = checkNotNull(collection, "missing NetworkStatsCollection");
+ }
+
+ /** {@inheritDoc} */
+ public void reset() {
+ // ignored
+ }
+
+ /** {@inheritDoc} */
+ public void read(InputStream in) throws IOException {
+ mCollection.read(in);
+ }
+
+ /** {@inheritDoc} */
+ public boolean shouldWrite() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ public void write(OutputStream out) throws IOException {
+ mCollection.write(new DataOutputStream(out));
+ mCollection.reset();
+ }
+ }
+
+ /**
+ * Rewriter that will remove any {@link NetworkStatsHistory} attributed to
+ * the requested UID, only writing data back when modified.
+ */
+ public static class RemoveUidRewriter implements FileRotator.Rewriter {
+ private final NetworkStatsCollection mTemp;
+ private final int mUid;
+
+ public RemoveUidRewriter(long bucketDuration, int uid) {
+ mTemp = new NetworkStatsCollection(bucketDuration);
+ mUid = uid;
+ }
+
+ /** {@inheritDoc} */
+ public void reset() {
+ mTemp.reset();
+ }
+
+ /** {@inheritDoc} */
+ public void read(InputStream in) throws IOException {
+ mTemp.read(in);
+ mTemp.clearDirty();
+ mTemp.removeUid(mUid);
+ }
+
+ /** {@inheritDoc} */
+ public boolean shouldWrite() {
+ return mTemp.isDirty();
+ }
+
+ /** {@inheritDoc} */
+ public void write(OutputStream out) throws IOException {
+ mTemp.write(new DataOutputStream(out));
+ }
+ }
+
+ public void importLegacyNetworkLocked(File file) throws IOException {
+ // legacy file still exists; start empty to avoid double importing
+ mRotator.deleteAll();
+
+ final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
+ collection.readLegacyNetwork(file);
+
+ final long startMillis = collection.getStartMillis();
+ final long endMillis = collection.getEndMillis();
+
+ if (!collection.isEmpty()) {
+ // process legacy data, creating active file at starting time, then
+ // using end time to possibly trigger rotation.
+ mRotator.rewriteActive(new CombiningRewriter(collection), startMillis);
+ mRotator.maybeRotate(endMillis);
+ }
+ }
+
+ public void importLegacyUidLocked(File file) throws IOException {
+ // legacy file still exists; start empty to avoid double importing
+ mRotator.deleteAll();
+
+ final NetworkStatsCollection collection = new NetworkStatsCollection(mBucketDuration);
+ collection.readLegacyUid(file, mOnlyTags);
+
+ final long startMillis = collection.getStartMillis();
+ final long endMillis = collection.getEndMillis();
+
+ if (!collection.isEmpty()) {
+ // process legacy data, creating active file at starting time, then
+ // using end time to possibly trigger rotation.
+ mRotator.rewriteActive(new CombiningRewriter(collection), startMillis);
+ mRotator.maybeRotate(endMillis);
+ }
+ }
+
+ public void dumpLocked(IndentingPrintWriter pw, boolean fullHistory) {
+ pw.print("Pending bytes: "); pw.println(mPending.getTotalBytes());
+ if (fullHistory) {
+ pw.println("Complete history:");
+ getOrLoadCompleteLocked().dump(pw);
+ } else {
+ pw.println("History since boot:");
+ mSinceBoot.dump(pw);
+ }
+ }
+}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index eeb7fec8e176..7930caf84763 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -34,14 +34,18 @@ import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
-import static android.net.TrafficStats.UID_REMOVED;
-import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;
-import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY;
-import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD;
+import static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
+import static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
+import static android.provider.Settings.Secure.NETSTATS_DEV_PERSIST_BYTES;
+import static android.provider.Settings.Secure.NETSTATS_DEV_ROTATE_AGE;
+import static android.provider.Settings.Secure.NETSTATS_GLOBAL_ALERT_BYTES;
import static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
-import static android.provider.Settings.Secure.NETSTATS_TAG_MAX_HISTORY;
+import static android.provider.Settings.Secure.NETSTATS_SAMPLE_ENABLED;
+import static android.provider.Settings.Secure.NETSTATS_TIME_CACHE_MAX_AGE;
import static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
-import static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY;
+import static android.provider.Settings.Secure.NETSTATS_UID_DELETE_AGE;
+import static android.provider.Settings.Secure.NETSTATS_UID_PERSIST_BYTES;
+import static android.provider.Settings.Secure.NETSTATS_UID_ROTATE_AGE;
import static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
import static android.telephony.PhoneStateListener.LISTEN_NONE;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
@@ -61,12 +65,10 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsService;
+import android.net.LinkProperties;
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
import android.net.NetworkState;
@@ -74,6 +76,7 @@ import android.net.NetworkStats;
import android.net.NetworkStats.NonMonotonicObserver;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
+import android.net.TrafficStats;
import android.os.Binder;
import android.os.DropBoxManager;
import android.os.Environment;
@@ -94,32 +97,18 @@ import android.util.Slog;
import android.util.SparseIntArray;
import android.util.TrustedTime;
-import com.android.internal.os.AtomicFile;
-import com.android.internal.util.Objects;
+import com.android.internal.util.FileRotator;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.server.EventLogTags;
import com.android.server.connectivity.Tethering;
-import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-import java.net.ProtocolException;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Random;
-
-import libcore.io.IoUtils;
/**
* Collect and persist detailed network statistics, and provide this data to
@@ -127,16 +116,8 @@ import libcore.io.IoUtils;
*/
public class NetworkStatsService extends INetworkStatsService.Stub {
private static final String TAG = "NetworkStats";
- private static final boolean LOGD = false;
- private static final boolean LOGV = false;
-
- /** File header magic number: "ANET" */
- private static final int FILE_MAGIC = 0x414E4554;
- private static final int VERSION_NETWORK_INIT = 1;
- private static final int VERSION_UID_INIT = 1;
- private static final int VERSION_UID_WITH_IDENT = 2;
- private static final int VERSION_UID_WITH_TAG = 3;
- private static final int VERSION_UID_WITH_SET = 4;
+ private static final boolean LOGD = true;
+ private static final boolean LOGV = true;
private static final int MSG_PERFORM_POLL = 1;
private static final int MSG_UPDATE_IFACES = 2;
@@ -147,9 +128,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
private static final int FLAG_PERSIST_FORCE = 0x100;
- /** Sample recent usage after each poll event. */
- private static final boolean ENABLE_SAMPLE_AFTER_POLL = true;
-
private static final String TAG_NETSTATS_ERROR = "netstats_error";
private final Context mContext;
@@ -159,10 +137,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final TelephonyManager mTeleManager;
private final NetworkStatsSettings mSettings;
+ private final File mSystemDir;
+ private final File mBaseDir;
+
private final PowerManager.WakeLock mWakeLock;
private IConnectivityManager mConnManager;
- private DropBoxManager mDropBox;
// @VisibleForTesting
public static final String ACTION_NETWORK_STATS_POLL =
@@ -172,71 +152,76 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private PendingIntent mPollIntent;
- // TODO: trim empty history objects entirely
-
private static final long KB_IN_BYTES = 1024;
private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES;
private static final long GB_IN_BYTES = 1024 * MB_IN_BYTES;
+ private static final String PREFIX_DEV = "dev";
+ private static final String PREFIX_UID = "uid";
+ private static final String PREFIX_UID_TAG = "uid_tag";
+
/**
* Settings that can be changed externally.
*/
public interface NetworkStatsSettings {
public long getPollInterval();
- public long getPersistThreshold();
- public long getNetworkBucketDuration();
- public long getNetworkMaxHistory();
- public long getUidBucketDuration();
- public long getUidMaxHistory();
- public long getTagMaxHistory();
public long getTimeCacheMaxAge();
+ public long getGlobalAlertBytes();
+ public boolean getSampleEnabled();
+
+ public static class Config {
+ public final long bucketDuration;
+ public final long persistBytes;
+ public final long rotateAgeMillis;
+ public final long deleteAgeMillis;
+
+ public Config(long bucketDuration, long persistBytes, long rotateAgeMillis,
+ long deleteAgeMillis) {
+ this.bucketDuration = bucketDuration;
+ this.persistBytes = persistBytes;
+ this.rotateAgeMillis = rotateAgeMillis;
+ this.deleteAgeMillis = deleteAgeMillis;
+ }
+ }
+
+ public Config getDevConfig();
+ public Config getUidConfig();
+ public Config getUidTagConfig();
}
private final Object mStatsLock = new Object();
/** Set of currently active ifaces. */
private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
- /** Set of historical {@code dev} stats for known networks. */
- private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkDevStats = Maps.newHashMap();
- /** Set of historical {@code xtables} stats for known networks. */
- private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkXtStats = Maps.newHashMap();
- /** Set of historical {@code xtables} stats for known UIDs. */
- private HashMap<UidStatsKey, NetworkStatsHistory> mUidStats = Maps.newHashMap();
-
- /** Flag if {@link #mNetworkDevStats} have been loaded from disk. */
- private boolean mNetworkStatsLoaded = false;
- /** Flag if {@link #mUidStats} have been loaded from disk. */
- private boolean mUidStatsLoaded = false;
-
- private NetworkStats mLastPollNetworkDevSnapshot;
- private NetworkStats mLastPollNetworkXtSnapshot;
- private NetworkStats mLastPollUidSnapshot;
- private NetworkStats mLastPollOperationsSnapshot;
-
- private NetworkStats mLastPersistNetworkDevSnapshot;
- private NetworkStats mLastPersistNetworkXtSnapshot;
- private NetworkStats mLastPersistUidSnapshot;
+ /** Current default active iface. */
+ private String mActiveIface;
+
+ private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
+ new DropBoxNonMonotonicObserver();
+
+ private NetworkStatsRecorder mDevRecorder;
+ private NetworkStatsRecorder mUidRecorder;
+ private NetworkStatsRecorder mUidTagRecorder;
+
+ /** Cached {@link #mDevRecorder} stats. */
+ private NetworkStatsCollection mDevStatsCached;
/** Current counter sets for each UID. */
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
/** Data layer operation counters for splicing into other structures. */
- private NetworkStats mOperations = new NetworkStats(0L, 10);
+ private NetworkStats mUidOperations = new NetworkStats(0L, 10);
private final HandlerThread mHandlerThread;
private final Handler mHandler;
- private final AtomicFile mNetworkDevFile;
- private final AtomicFile mNetworkXtFile;
- private final AtomicFile mUidFile;
-
public NetworkStatsService(
Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
- getSystemDir(), new DefaultNetworkStatsSettings(context));
+ getDefaultSystemDir(), new DefaultNetworkStatsSettings(context));
}
- private static File getSystemDir() {
+ private static File getDefaultSystemDir() {
return new File(Environment.getDataDirectory(), "system");
}
@@ -258,9 +243,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
- mNetworkDevFile = new AtomicFile(new File(systemDir, "netstats.bin"));
- mNetworkXtFile = new AtomicFile(new File(systemDir, "netstats_xt.bin"));
- mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin"));
+ mSystemDir = checkNotNull(systemDir);
+ mBaseDir = new File(systemDir, "netstats");
+ mBaseDir.mkdirs();
}
public void bindConnectivityManager(IConnectivityManager connManager) {
@@ -273,17 +258,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return;
}
+ // create data recorders along with historical rotators
+ mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
+ mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
+ mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
+
synchronized (mStatsLock) {
+ // upgrade any legacy stats, migrating them to rotated files
+ maybeUpgradeLegacyStatsLocked();
+
// read historical network stats from disk, since policy service
- // might need them right away. we delay loading detailed UID stats
- // until actually needed.
- readNetworkDevStatsLocked();
- readNetworkXtStatsLocked();
- mNetworkStatsLoaded = true;
- }
+ // might need them right away.
+ mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked();
- // bootstrap initial stats to prevent double-counting later
- bootstrapStats();
+ // bootstrap initial stats to prevent double-counting later
+ bootstrapStatsLocked();
+ }
// watch for network interfaces to be claimed
final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE);
@@ -317,8 +307,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
registerPollAlarmLocked();
registerGlobalAlert();
+ }
- mDropBox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE);
+ private NetworkStatsRecorder buildRecorder(
+ String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
+ return new NetworkStatsRecorder(
+ new FileRotator(mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
+ mNonMonotonicObserver, prefix, config.bucketDuration, config.persistBytes,
+ includeTags);
}
private void shutdownLocked() {
@@ -330,18 +326,44 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mTeleManager.listen(mPhoneListener, LISTEN_NONE);
- if (mNetworkStatsLoaded) {
- writeNetworkDevStatsLocked();
- writeNetworkXtStatsLocked();
- }
- if (mUidStatsLoaded) {
- writeUidStatsLocked();
+ final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
+ : System.currentTimeMillis();
+
+ // persist any pending stats
+ mDevRecorder.forcePersistLocked(currentTime);
+ mUidRecorder.forcePersistLocked(currentTime);
+ mUidTagRecorder.forcePersistLocked(currentTime);
+
+ mDevRecorder = null;
+ mUidRecorder = null;
+ mUidTagRecorder = null;
+
+ mDevStatsCached = null;
+ }
+
+ private void maybeUpgradeLegacyStatsLocked() {
+ File file;
+ try {
+ file = new File(mSystemDir, "netstats.bin");
+ if (file.exists()) {
+ mDevRecorder.importLegacyNetworkLocked(file);
+ file.delete();
+ }
+
+ file = new File(mSystemDir, "netstats_xt.bin");
+ if (file.exists()) {
+ file.delete();
+ }
+
+ file = new File(mSystemDir, "netstats_uid.bin");
+ if (file.exists()) {
+ mUidRecorder.importLegacyUidLocked(file);
+ mUidTagRecorder.importLegacyUidLocked(file);
+ file.delete();
+ }
+ } catch (IOException e) {
+ Log.wtf(TAG, "problem during legacy upgrade", e);
}
- mNetworkDevStats.clear();
- mNetworkXtStats.clear();
- mUidStats.clear();
- mNetworkStatsLoaded = false;
- mUidStatsLoaded = false;
}
/**
@@ -372,7 +394,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
*/
private void registerGlobalAlert() {
try {
- final long alertBytes = mSettings.getPersistThreshold();
+ final long alertBytes = mSettings.getGlobalAlertBytes();
mNetworkManager.setGlobalAlert(alertBytes);
} catch (IllegalStateException e) {
Slog.w(TAG, "problem registering for global alert: " + e);
@@ -383,161 +405,39 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
- mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
- return getHistoryForNetworkDev(template, fields);
- }
-
- private NetworkStatsHistory getHistoryForNetworkDev(NetworkTemplate template, int fields) {
- return getHistoryForNetwork(template, fields, mNetworkDevStats);
- }
-
- private NetworkStatsHistory getHistoryForNetworkXt(NetworkTemplate template, int fields) {
- return getHistoryForNetwork(template, fields, mNetworkXtStats);
+ return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
}
- private NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields,
- HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
- synchronized (mStatsLock) {
- // combine all interfaces that match template
- final NetworkStatsHistory combined = new NetworkStatsHistory(
- mSettings.getNetworkBucketDuration(), estimateNetworkBuckets(), fields);
- for (NetworkIdentitySet ident : source.keySet()) {
- if (templateMatches(template, ident)) {
- final NetworkStatsHistory history = source.get(ident);
- if (history != null) {
- combined.recordEntireHistory(history);
- }
- }
- }
- return combined;
- }
+ @Override
+ public NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end) {
+ return mDevStatsCached.getSummary(template, start, end);
}
@Override
public NetworkStatsHistory getHistoryForUid(
NetworkTemplate template, int uid, int set, int tag, int fields) {
- mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
-
- synchronized (mStatsLock) {
- ensureUidStatsLoadedLocked();
-
- // combine all interfaces that match template
- final NetworkStatsHistory combined = new NetworkStatsHistory(
- mSettings.getUidBucketDuration(), estimateUidBuckets(), fields);
- for (UidStatsKey key : mUidStats.keySet()) {
- final boolean setMatches = set == SET_ALL || key.set == set;
- if (templateMatches(template, key.ident) && key.uid == uid && setMatches
- && key.tag == tag) {
- final NetworkStatsHistory history = mUidStats.get(key);
- combined.recordEntireHistory(history);
- }
- }
-
- return combined;
- }
- }
-
- @Override
- public NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end) {
- mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
- return getSummaryForNetworkDev(template, start, end);
- }
-
- private NetworkStats getSummaryForNetworkDev(NetworkTemplate template, long start, long end) {
- return getSummaryForNetwork(template, start, end, mNetworkDevStats);
- }
-
- private NetworkStats getSummaryForNetworkXt(NetworkTemplate template, long start, long end) {
- return getSummaryForNetwork(template, start, end, mNetworkXtStats);
- }
-
- private NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end,
- HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
- synchronized (mStatsLock) {
- // use system clock to be externally consistent
- final long now = System.currentTimeMillis();
-
- final NetworkStats stats = new NetworkStats(end - start, 1);
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- NetworkStatsHistory.Entry historyEntry = null;
-
- // combine total from all interfaces that match template
- for (NetworkIdentitySet ident : source.keySet()) {
- if (templateMatches(template, ident)) {
- final NetworkStatsHistory history = source.get(ident);
- historyEntry = history.getValues(start, end, now, historyEntry);
-
- entry.iface = IFACE_ALL;
- entry.uid = UID_ALL;
- entry.tag = TAG_NONE;
- entry.rxBytes = historyEntry.rxBytes;
- entry.rxPackets = historyEntry.rxPackets;
- entry.txBytes = historyEntry.txBytes;
- entry.txPackets = historyEntry.txPackets;
-
- stats.combineValues(entry);
- }
- }
-
- return stats;
- }
- }
-
- private long getHistoryStartLocked(
- NetworkTemplate template, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
- long start = Long.MAX_VALUE;
- for (NetworkIdentitySet ident : source.keySet()) {
- if (templateMatches(template, ident)) {
- final NetworkStatsHistory history = source.get(ident);
- start = Math.min(start, history.getStart());
- }
+ // TODO: transition to stats sessions to avoid WeakReferences
+ if (tag == TAG_NONE) {
+ return mUidRecorder.getOrLoadCompleteLocked().getHistory(
+ template, uid, set, tag, fields);
+ } else {
+ return mUidTagRecorder.getOrLoadCompleteLocked().getHistory(
+ template, uid, set, tag, fields);
}
- return start;
}
@Override
public NetworkStats getSummaryForAllUid(
NetworkTemplate template, long start, long end, boolean includeTags) {
- mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
-
- synchronized (mStatsLock) {
- ensureUidStatsLoadedLocked();
-
- // use system clock to be externally consistent
- final long now = System.currentTimeMillis();
-
- final NetworkStats stats = new NetworkStats(end - start, 24);
- final NetworkStats.Entry entry = new NetworkStats.Entry();
- NetworkStatsHistory.Entry historyEntry = null;
-
- for (UidStatsKey key : mUidStats.keySet()) {
- if (templateMatches(template, key.ident)) {
- // always include summary under TAG_NONE, and include
- // other tags when requested.
- if (key.tag == TAG_NONE || includeTags) {
- final NetworkStatsHistory history = mUidStats.get(key);
- historyEntry = history.getValues(start, end, now, historyEntry);
-
- entry.iface = IFACE_ALL;
- entry.uid = key.uid;
- entry.set = key.set;
- entry.tag = key.tag;
- entry.rxBytes = historyEntry.rxBytes;
- entry.rxPackets = historyEntry.rxPackets;
- entry.txBytes = historyEntry.txBytes;
- entry.txPackets = historyEntry.txPackets;
- entry.operations = historyEntry.operations;
-
- if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
- || entry.txPackets > 0 || entry.operations > 0) {
- stats.combineValues(entry);
- }
- }
- }
- }
-
- return stats;
- }
+ // TODO: transition to stats sessions to avoid WeakReferences
+ final NetworkStats stats = mUidRecorder.getOrLoadCompleteLocked().getSummary(
+ template, start, end);
+ if (includeTags) {
+ final NetworkStats tagStats = mUidTagRecorder.getOrLoadCompleteLocked().getSummary(
+ template, start, end);
+ stats.combineAllValues(tagStats);
+ }
+ return stats;
}
@Override
@@ -567,7 +467,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
// splice in operation counts
- dataLayer.spliceOperationsFrom(mOperations);
+ dataLayer.spliceOperationsFrom(mUidOperations);
return dataLayer;
}
@@ -586,8 +486,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
synchronized (mStatsLock) {
final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
- mOperations.combineValues(IFACE_ALL, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
- mOperations.combineValues(IFACE_ALL, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
+ mUidOperations.combineValues(
+ mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
+ mUidOperations.combineValues(
+ mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
}
}
@@ -608,7 +510,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
- performPoll(FLAG_PERSIST_ALL);
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ performPoll(FLAG_PERSIST_ALL);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
/**
@@ -755,13 +663,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
performPollLocked(FLAG_PERSIST_NETWORK);
final NetworkState[] states;
+ final LinkProperties activeLink;
try {
states = mConnManager.getAllNetworkState();
+ activeLink = mConnManager.getActiveLinkProperties();
} catch (RemoteException e) {
// ignored; service lives in system_server
return;
}
+ mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
+
// rebuild active interfaces based on connected networks
mActiveIfaces.clear();
@@ -785,12 +697,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* Bootstrap initial stats snapshot, usually during {@link #systemReady()}
* so we have baseline values without double-counting.
*/
- private void bootstrapStats() {
+ private void bootstrapStatsLocked() {
+ final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
+ : System.currentTimeMillis();
+
try {
- mLastPollUidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
- mLastPollNetworkDevSnapshot = mNetworkManager.getNetworkStatsSummary();
- mLastPollNetworkXtSnapshot = computeNetworkXtSnapshotFromUid(mLastPollUidSnapshot);
- mLastPollOperationsSnapshot = new NetworkStats(0L, 0);
+ // snapshot and record current counters; read UID stats first to
+ // avoid overcounting dev stats.
+ final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
+ final NetworkStats devSnapshot = getNetworkStatsSummary();
+
+ mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
+ mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
+ mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
+
} catch (IllegalStateException e) {
Slog.w(TAG, "problem reading network stats: " + e);
} catch (RemoteException e) {
@@ -830,27 +750,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// TODO: consider marking "untrusted" times in historical stats
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
: System.currentTimeMillis();
- final long threshold = mSettings.getPersistThreshold();
- final NetworkStats uidSnapshot;
- final NetworkStats networkXtSnapshot;
- final NetworkStats networkDevSnapshot;
try {
- // collect any tethering stats
- final NetworkStats tetherSnapshot = getNetworkStatsTethering();
-
- // record uid stats, folding in tethering stats
- uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
- uidSnapshot.combineAllValues(tetherSnapshot);
- performUidPollLocked(uidSnapshot, currentTime);
-
- // record dev network stats
- networkDevSnapshot = mNetworkManager.getNetworkStatsSummary();
- performNetworkDevPollLocked(networkDevSnapshot, currentTime);
+ // snapshot and record current counters; read UID stats first to
+ // avoid overcounting dev stats.
+ final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
+ final NetworkStats devSnapshot = getNetworkStatsSummary();
- // record xt network stats
- networkXtSnapshot = computeNetworkXtSnapshotFromUid(uidSnapshot);
- performNetworkXtPollLocked(networkXtSnapshot, currentTime);
+ mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
+ mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
+ mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
} catch (IllegalStateException e) {
Log.wtf(TAG, "problem reading network stats", e);
@@ -860,26 +769,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return;
}
- // persist when enough network data has occurred
- final long persistNetworkDevDelta = computeStatsDelta(
- mLastPersistNetworkDevSnapshot, networkDevSnapshot, true, "devp").getTotalBytes();
- final long persistNetworkXtDelta = computeStatsDelta(
- mLastPersistNetworkXtSnapshot, networkXtSnapshot, true, "xtp").getTotalBytes();
- final boolean networkOverThreshold = persistNetworkDevDelta > threshold
- || persistNetworkXtDelta > threshold;
- if (persistForce || (persistNetwork && networkOverThreshold)) {
- writeNetworkDevStatsLocked();
- writeNetworkXtStatsLocked();
- mLastPersistNetworkDevSnapshot = networkDevSnapshot;
- mLastPersistNetworkXtSnapshot = networkXtSnapshot;
- }
-
- // persist when enough uid data has occurred
- final long persistUidDelta = computeStatsDelta(
- mLastPersistUidSnapshot, uidSnapshot, true, "uidp").getTotalBytes();
- if (persistForce || (persistUid && persistUidDelta > threshold)) {
- writeUidStatsLocked();
- mLastPersistUidSnapshot = uidSnapshot;
+ // persist any pending data depending on requested flags
+ if (persistForce) {
+ mDevRecorder.forcePersistLocked(currentTime);
+ mUidRecorder.forcePersistLocked(currentTime);
+ mUidTagRecorder.forcePersistLocked(currentTime);
+ } else {
+ if (persistNetwork) {
+ mDevRecorder.maybePersistLocked(currentTime);
+ }
+ if (persistUid) {
+ mUidRecorder.maybePersistLocked(currentTime);
+ mUidTagRecorder.maybePersistLocked(currentTime);
+ }
}
if (LOGV) {
@@ -887,9 +789,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
Slog.v(TAG, "performPollLocked() took " + duration + "ms");
}
- if (ENABLE_SAMPLE_AFTER_POLL) {
+ if (mSettings.getSampleEnabled()) {
// sample stats after each full poll
- performSample();
+ performSampleLocked();
}
// finally, dispatch updated event to any listeners
@@ -899,511 +801,58 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
- * Update {@link #mNetworkDevStats} historical usage.
- */
- private void performNetworkDevPollLocked(NetworkStats networkDevSnapshot, long currentTime) {
- final HashSet<String> unknownIface = Sets.newHashSet();
-
- final NetworkStats delta = computeStatsDelta(
- mLastPollNetworkDevSnapshot, networkDevSnapshot, false, "dev");
- final long timeStart = currentTime - delta.getElapsedRealtime();
-
- NetworkStats.Entry entry = null;
- for (int i = 0; i < delta.size(); i++) {
- entry = delta.getValues(i, entry);
- final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
- if (ident == null) {
- unknownIface.add(entry.iface);
- continue;
- }
-
- final NetworkStatsHistory history = findOrCreateNetworkDevStatsLocked(ident);
- history.recordData(timeStart, currentTime, entry);
- }
-
- mLastPollNetworkDevSnapshot = networkDevSnapshot;
-
- if (LOGD && unknownIface.size() > 0) {
- Slog.w(TAG, "unknown dev interfaces " + unknownIface + ", ignoring those stats");
- }
- }
-
- /**
- * Update {@link #mNetworkXtStats} historical usage.
- */
- private void performNetworkXtPollLocked(NetworkStats networkXtSnapshot, long currentTime) {
- final HashSet<String> unknownIface = Sets.newHashSet();
-
- final NetworkStats delta = computeStatsDelta(
- mLastPollNetworkXtSnapshot, networkXtSnapshot, false, "xt");
- final long timeStart = currentTime - delta.getElapsedRealtime();
-
- NetworkStats.Entry entry = null;
- for (int i = 0; i < delta.size(); i++) {
- entry = delta.getValues(i, entry);
- final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
- if (ident == null) {
- unknownIface.add(entry.iface);
- continue;
- }
-
- final NetworkStatsHistory history = findOrCreateNetworkXtStatsLocked(ident);
- history.recordData(timeStart, currentTime, entry);
- }
-
- mLastPollNetworkXtSnapshot = networkXtSnapshot;
-
- if (LOGD && unknownIface.size() > 0) {
- Slog.w(TAG, "unknown xt interfaces " + unknownIface + ", ignoring those stats");
- }
- }
-
- /**
- * Update {@link #mUidStats} historical usage.
- */
- private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
- ensureUidStatsLoadedLocked();
-
- final NetworkStats delta = computeStatsDelta(
- mLastPollUidSnapshot, uidSnapshot, false, "uid");
- final NetworkStats operationsDelta = computeStatsDelta(
- mLastPollOperationsSnapshot, mOperations, false, "uidop");
- final long timeStart = currentTime - delta.getElapsedRealtime();
-
- NetworkStats.Entry entry = null;
- NetworkStats.Entry operationsEntry = null;
- for (int i = 0; i < delta.size(); i++) {
- entry = delta.getValues(i, entry);
- final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
- if (ident == null) {
- if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
- || entry.txPackets > 0) {
- Log.w(TAG, "dropping UID delta from unknown iface: " + entry);
- }
- continue;
- }
-
- // splice in operation counts since last poll
- final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.set, entry.tag);
- if (j != -1) {
- operationsEntry = operationsDelta.getValues(j, operationsEntry);
- entry.operations = operationsEntry.operations;
- }
-
- final NetworkStatsHistory history = findOrCreateUidStatsLocked(
- ident, entry.uid, entry.set, entry.tag);
- history.recordData(timeStart, currentTime, entry);
- }
-
- mLastPollUidSnapshot = uidSnapshot;
- mLastPollOperationsSnapshot = mOperations.clone();
- }
-
- /**
* Sample recent statistics summary into {@link EventLog}.
*/
- private void performSample() {
- final long largestBucketSize = Math.max(
- mSettings.getNetworkBucketDuration(), mSettings.getUidBucketDuration());
-
- // take sample as atomic buckets
- final long now = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
- final long end = now - (now % largestBucketSize) + largestBucketSize;
- final long start = end - largestBucketSize;
-
+ private void performSampleLocked() {
+ // TODO: migrate trustedtime fixes to separate binary log events
final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
- long devHistoryStart = Long.MAX_VALUE;
- NetworkTemplate template = null;
- NetworkStats.Entry devTotal = null;
- NetworkStats.Entry xtTotal = null;
- NetworkStats.Entry uidTotal = null;
+ NetworkTemplate template;
+ NetworkStats.Entry devTotal;
+ NetworkStats.Entry xtTotal;
+ NetworkStats.Entry uidTotal;
// collect mobile sample
template = buildTemplateMobileAll(getActiveSubscriberId(mContext));
- devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
- devHistoryStart = getHistoryStartLocked(template, mNetworkDevStats);
- xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
- uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
+ devTotal = mDevRecorder.getTotalSinceBootLocked(template);
+ xtTotal = new NetworkStats.Entry();
+ uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
EventLogTags.writeNetstatsMobileSample(
devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
- trustedTime, devHistoryStart);
+ trustedTime);
// collect wifi sample
template = buildTemplateWifi();
- devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
- devHistoryStart = getHistoryStartLocked(template, mNetworkDevStats);
- xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
- uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
+ devTotal = mDevRecorder.getTotalSinceBootLocked(template);
+ xtTotal = new NetworkStats.Entry();
+ uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
+
EventLogTags.writeNetstatsWifiSample(
devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
- trustedTime, devHistoryStart);
+ trustedTime);
}
/**
- * Clean up {@link #mUidStats} after UID is removed.
+ * Clean up {@link #mUidRecorder} after UID is removed.
*/
private void removeUidLocked(int uid) {
- ensureUidStatsLoadedLocked();
-
// perform one last poll before removing
performPollLocked(FLAG_PERSIST_ALL);
- final ArrayList<UidStatsKey> knownKeys = Lists.newArrayList();
- knownKeys.addAll(mUidStats.keySet());
-
- // migrate all UID stats into special "removed" bucket
- for (UidStatsKey key : knownKeys) {
- if (key.uid == uid) {
- // only migrate combined TAG_NONE history
- if (key.tag == TAG_NONE) {
- final NetworkStatsHistory uidHistory = mUidStats.get(key);
- final NetworkStatsHistory removedHistory = findOrCreateUidStatsLocked(
- key.ident, UID_REMOVED, SET_DEFAULT, TAG_NONE);
- removedHistory.recordEntireHistory(uidHistory);
- }
- mUidStats.remove(key);
- }
- }
-
- // clear UID from current stats snapshot
- if (mLastPollUidSnapshot != null) {
- mLastPollUidSnapshot = mLastPollUidSnapshot.withoutUid(uid);
- mLastPollNetworkXtSnapshot = computeNetworkXtSnapshotFromUid(mLastPollUidSnapshot);
- }
+ mUidRecorder.removeUidLocked(uid);
+ mUidTagRecorder.removeUidLocked(uid);
// clear kernel stats associated with UID
resetKernelUidStats(uid);
-
- // since this was radical rewrite, push to disk
- writeUidStatsLocked();
- }
-
- private NetworkStatsHistory findOrCreateNetworkXtStatsLocked(NetworkIdentitySet ident) {
- return findOrCreateNetworkStatsLocked(ident, mNetworkXtStats);
- }
-
- private NetworkStatsHistory findOrCreateNetworkDevStatsLocked(NetworkIdentitySet ident) {
- return findOrCreateNetworkStatsLocked(ident, mNetworkDevStats);
- }
-
- private NetworkStatsHistory findOrCreateNetworkStatsLocked(
- NetworkIdentitySet ident, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
- final NetworkStatsHistory existing = source.get(ident);
-
- // update when no existing, or when bucket duration changed
- final long bucketDuration = mSettings.getNetworkBucketDuration();
- NetworkStatsHistory updated = null;
- if (existing == null) {
- updated = new NetworkStatsHistory(bucketDuration, 10);
- } else if (existing.getBucketDuration() != bucketDuration) {
- updated = new NetworkStatsHistory(
- bucketDuration, estimateResizeBuckets(existing, bucketDuration));
- updated.recordEntireHistory(existing);
- }
-
- if (updated != null) {
- source.put(ident, updated);
- return updated;
- } else {
- return existing;
- }
- }
-
- private NetworkStatsHistory findOrCreateUidStatsLocked(
- NetworkIdentitySet ident, int uid, int set, int tag) {
- ensureUidStatsLoadedLocked();
-
- final UidStatsKey key = new UidStatsKey(ident, uid, set, tag);
- final NetworkStatsHistory existing = mUidStats.get(key);
-
- // update when no existing, or when bucket duration changed
- final long bucketDuration = mSettings.getUidBucketDuration();
- NetworkStatsHistory updated = null;
- if (existing == null) {
- updated = new NetworkStatsHistory(bucketDuration, 10);
- } else if (existing.getBucketDuration() != bucketDuration) {
- updated = new NetworkStatsHistory(
- bucketDuration, estimateResizeBuckets(existing, bucketDuration));
- updated.recordEntireHistory(existing);
- }
-
- if (updated != null) {
- mUidStats.put(key, updated);
- return updated;
- } else {
- return existing;
- }
- }
-
- private void readNetworkDevStatsLocked() {
- if (LOGV) Slog.v(TAG, "readNetworkDevStatsLocked()");
- readNetworkStats(mNetworkDevFile, mNetworkDevStats);
- }
-
- private void readNetworkXtStatsLocked() {
- if (LOGV) Slog.v(TAG, "readNetworkXtStatsLocked()");
- readNetworkStats(mNetworkXtFile, mNetworkXtStats);
- }
-
- private static void readNetworkStats(
- AtomicFile inputFile, HashMap<NetworkIdentitySet, NetworkStatsHistory> output) {
- // clear any existing stats and read from disk
- output.clear();
-
- DataInputStream in = null;
- try {
- in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
-
- // verify file magic header intact
- final int magic = in.readInt();
- if (magic != FILE_MAGIC) {
- throw new ProtocolException("unexpected magic: " + magic);
- }
-
- final int version = in.readInt();
- switch (version) {
- case VERSION_NETWORK_INIT: {
- // network := size *(NetworkIdentitySet NetworkStatsHistory)
- final int size = in.readInt();
- for (int i = 0; i < size; i++) {
- final NetworkIdentitySet ident = new NetworkIdentitySet(in);
- final NetworkStatsHistory history = new NetworkStatsHistory(in);
- output.put(ident, history);
- }
- break;
- }
- default: {
- throw new ProtocolException("unexpected version: " + version);
- }
- }
- } catch (FileNotFoundException e) {
- // missing stats is okay, probably first boot
- } catch (IOException e) {
- Log.wtf(TAG, "problem reading network stats", e);
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
-
- private void ensureUidStatsLoadedLocked() {
- if (!mUidStatsLoaded) {
- readUidStatsLocked();
- mUidStatsLoaded = true;
- }
- }
-
- private void readUidStatsLocked() {
- if (LOGV) Slog.v(TAG, "readUidStatsLocked()");
-
- // clear any existing stats and read from disk
- mUidStats.clear();
-
- DataInputStream in = null;
- try {
- in = new DataInputStream(new BufferedInputStream(mUidFile.openRead()));
-
- // verify file magic header intact
- final int magic = in.readInt();
- if (magic != FILE_MAGIC) {
- throw new ProtocolException("unexpected magic: " + magic);
- }
-
- final int version = in.readInt();
- switch (version) {
- case VERSION_UID_INIT: {
- // uid := size *(UID NetworkStatsHistory)
-
- // drop this data version, since we don't have a good
- // mapping into NetworkIdentitySet.
- break;
- }
- case VERSION_UID_WITH_IDENT: {
- // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory))
-
- // drop this data version, since this version only existed
- // for a short time.
- break;
- }
- case VERSION_UID_WITH_TAG:
- case VERSION_UID_WITH_SET: {
- // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory))
- final int identSize = in.readInt();
- for (int i = 0; i < identSize; i++) {
- final NetworkIdentitySet ident = new NetworkIdentitySet(in);
-
- final int size = in.readInt();
- for (int j = 0; j < size; j++) {
- final int uid = in.readInt();
- final int set = (version >= VERSION_UID_WITH_SET) ? in.readInt()
- : SET_DEFAULT;
- final int tag = in.readInt();
-
- final UidStatsKey key = new UidStatsKey(ident, uid, set, tag);
- final NetworkStatsHistory history = new NetworkStatsHistory(in);
- mUidStats.put(key, history);
- }
- }
- break;
- }
- default: {
- throw new ProtocolException("unexpected version: " + version);
- }
- }
- } catch (FileNotFoundException e) {
- // missing stats is okay, probably first boot
- } catch (IOException e) {
- Log.wtf(TAG, "problem reading uid stats", e);
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
-
- private void writeNetworkDevStatsLocked() {
- if (LOGV) Slog.v(TAG, "writeNetworkDevStatsLocked()");
- writeNetworkStats(mNetworkDevStats, mNetworkDevFile);
- }
-
- private void writeNetworkXtStatsLocked() {
- if (LOGV) Slog.v(TAG, "writeNetworkXtStatsLocked()");
- writeNetworkStats(mNetworkXtStats, mNetworkXtFile);
- }
-
- private void writeNetworkStats(
- HashMap<NetworkIdentitySet, NetworkStatsHistory> input, AtomicFile outputFile) {
- // TODO: consider duplicating stats and releasing lock while writing
-
- // trim any history beyond max
- if (mTime.hasCache()) {
- final long systemCurrentTime = System.currentTimeMillis();
- final long trustedCurrentTime = mTime.currentTimeMillis();
-
- final long currentTime = Math.min(systemCurrentTime, trustedCurrentTime);
- final long maxHistory = mSettings.getNetworkMaxHistory();
-
- for (NetworkStatsHistory history : input.values()) {
- final int beforeSize = history.size();
- history.removeBucketsBefore(currentTime - maxHistory);
- final int afterSize = history.size();
-
- if (beforeSize > 24 && afterSize < beforeSize / 2) {
- // yikes, dropping more than half of significant history
- final StringBuilder builder = new StringBuilder();
- builder.append("yikes, dropping more than half of history").append('\n');
- builder.append("systemCurrentTime=").append(systemCurrentTime).append('\n');
- builder.append("trustedCurrentTime=").append(trustedCurrentTime).append('\n');
- builder.append("maxHistory=").append(maxHistory).append('\n');
- builder.append("beforeSize=").append(beforeSize).append('\n');
- builder.append("afterSize=").append(afterSize).append('\n');
- mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
- }
- }
- }
-
- FileOutputStream fos = null;
- try {
- fos = outputFile.startWrite();
- final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
-
- out.writeInt(FILE_MAGIC);
- out.writeInt(VERSION_NETWORK_INIT);
-
- out.writeInt(input.size());
- for (NetworkIdentitySet ident : input.keySet()) {
- final NetworkStatsHistory history = input.get(ident);
- ident.writeToStream(out);
- history.writeToStream(out);
- }
-
- out.flush();
- outputFile.finishWrite(fos);
- } catch (IOException e) {
- Log.wtf(TAG, "problem writing stats", e);
- if (fos != null) {
- outputFile.failWrite(fos);
- }
- }
- }
-
- private void writeUidStatsLocked() {
- if (LOGV) Slog.v(TAG, "writeUidStatsLocked()");
-
- if (!mUidStatsLoaded) {
- Slog.w(TAG, "asked to write UID stats when not loaded; skipping");
- return;
- }
-
- // TODO: consider duplicating stats and releasing lock while writing
-
- // trim any history beyond max
- if (mTime.hasCache()) {
- final long currentTime = Math.min(
- System.currentTimeMillis(), mTime.currentTimeMillis());
- final long maxUidHistory = mSettings.getUidMaxHistory();
- final long maxTagHistory = mSettings.getTagMaxHistory();
- for (UidStatsKey key : mUidStats.keySet()) {
- final NetworkStatsHistory history = mUidStats.get(key);
-
- // detailed tags are trimmed sooner than summary in TAG_NONE
- if (key.tag == TAG_NONE) {
- history.removeBucketsBefore(currentTime - maxUidHistory);
- } else {
- history.removeBucketsBefore(currentTime - maxTagHistory);
- }
- }
- }
-
- // build UidStatsKey lists grouped by ident
- final HashMap<NetworkIdentitySet, ArrayList<UidStatsKey>> keysByIdent = Maps.newHashMap();
- for (UidStatsKey key : mUidStats.keySet()) {
- ArrayList<UidStatsKey> keys = keysByIdent.get(key.ident);
- if (keys == null) {
- keys = Lists.newArrayList();
- keysByIdent.put(key.ident, keys);
- }
- keys.add(key);
- }
-
- FileOutputStream fos = null;
- try {
- fos = mUidFile.startWrite();
- final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
-
- out.writeInt(FILE_MAGIC);
- out.writeInt(VERSION_UID_WITH_SET);
-
- out.writeInt(keysByIdent.size());
- for (NetworkIdentitySet ident : keysByIdent.keySet()) {
- final ArrayList<UidStatsKey> keys = keysByIdent.get(ident);
- ident.writeToStream(out);
-
- out.writeInt(keys.size());
- for (UidStatsKey key : keys) {
- final NetworkStatsHistory history = mUidStats.get(key);
- out.writeInt(key.uid);
- out.writeInt(key.set);
- out.writeInt(key.tag);
- history.writeToStream(out);
- }
- }
-
- out.flush();
- mUidFile.finishWrite(fos);
- } catch (IOException e) {
- Log.wtf(TAG, "problem writing stats", e);
- if (fos != null) {
- mUidFile.failWrite(fos);
- }
- }
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
final HashSet<String> argSet = new HashSet<String>();
@@ -1411,187 +860,68 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
argSet.add(arg);
}
- final boolean fullHistory = argSet.contains("full");
+ // usage: dumpsys netstats --full --uid --tag
+ final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
+ final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
+ final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
+ final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
- synchronized (mStatsLock) {
- // TODO: remove this testing code, since it corrupts stats
- if (argSet.contains("generate")) {
- generateRandomLocked(args);
- pw.println("Generated stub stats");
- return;
- }
+ final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (argSet.contains("poll")) {
+ synchronized (mStatsLock) {
+ if (poll) {
performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
pw.println("Forced poll");
return;
}
pw.println("Active interfaces:");
+ pw.increaseIndent();
for (String iface : mActiveIfaces.keySet()) {
final NetworkIdentitySet ident = mActiveIfaces.get(iface);
- pw.print(" iface="); pw.print(iface);
+ pw.print("iface="); pw.print(iface);
pw.print(" ident="); pw.println(ident.toString());
}
-
- pw.println("Known historical dev stats:");
- for (NetworkIdentitySet ident : mNetworkDevStats.keySet()) {
- final NetworkStatsHistory history = mNetworkDevStats.get(ident);
- pw.print(" ident="); pw.println(ident.toString());
- history.dump(" ", pw, fullHistory);
- }
-
- pw.println("Known historical xt stats:");
- for (NetworkIdentitySet ident : mNetworkXtStats.keySet()) {
- final NetworkStatsHistory history = mNetworkXtStats.get(ident);
- pw.print(" ident="); pw.println(ident.toString());
- history.dump(" ", pw, fullHistory);
- }
-
- if (argSet.contains("detail")) {
- // since explicitly requested with argument, we're okay to load
- // from disk if not already in memory.
- ensureUidStatsLoadedLocked();
-
- final ArrayList<UidStatsKey> keys = Lists.newArrayList();
- keys.addAll(mUidStats.keySet());
- Collections.sort(keys);
-
- pw.println("Detailed UID stats:");
- for (UidStatsKey key : keys) {
- pw.print(" ident="); pw.print(key.ident.toString());
- pw.print(" uid="); pw.print(key.uid);
- pw.print(" set="); pw.print(NetworkStats.setToString(key.set));
- pw.print(" tag="); pw.println(NetworkStats.tagToString(key.tag));
-
- final NetworkStatsHistory history = mUidStats.get(key);
- history.dump(" ", pw, fullHistory);
- }
- }
- }
- }
-
- /**
- * @deprecated only for temporary testing
- */
- @Deprecated
- private void generateRandomLocked(String[] args) {
- final long totalBytes = Long.parseLong(args[1]);
- final long totalTime = Long.parseLong(args[2]);
-
- final PackageManager pm = mContext.getPackageManager();
- final ArrayList<Integer> specialUidList = Lists.newArrayList();
- for (int i = 3; i < args.length; i++) {
- try {
- specialUidList.add(pm.getApplicationInfo(args[i], 0).uid);
- } catch (NameNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
-
- final HashSet<Integer> otherUidSet = Sets.newHashSet();
- for (ApplicationInfo info : pm.getInstalledApplications(0)) {
- if (pm.checkPermission(android.Manifest.permission.INTERNET, info.packageName)
- == PackageManager.PERMISSION_GRANTED && !specialUidList.contains(info.uid)) {
- otherUidSet.add(info.uid);
- }
- }
-
- final ArrayList<Integer> otherUidList = new ArrayList<Integer>(otherUidSet);
-
- final long end = System.currentTimeMillis();
- final long start = end - totalTime;
-
- mNetworkDevStats.clear();
- mNetworkXtStats.clear();
- mUidStats.clear();
-
- final Random r = new Random();
- for (NetworkIdentitySet ident : mActiveIfaces.values()) {
- final NetworkStatsHistory devHistory = findOrCreateNetworkDevStatsLocked(ident);
- final NetworkStatsHistory xtHistory = findOrCreateNetworkXtStatsLocked(ident);
-
- final ArrayList<Integer> uidList = new ArrayList<Integer>();
- uidList.addAll(specialUidList);
-
- if (uidList.size() == 0) {
- Collections.shuffle(otherUidList);
- uidList.addAll(otherUidList);
+ pw.decreaseIndent();
+
+ pw.println("Dev stats:");
+ pw.increaseIndent();
+ mDevRecorder.dumpLocked(pw, fullHistory);
+ pw.decreaseIndent();
+
+ if (includeUid) {
+ pw.println("UID stats:");
+ pw.increaseIndent();
+ mUidRecorder.dumpLocked(pw, fullHistory);
+ pw.decreaseIndent();
}
- boolean first = true;
- long remainingBytes = totalBytes;
- for (int uid : uidList) {
- final NetworkStatsHistory defaultHistory = findOrCreateUidStatsLocked(
- ident, uid, SET_DEFAULT, TAG_NONE);
- final NetworkStatsHistory foregroundHistory = findOrCreateUidStatsLocked(
- ident, uid, SET_FOREGROUND, TAG_NONE);
-
- final long uidBytes = totalBytes / uidList.size();
-
- final float fractionDefault = r.nextFloat();
- final long defaultBytes = (long) (uidBytes * fractionDefault);
- final long foregroundBytes = (long) (uidBytes * (1 - fractionDefault));
-
- defaultHistory.generateRandom(start, end, defaultBytes);
- foregroundHistory.generateRandom(start, end, foregroundBytes);
-
- if (first) {
- final long bumpTime = (start + end) / 2;
- defaultHistory.recordData(
- bumpTime, bumpTime + DAY_IN_MILLIS, 200 * MB_IN_BYTES, 0);
- first = false;
- }
-
- devHistory.recordEntireHistory(defaultHistory);
- devHistory.recordEntireHistory(foregroundHistory);
- xtHistory.recordEntireHistory(defaultHistory);
- xtHistory.recordEntireHistory(foregroundHistory);
+ if (includeTag) {
+ pw.println("UID tag stats:");
+ pw.increaseIndent();
+ mUidTagRecorder.dumpLocked(pw, fullHistory);
+ pw.decreaseIndent();
}
}
}
- private StatsObserver mStatsObserver = new StatsObserver();
-
- private class StatsObserver implements NonMonotonicObserver {
- private String mCurrentType;
-
- public void setCurrentType(String type) {
- mCurrentType = type;
- }
-
- /** {@inheritDoc} */
- public void foundNonMonotonic(
- NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) {
- Log.w(TAG, "found non-monotonic values; saving to dropbox");
-
- // record error for debugging
- final StringBuilder builder = new StringBuilder();
- builder.append("found non-monotonic " + mCurrentType + " values at left[" + leftIndex
- + "] - right[" + rightIndex + "]\n");
- builder.append("left=").append(left).append('\n');
- builder.append("right=").append(right).append('\n');
- mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
- }
+ private NetworkStats getNetworkStatsSummary() throws RemoteException {
+ return mNetworkManager.getNetworkStatsSummary();
}
/**
- * Return the delta between two {@link NetworkStats} snapshots, where {@code
- * before} can be {@code null}.
+ * Return snapshot of current UID statistics, including any
+ * {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.
*/
- private NetworkStats computeStatsDelta(
- NetworkStats before, NetworkStats current, boolean collectStale, String type) {
- if (before != null) {
- mStatsObserver.setCurrentType(type);
- return NetworkStats.subtract(current, before, mStatsObserver);
- } else if (collectStale) {
- // caller is okay collecting stale stats for first call.
- return current;
- } else {
- // this is first snapshot; to prevent from double-counting we only
- // observe traffic occuring between known snapshots.
- return new NetworkStats(0L, 10);
- }
+ private NetworkStats getNetworkStatsUidDetail() throws RemoteException {
+ final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+
+ // fold tethering stats and operations into uid snapshot
+ final NetworkStats tetherSnapshot = getNetworkStatsTethering();
+ uidSnapshot.combineAllValues(tetherSnapshot);
+ uidSnapshot.combineAllValues(mUidOperations);
+
+ return uidSnapshot;
}
/**
@@ -1608,35 +938,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- private static NetworkStats computeNetworkXtSnapshotFromUid(NetworkStats uidSnapshot) {
- return uidSnapshot.groupedByIface();
- }
-
- private int estimateNetworkBuckets() {
- return (int) (mSettings.getNetworkMaxHistory() / mSettings.getNetworkBucketDuration());
- }
-
- private int estimateUidBuckets() {
- return (int) (mSettings.getUidMaxHistory() / mSettings.getUidBucketDuration());
- }
-
- private static int estimateResizeBuckets(NetworkStatsHistory existing, long newBucketDuration) {
- return (int) (existing.size() * existing.getBucketDuration() / newBucketDuration);
- }
-
- /**
- * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity}
- * in the given {@link NetworkIdentitySet}.
- */
- private static boolean templateMatches(NetworkTemplate template, NetworkIdentitySet identSet) {
- for (NetworkIdentity ident : identSet) {
- if (template.matches(ident)) {
- return true;
- }
- }
- return false;
- }
-
private Handler.Callback mHandlerCallback = new Handler.Callback() {
/** {@inheritDoc} */
public boolean handleMessage(Message msg) {
@@ -1672,40 +973,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- /**
- * Key uniquely identifying a {@link NetworkStatsHistory} for a UID.
- */
- private static class UidStatsKey implements Comparable<UidStatsKey> {
- public final NetworkIdentitySet ident;
- public final int uid;
- public final int set;
- public final int tag;
-
- public UidStatsKey(NetworkIdentitySet ident, int uid, int set, int tag) {
- this.ident = ident;
- this.uid = uid;
- this.set = set;
- this.tag = tag;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(ident, uid, set, tag);
- }
+ private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
+ /** {@inheritDoc} */
+ public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
+ int rightIndex, String cookie) {
+ Log.w(TAG, "found non-monotonic values; saving to dropbox");
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof UidStatsKey) {
- final UidStatsKey key = (UidStatsKey) obj;
- return Objects.equal(ident, key.ident) && uid == key.uid && set == key.set
- && tag == key.tag;
- }
- return false;
- }
+ // record error for debugging
+ final StringBuilder builder = new StringBuilder();
+ builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
+ + "] - right[" + rightIndex + "]\n");
+ builder.append("left=").append(left).append('\n');
+ builder.append("right=").append(right).append('\n');
- /** {@inheritDoc} */
- public int compareTo(UidStatsKey another) {
- return Integer.compare(uid, another.uid);
+ final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
+ Context.DROPBOX_SERVICE);
+ dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
}
}
@@ -1731,26 +1014,35 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
public long getPollInterval() {
return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
}
- public long getPersistThreshold() {
- return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 2 * MB_IN_BYTES);
- }
- public long getNetworkBucketDuration() {
- return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS);
+ public long getTimeCacheMaxAge() {
+ return getSecureLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
}
- public long getNetworkMaxHistory() {
- return getSecureLong(NETSTATS_NETWORK_MAX_HISTORY, 90 * DAY_IN_MILLIS);
+ public long getGlobalAlertBytes() {
+ return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, 2 * MB_IN_BYTES);
}
- public long getUidBucketDuration() {
- return getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS);
+ public boolean getSampleEnabled() {
+ return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
}
- public long getUidMaxHistory() {
- return getSecureLong(NETSTATS_UID_MAX_HISTORY, 90 * DAY_IN_MILLIS);
+
+ public Config getDevConfig() {
+ return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
+ getSecureLong(NETSTATS_DEV_PERSIST_BYTES, 2 * MB_IN_BYTES),
+ getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
+ getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
}
- public long getTagMaxHistory() {
- return getSecureLong(NETSTATS_TAG_MAX_HISTORY, 30 * DAY_IN_MILLIS);
+
+ public Config getUidConfig() {
+ return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
+ getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
+ getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
+ getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
}
- public long getTimeCacheMaxAge() {
- return DAY_IN_MILLIS;
+
+ public Config getUidTagConfig() {
+ return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
+ getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
+ getSecureLong(NETSTATS_UID_ROTATE_AGE, 5 * DAY_IN_MILLIS),
+ getSecureLong(NETSTATS_UID_DELETE_AGE, 15 * DAY_IN_MILLIS));
}
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 24b6064fe964..19d94a1fdbad 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -2543,8 +2543,12 @@ public class WindowManagerService extends IWindowManager.Stub
if (win == null) {
return 0;
}
- win.mRequestedWidth = requestedWidth;
- win.mRequestedHeight = requestedHeight;
+ if (win.mRequestedWidth != requestedWidth
+ || win.mRequestedHeight != requestedHeight) {
+ win.mLayoutNeeded = true;
+ win.mRequestedWidth = requestedWidth;
+ win.mRequestedHeight = requestedHeight;
+ }
if (attrs != null && seq == win.mSeq) {
win.mSystemUiVisibility = systemUiVisibility;
}
@@ -2565,6 +2569,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
flagChanges = win.mAttrs.flags ^= attrs.flags;
attrChanges = win.mAttrs.copyFrom(attrs);
+ if ((attrChanges&WindowManager.LayoutParams.LAYOUT_CHANGED) != 0) {
+ win.mLayoutNeeded = true;
+ }
}
if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": " + win.mAttrs);
@@ -7460,12 +7467,13 @@ public class WindowManagerService extends IWindowManager.Stub
// if they want. (We do the normal layout for INVISIBLE
// windows, since that means "perform layout as normal,
// just don't display").
- if (!gone || !win.mHaveFrame) {
+ if (!gone || !win.mHaveFrame || win.mLayoutNeeded) {
if (!win.mLayoutAttached) {
if (initial) {
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
win.mContentChanged = false;
}
+ win.mLayoutNeeded = false;
win.prelayout();
mPolicy.layoutWindowLw(win, win.mAttrs, null);
win.mLayoutSeq = seq;
@@ -7497,11 +7505,12 @@ public class WindowManagerService extends IWindowManager.Stub
// windows, since that means "perform layout as normal,
// just don't display").
if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
- || !win.mHaveFrame) {
+ || !win.mHaveFrame || win.mLayoutNeeded) {
if (initial) {
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
win.mContentChanged = false;
}
+ win.mLayoutNeeded = false;
win.prelayout();
mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
win.mLayoutSeq = seq;
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 91183814b21c..1067cade647c 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -238,6 +238,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
// we can give the window focus before waiting for the relayout.
boolean mRelayoutCalled;
+ // If the application has called relayout() with changes that can
+ // impact its window's size, we need to perform a layout pass on it
+ // even if it is not currently visible for layout. This is set
+ // when in that case until the layout is done.
+ boolean mLayoutNeeded;
+
// This is set after the Surface has been created but before the
// window has been drawn. During this time the surface is hidden.
boolean mDrawPending;
@@ -1449,7 +1455,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return mViewVisibility == View.GONE
|| !mRelayoutCalled
|| (atoken == null && mRootToken.hidden)
- || (atoken != null && atoken.hiddenRequested)
+ || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
|| mAttachedHidden
|| mExiting || mDestroying;
}
@@ -1728,8 +1734,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(mPolicyVisibilityAfterAnim);
pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
}
- if (!mRelayoutCalled) {
- pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
+ if (!mRelayoutCalled || mLayoutNeeded) {
+ pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
+ pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
}
if (mSurfaceResized || mSurfaceDestroyDeferred) {
pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 95d651acc224..fc211e56b91c 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -23,18 +23,21 @@ LOCAL_SRC_FILES:= \
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+ifeq ($(TARGET_HAS_WAITFORVSYNC), true)
+ LOCAL_CFLAGS += -DHAS_WAITFORVSYNC
+endif
+
ifeq ($(TARGET_BOARD_PLATFORM), omap3)
LOCAL_CFLAGS += -DNO_RGBX_8888
endif
ifeq ($(TARGET_BOARD_PLATFORM), omap4)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+ LOCAL_CFLAGS += -DUSE_TRIPLE_BUFFERING=1
endif
ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
- LOCAL_CFLAGS += -DREFRESH_RATE=56
endif
-
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 438a6daf37be..986aec576a0f 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -350,15 +350,28 @@ uint32_t DisplayHardware::getPageFlipCount() const {
}
// this needs to be thread safe
-nsecs_t DisplayHardware::waitForVSync() const {
+nsecs_t DisplayHardware::waitForRefresh() const {
nsecs_t timestamp;
if (mVSync.wait(&timestamp) < 0) {
// vsync not supported!
usleep( getDelayToNextVSyncUs(&timestamp) );
}
+ mLastHwVSync = timestamp; // FIXME: Not thread safe
return timestamp;
}
+nsecs_t DisplayHardware::getRefreshTimestamp() const {
+ // this returns the last refresh timestamp.
+ // if the last one is not available, we estimate it based on
+ // the refresh period and whatever closest timestamp we have.
+ nsecs_t now = systemTime();
+ return now - ((now - mLastHwVSync) % mRefreshPeriod);
+}
+
+nsecs_t DisplayHardware::getRefreshPeriod() const {
+ return mRefreshPeriod;
+}
+
int32_t DisplayHardware::getDelayToNextVSyncUs(nsecs_t* timestamp) const {
Mutex::Autolock _l(mFakeVSyncMutex);
const nsecs_t period = mRefreshPeriod;
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 77da272bbe8b..02be4dcba7fd 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -76,7 +76,9 @@ public:
uint32_t getMaxViewportDims() const;
// waits for the next vsync and returns the timestamp of when it happened
- nsecs_t waitForVSync() const;
+ nsecs_t waitForRefresh() const;
+ nsecs_t getRefreshPeriod() const;
+ nsecs_t getRefreshTimestamp() const;
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
@@ -119,6 +121,7 @@ private:
mutable Mutex mFakeVSyncMutex;
mutable nsecs_t mNextFakeVSync;
nsecs_t mRefreshPeriod;
+ mutable nsecs_t mLastHwVSync;
HWComposer* mHwc;
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 80ab5195cec5..af0da0bdb22c 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -36,6 +36,7 @@ namespace android {
EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
: mFlinger(flinger),
mHw(flinger->graphicPlane(0).displayHardware()),
+ mLastVSyncTimestamp(0),
mDeliveredEvents(0)
{
}
@@ -44,6 +45,20 @@ void EventThread::onFirstRef() {
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
+sp<DisplayEventConnection> EventThread::createEventConnection() const {
+ return new DisplayEventConnection(const_cast<EventThread*>(this));
+}
+
+nsecs_t EventThread::getLastVSyncTimestamp() const {
+ Mutex::Autolock _l(mLock);
+ return mLastVSyncTimestamp;
+}
+
+nsecs_t EventThread::getVSyncPeriod() const {
+ return mHw.getRefreshPeriod();
+
+}
+
status_t EventThread::registerDisplayEventConnection(
const sp<DisplayEventConnection>& connection) {
Mutex::Autolock _l(mLock);
@@ -80,8 +95,11 @@ void EventThread::setVsyncRate(uint32_t count,
Mutex::Autolock _l(mLock);
ConnectionInfo* info = getConnectionInfoLocked(connection);
if (info) {
- info->count = (count == 0) ? -1 : count;
- mCondition.signal();
+ const int32_t new_count = (count == 0) ? -1 : count;
+ if (info->count != new_count) {
+ info->count = new_count;
+ mCondition.signal();
+ }
}
}
}
@@ -90,10 +108,8 @@ void EventThread::requestNextVsync(
const wp<DisplayEventConnection>& connection) {
Mutex::Autolock _l(mLock);
ConnectionInfo* info = getConnectionInfoLocked(connection);
- if (info) {
- if (info->count < 0) {
- info->count = 0;
- }
+ if (info && info->count < 0) {
+ info->count = 0;
mCondition.signal();
}
}
@@ -129,14 +145,15 @@ bool EventThread::threadLoop() {
// at least one listener requested VSYNC
mLock.unlock();
- timestamp = mHw.waitForVSync();
+ timestamp = mHw.waitForRefresh();
mLock.lock();
mDeliveredEvents++;
+ mLastVSyncTimestamp = timestamp;
// now see if we still need to report this VSYNC event
- bool reportVsync = false;
- size_t count = mDisplayEventConnections.size();
+ const size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
+ bool reportVsync = false;
const ConnectionInfo& info(
mDisplayEventConnections.valueAt(i));
if (info.count >= 1) {
@@ -157,11 +174,7 @@ bool EventThread::threadLoop() {
displayEventConnections.add(mDisplayEventConnections.keyAt(i));
}
}
-
- if (reportVsync) {
- break;
- }
- } while (true);
+ } while (!displayEventConnections.size());
// dispatch vsync events to listeners...
vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index 35bd299a8675..3a3071ef8bea 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -36,6 +36,7 @@ namespace android {
class SurfaceFlinger;
class DisplayHardware;
+class DisplayEventConnection;
// ---------------------------------------------------------------------------
@@ -45,6 +46,8 @@ class EventThread : public Thread {
public:
EventThread(const sp<SurfaceFlinger>& flinger);
+ sp<DisplayEventConnection> createEventConnection() const;
+
status_t registerDisplayEventConnection(
const sp<DisplayEventConnection>& connection);
@@ -56,6 +59,10 @@ public:
void requestNextVsync(const wp<DisplayEventConnection>& connection);
+ nsecs_t getLastVSyncTimestamp() const;
+
+ nsecs_t getVSyncPeriod() const;
+
void dump(String8& result, char* buffer, size_t SIZE) const;
private:
@@ -88,6 +95,7 @@ private:
// protected by mLock
KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > mDisplayEventConnections;
+ nsecs_t mLastVSyncTimestamp;
// main thread only
size_t mDeliveredEvents;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d4c4b1f93652..9c04d597205c 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -38,6 +38,7 @@
#include "Layer.h"
#include "SurfaceFlinger.h"
#include "SurfaceTextureLayer.h"
+#include <math.h>
#define DEBUG_RESIZE 0
@@ -54,6 +55,8 @@ Layer::Layer(SurfaceFlinger* flinger,
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
+ mFrameLatencyNeeded(false),
+ mFrameLatencyOffset(0),
mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
mOpaqueLayer(true),
@@ -65,6 +68,17 @@ Layer::Layer(SurfaceFlinger* flinger,
glGenTextures(1, &mTextureName);
}
+void Layer::onLayerDisplayed() {
+ if (mFrameLatencyNeeded) {
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
+ mFrameStats[mFrameLatencyOffset].set = systemTime();
+ mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
+ mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
+ mFrameLatencyNeeded = false;
+ }
+}
+
void Layer::onFirstRef()
{
LayerBaseClient::onFirstRef();
@@ -83,7 +97,12 @@ void Layer::onFirstRef()
mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
mSurfaceTexture->setSynchronousMode(true);
+#ifdef USE_TRIPLE_BUFFERING
+#warning "using triple buffering"
+ mSurfaceTexture->setBufferCountServer(3);
+#else
mSurfaceTexture->setBufferCountServer(2);
+#endif
}
Layer::~Layer()
@@ -408,6 +427,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
// update the active buffer
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
+ mFrameLatencyNeeded = true;
const Rect crop(mSurfaceTexture->getCurrentCrop());
const uint32_t transform(mSurfaceTexture->getCurrentTransform());
@@ -543,6 +563,32 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
}
}
+void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
+{
+ LayerBaseClient::dumpStats(result, buffer, SIZE);
+ const size_t o = mFrameLatencyOffset;
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const nsecs_t period = hw.getRefreshPeriod();
+ result.appendFormat("%lld\n", period);
+ for (size_t i=0 ; i<128 ; i++) {
+ const size_t index = (o+i) % 128;
+ const nsecs_t time_app = mFrameStats[index].timestamp;
+ const nsecs_t time_set = mFrameStats[index].set;
+ const nsecs_t time_vsync = mFrameStats[index].vsync;
+ result.appendFormat("%lld\t%lld\t%lld\n",
+ time_app,
+ time_vsync,
+ time_set);
+ }
+ result.append("\n");
+}
+
+void Layer::clearStats()
+{
+ LayerBaseClient::clearStats();
+ memset(mFrameStats, 0, sizeof(mFrameStats));
+}
+
uint32_t Layer::getEffectiveUsage(uint32_t usage) const
{
// TODO: should we do something special if mSecure is set?
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2b9471b011b6..2dd4da130dcf 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -34,6 +34,7 @@
#include "LayerBase.h"
#include "SurfaceTextureLayer.h"
#include "Transform.h"
+#include <utils/Timers.h>
namespace android {
@@ -78,12 +79,16 @@ public:
// LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const;
+ virtual void onLayerDisplayed();
+
// only for debugging
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
protected:
virtual void onFirstRef();
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
+ virtual void clearStats();
private:
friend class SurfaceTextureLayer;
@@ -110,6 +115,16 @@ private:
uint32_t mCurrentTransform;
uint32_t mCurrentScalingMode;
bool mCurrentOpacity;
+ bool mFrameLatencyNeeded;
+ int mFrameLatencyOffset;
+ struct Statistics {
+ Statistics() : timestamp(0), set(0), vsync(0) { }
+ nsecs_t timestamp; // buffer timestamp
+ nsecs_t set; // buffer displayed timestamp
+ nsecs_t vsync; // vsync immediately before set
+ };
+ // protected by mLock
+ Statistics mFrameStats[128];
// constants
PixelFormat mFormat;
@@ -121,9 +136,6 @@ private:
bool mSecure; // no screenshots
bool mProtectedByApp; // application requires protected path to external sink
Region mPostedDirtyRegion;
-
- // binder thread, transaction thread
- mutable Mutex mLock;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 37879f1a47d0..d32fcdd62528 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -471,6 +471,9 @@ void LayerBase::drawWithOpenGL(const Region& clip) const
void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
{
const Layer::State& s(drawingState());
+ s.transparentRegion.dump(result, "transparentRegion");
+ transparentRegionScreen.dump(result, "transparentRegionScreen");
+ visibleRegionScreen.dump(result, "visibleRegionScreen");
snprintf(buffer, SIZE,
"+ %s %p (%s)\n"
" "
@@ -486,11 +489,15 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
result.append(buffer);
}
-void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
-{
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const {
LayerBase::dump(result, scratch, size);
}
+void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const {
+}
+
+void LayerBase::clearStats() {
+}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 7f6214510d33..6b62c9db7836 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -205,10 +205,14 @@ public:
/** called with the state lock when the surface is removed from the
* current list */
virtual void onRemoved() { };
-
+
+ virtual void onLayerDisplayed() { };
+
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
virtual void shortDump(String8& result, char* scratch, size_t size) const;
+ virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
+ virtual void clearStats();
enum { // flags for doTransaction()
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index cbd530c822a5..70711e73ee46 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -18,12 +18,17 @@
#include <errno.h>
#include <sys/types.h>
+#include <binder/IPCThreadState.h>
+
#include <utils/threads.h>
#include <utils/Timers.h>
#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
+
+#include <gui/IDisplayEventConnection.h>
+#include <gui/BitTube.h>
#include "MessageQueue.h"
+#include "EventThread.h"
namespace android {
@@ -51,6 +56,15 @@ MessageQueue::MessageQueue()
MessageQueue::~MessageQueue() {
}
+void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
+{
+ mEventThread = eventThread;
+ mEvents = eventThread->createEventConnection();
+ mEventTube = mEvents->getDataChannel();
+ mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
+ MessageQueue::cb_eventReceiver, this);
+}
+
void MessageQueue::waitMessage() {
do {
IPCThreadState::self()->flushCommands();
@@ -93,13 +107,54 @@ status_t MessageQueue::postMessage(
return NO_ERROR;
}
-status_t MessageQueue::invalidate() {
+void MessageQueue::scheduleWorkASAP() {
if (android_atomic_or(1, &mWorkPending) == 0) {
mLooper->wake();
- }
+ }
+}
+
+status_t MessageQueue::invalidate() {
+ mEvents->requestNextVsync();
return NO_ERROR;
}
+int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
+ MessageQueue* queue = reinterpret_cast<MessageQueue *>(data);
+ return queue->eventReceiver(fd, events);
+}
+
+int MessageQueue::eventReceiver(int fd, int events) {
+ ssize_t n;
+ DisplayEventReceiver::Event buffer[8];
+ while ((n = getEvents(buffer, 8)) > 0) {
+ for (int i=0 ; i<n ; i++) {
+ if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+ scheduleWorkASAP();
+ break;
+ }
+ }
+ }
+ return 1;
+}
+
+ssize_t MessageQueue::getEvents(
+ DisplayEventReceiver::Event* events, size_t count)
+{
+ ssize_t size = mEventTube->read(events, sizeof(events[0])*count);
+ ALOGE_IF(size<0, "MessageQueue::getEvents error (%s)", strerror(-size));
+ if (size >= 0) {
+ // Note: if (size % sizeof(events[0])) != 0, we've got a
+ // partial read. This can happen if the queue filed up (ie: if we
+ // didn't pull from it fast enough).
+ // We discard the partial event and rely on the sender to
+ // re-send the event if appropriate (some events, like VSYNC
+ // can be lost forever).
+ // returns number of events read
+ size /= sizeof(events[0]);
+ }
+ return size;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
index 2317d81ab8e9..5ea197dc70c9 100644
--- a/services/surfaceflinger/MessageQueue.h
+++ b/services/surfaceflinger/MessageQueue.h
@@ -25,10 +25,15 @@
#include <utils/Timers.h>
#include <utils/Looper.h>
+#include <gui/DisplayEventReceiver.h>
+
#include "Barrier.h"
namespace android {
+class IDisplayEventConnection;
+class EventThread;
+
// ---------------------------------------------------------------------------
class MessageBase : public MessageHandler
@@ -55,11 +60,20 @@ private:
class MessageQueue {
sp<Looper> mLooper;
- volatile int32_t mWorkPending;
+ sp<EventThread> mEventThread;
+ sp<IDisplayEventConnection> mEvents;
+ sp<BitTube> mEventTube;
+ int32_t mWorkPending;
+
+ static int cb_eventReceiver(int fd, int events, void* data);
+ int eventReceiver(int fd, int events);
+ ssize_t getEvents(DisplayEventReceiver::Event* events, size_t count);
+ void scheduleWorkASAP();
public:
MessageQueue();
~MessageQueue();
+ void setEventThread(const sp<EventThread>& events);
void waitMessage();
status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index af474022dddf..ff70ec327eb3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -188,7 +188,8 @@ void SurfaceFlinger::binderDied(const wp<IBinder>& who)
// the window manager died on us. prepare its eulogy.
// reset screen orientation
- setOrientation(0, eOrientationDefault, 0);
+ Vector<ComposerState> state;
+ setTransactionState(state, eOrientationDefault, 0);
// restart the boot-animation
property_set("ctl.start", "bootanim");
@@ -295,6 +296,7 @@ status_t SurfaceFlinger::readyToRun()
// start the EventThread
mEventThread = new EventThread(this);
+ mEventQueue.setEventThread(mEventThread);
/*
* We're now ready to accept clients...
@@ -382,8 +384,7 @@ bool SurfaceFlinger::authenticateSurfaceTexture(
// ----------------------------------------------------------------------------
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
- sp<DisplayEventConnection> result(new DisplayEventConnection(mEventThread));
- return result;
+ return mEventThread->createEventConnection();
}
// ----------------------------------------------------------------------------
@@ -431,7 +432,6 @@ bool SurfaceFlinger::threadLoop()
} else {
// pretend we did the post
hw.compositionComplete();
- hw.waitForVSync();
}
return true;
}
@@ -445,6 +445,12 @@ void SurfaceFlinger::postFramebuffer()
const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;
hw.flip(mSwapRegion);
+
+ size_t numLayers = mVisibleLayersSortedByZ.size();
+ for (size_t i = 0; i < numLayers; i++) {
+ mVisibleLayersSortedByZ[i]->onLayerDisplayed();
+ }
+
mLastSwapBufferTime = systemTime() - now;
mDebugInSwapBuffers = 0;
mSwapRegion.clear();
@@ -1219,26 +1225,6 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
}
}
-int SurfaceFlinger::setOrientation(DisplayID dpy,
- int orientation, uint32_t flags)
-{
- if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
- return BAD_VALUE;
-
- Mutex::Autolock _l(mStateLock);
- if (mCurrentState.orientation != orientation) {
- if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
- mCurrentState.orientationFlags = flags;
- mCurrentState.orientation = orientation;
- setTransactionFlags(eTransactionNeeded);
- mTransactionCV.wait(mStateLock);
- } else {
- orientation = BAD_VALUE;
- }
- }
- return orientation;
-}
-
sp<ISurface> SurfaceFlinger::createSurface(
ISurfaceComposerClient::surface_data_t* params,
const String8& name,
@@ -1463,14 +1449,6 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
IPCThreadState::self()->getCallingUid());
result.append(buffer);
} else {
-
- // figure out if we're stuck somewhere
- const nsecs_t now = systemTime();
- const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
- const nsecs_t inTransaction(mDebugInTransaction);
- nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
- nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
-
// Try to get the main lock, but don't insist if we can't
// (this would indicate SF is stuck, but we want to be able to
// print something in dumpsys).
@@ -1486,117 +1464,203 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
result.append(buffer);
}
- /*
- * Dump the visible layer list
- */
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
- result.append(buffer);
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
- layer->dump(result, buffer, SIZE);
- const Layer::State& s(layer->drawingState());
- s.transparentRegion.dump(result, "transparentRegion");
- layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
- layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
- }
+ bool dumpAll = true;
+ size_t index = 0;
+ size_t numArgs = args.size();
+ if (numArgs) {
+ dumpAll = false;
- /*
- * Dump the layers in the purgatory
- */
-
- const size_t purgatorySize = mLayerPurgatory.size();
- snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
- result.append(buffer);
- for (size_t i=0 ; i<purgatorySize ; i++) {
- const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
- layer->shortDump(result, buffer, SIZE);
- }
+ if ((index < numArgs) &&
+ (args[index] == String16("--list"))) {
+ index++;
+ listLayersLocked(args, index, result, buffer, SIZE);
+ }
- /*
- * Dump SurfaceFlinger global state
- */
+ if ((index < numArgs) &&
+ (args[index] == String16("--latency"))) {
+ index++;
+ dumpStatsLocked(args, index, result, buffer, SIZE);
+ }
- snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
- result.append(buffer);
+ if ((index < numArgs) &&
+ (args[index] == String16("--latency-clear"))) {
+ index++;
+ clearStatsLocked(args, index, result, buffer, SIZE);
+ }
+ }
- const GLExtensions& extensions(GLExtensions::getInstance());
- snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
- extensions.getVendor(),
- extensions.getRenderer(),
- extensions.getVersion());
- result.append(buffer);
+ if (dumpAll) {
+ dumpAllLocked(result, buffer, SIZE);
+ }
- snprintf(buffer, SIZE, "EGL : %s\n",
- eglQueryString(graphicPlane(0).getEGLDisplay(),
- EGL_VERSION_HW_ANDROID));
- result.append(buffer);
+ if (locked) {
+ mStateLock.unlock();
+ }
+ }
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
- snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ snprintf(buffer, SIZE, "%s\n", layer->getName().string());
result.append(buffer);
+ }
+}
- mWormholeRegion.dump(result, "WormholeRegion");
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- snprintf(buffer, SIZE,
- " orientation=%d, canDraw=%d\n",
- mCurrentState.orientation, hw.canDraw());
- result.append(buffer);
- snprintf(buffer, SIZE,
- " last eglSwapBuffers() time: %f us\n"
- " last transaction time : %f us\n"
- " refresh-rate : %f fps\n"
- " x-dpi : %f\n"
- " y-dpi : %f\n",
- mLastSwapBufferTime/1000.0,
- mLastTransactionTime/1000.0,
- hw.getRefreshRate(),
- hw.getDpiX(),
- hw.getDpiY());
- result.append(buffer);
+void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ String8 name;
+ if (index < args.size()) {
+ name = String8(args[index]);
+ index++;
+ }
- if (inSwapBuffersDuration || !locked) {
- snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
- inSwapBuffersDuration/1000.0);
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ if (name.isEmpty()) {
+ snprintf(buffer, SIZE, "%s\n", layer->getName().string());
result.append(buffer);
}
+ if (name.isEmpty() || (name == layer->getName())) {
+ layer->dumpStats(result, buffer, SIZE);
+ }
+ }
+}
- if (inTransactionDuration || !locked) {
- snprintf(buffer, SIZE, " transaction time: %f us\n",
- inTransactionDuration/1000.0);
- result.append(buffer);
+void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ String8 name;
+ if (index < args.size()) {
+ name = String8(args[index]);
+ index++;
+ }
+
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ if (name.isEmpty() || (name == layer->getName())) {
+ layer->clearStats();
}
+ }
+}
- /*
- * VSYNC state
- */
- mEventThread->dump(result, buffer, SIZE);
+void SurfaceFlinger::dumpAllLocked(
+ String8& result, char* buffer, size_t SIZE) const
+{
+ // figure out if we're stuck somewhere
+ const nsecs_t now = systemTime();
+ const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
+ const nsecs_t inTransaction(mDebugInTransaction);
+ nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
+ nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
- /*
- * Dump HWComposer state
- */
- HWComposer& hwc(hw.getHwComposer());
- snprintf(buffer, SIZE, "h/w composer state:\n");
- result.append(buffer);
- snprintf(buffer, SIZE, " h/w composer %s and %s\n",
- hwc.initCheck()==NO_ERROR ? "present" : "not present",
- (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
- result.append(buffer);
- hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+ /*
+ * Dump the visible layer list
+ */
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+ result.append(buffer);
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ layer->dump(result, buffer, SIZE);
+ }
- /*
- * Dump gralloc state
- */
- const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
- alloc.dump(result);
- hw.dump(result);
+ /*
+ * Dump the layers in the purgatory
+ */
- if (locked) {
- mStateLock.unlock();
- }
+ const size_t purgatorySize = mLayerPurgatory.size();
+ snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+ result.append(buffer);
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ layer->shortDump(result, buffer, SIZE);
}
- write(fd, result.string(), result.size());
- return NO_ERROR;
+
+ /*
+ * Dump SurfaceFlinger global state
+ */
+
+ snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
+ result.append(buffer);
+
+ const GLExtensions& extensions(GLExtensions::getInstance());
+ snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
+ extensions.getVendor(),
+ extensions.getRenderer(),
+ extensions.getVersion());
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "EGL : %s\n",
+ eglQueryString(graphicPlane(0).getEGLDisplay(),
+ EGL_VERSION_HW_ANDROID));
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+ result.append(buffer);
+
+ mWormholeRegion.dump(result, "WormholeRegion");
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ snprintf(buffer, SIZE,
+ " orientation=%d, canDraw=%d\n",
+ mCurrentState.orientation, hw.canDraw());
+ result.append(buffer);
+ snprintf(buffer, SIZE,
+ " last eglSwapBuffers() time: %f us\n"
+ " last transaction time : %f us\n"
+ " refresh-rate : %f fps\n"
+ " x-dpi : %f\n"
+ " y-dpi : %f\n",
+ mLastSwapBufferTime/1000.0,
+ mLastTransactionTime/1000.0,
+ hw.getRefreshRate(),
+ hw.getDpiX(),
+ hw.getDpiY());
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
+ inSwapBuffersDuration/1000.0);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " transaction time: %f us\n",
+ inTransactionDuration/1000.0);
+ result.append(buffer);
+
+ /*
+ * VSYNC state
+ */
+ mEventThread->dump(result, buffer, SIZE);
+
+ /*
+ * Dump HWComposer state
+ */
+ HWComposer& hwc(hw.getHwComposer());
+ snprintf(buffer, SIZE, "h/w composer state:\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " h/w composer %s and %s\n",
+ hwc.initCheck()==NO_ERROR ? "present" : "not present",
+ (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
+ result.append(buffer);
+ hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+
+ /*
+ * Dump gralloc state
+ */
+ const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+ alloc.dump(result);
+ hw.dump(result);
}
status_t SurfaceFlinger::onTransact(
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 7f6c90ca0685..c24a9de45a59 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -170,7 +170,6 @@ public:
virtual void bootFinished();
virtual void setTransactionState(const Vector<ComposerState>& state,
int orientation, uint32_t flags);
- virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
virtual bool authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const;
virtual sp<IDisplayEventConnection> createDisplayEventConnection();
@@ -337,6 +336,13 @@ private:
void debugFlashRegions();
void drawWormhole() const;
+ void listLayersLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const;
+ void dumpStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const;
+ void clearStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const;
+ void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const;
mutable MessageQueue mEventQueue;
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index 259b93766a92..49e8e6393505 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -94,6 +94,10 @@ status_t SurfaceTextureLayer::connect(int api,
*outTransform = orientation;
}
switch(api) {
+ case NATIVE_WINDOW_API_CPU:
+ // SurfaceTextureClient supports only 2 buffers for CPU connections
+ this->setBufferCountServer(2);
+ break;
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
// Camera preview and videos are rate-limited on the producer
diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp
index 4f790802535c..b0d54c4e0b17 100644
--- a/services/surfaceflinger/tests/vsync/vsync.cpp
+++ b/services/surfaceflinger/tests/vsync/vsync.cpp
@@ -55,6 +55,8 @@ int main(int argc, char** argv)
loop->addFd(myDisplayEvent.getFd(), 0, ALOOPER_EVENT_INPUT, receiver,
&myDisplayEvent);
+ myDisplayEvent.setVsyncRate(1);
+
do {
//printf("about to poll...\n");
int32_t ret = loop->pollOnce(-1);
diff --git a/services/tests/servicestests/res/raw/netstats_uid_v4 b/services/tests/servicestests/res/raw/netstats_uid_v4
new file mode 100644
index 000000000000..e75fc1ca5c2e
--- /dev/null
+++ b/services/tests/servicestests/res/raw/netstats_uid_v4
Binary files differ
diff --git a/services/tests/servicestests/res/raw/netstats_v1 b/services/tests/servicestests/res/raw/netstats_v1
new file mode 100644
index 000000000000..e80860a6b959
--- /dev/null
+++ b/services/tests/servicestests/res/raw/netstats_v1
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 90b5a2ee57f0..8f5e77e3c3fe 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -39,6 +39,7 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL;
import static org.easymock.EasyMock.anyLong;
+import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
@@ -63,10 +64,12 @@ import android.os.INetworkManagementService;
import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.TrustedTime;
import com.android.server.net.NetworkStatsService;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
+import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
import org.easymock.Capture;
import org.easymock.EasyMock;
@@ -89,6 +92,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private static final String IMSI_1 = "310004";
private static final String IMSI_2 = "310260";
+ private static final long KB_IN_BYTES = 1024;
+ private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES;
+ private static final long GB_IN_BYTES = 1024 * MB_IN_BYTES;
+
private static NetworkTemplate sTemplateWifi = buildTemplateWifi();
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
@@ -282,13 +289,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
verifyAndReset();
- // talk with zombie service to assert stats have gone; and assert that
- // we persisted them to file.
- expectDefaultSettings();
- replay();
- assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
- verifyAndReset();
-
assertStatsFilesExist(true);
// boot through serviceReady() again
@@ -319,6 +319,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
+ // TODO: simulate reboot to test bucket resize
+ @Suppress
public void testStatsBucketResize() throws Exception {
NetworkStatsHistory history = null;
@@ -602,7 +604,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);
verifyAndReset();
-
}
public void testSummaryForAllUid() throws Exception {
@@ -755,11 +756,15 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L));
+
+ final NetworkStats uidStats = new NetworkStats(getElapsedRealtime(), 1)
+ .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
- expectNetworkStatsPoll(tetherIfacePairs, new NetworkStats(getElapsedRealtime(), 1)
- .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L));
+ final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
+ .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L);
+
+ expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -808,6 +813,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
private void expectNetworkState(NetworkState... state) throws Exception {
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
+
+ final LinkProperties linkProp = state.length > 0 ? state[0].linkProperties : null;
+ expect(mConnManager.getActiveLinkProperties()).andReturn(linkProp).atLeastOnce();
}
private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
@@ -815,23 +823,35 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
+ expectNetworkStatsUidDetail(detail, new String[0], new NetworkStats(0L, 0));
+ }
+
+ private void expectNetworkStatsUidDetail(
+ NetworkStats detail, String[] tetherIfacePairs, NetworkStats tetherStats)
+ throws Exception {
expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
+
+ // also include tethering details, since they are folded into UID
+ expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).atLeastOnce();
+ expect(mNetManager.getNetworkStatsTethering(aryEq(tetherIfacePairs)))
+ .andReturn(tetherStats).atLeastOnce();
}
private void expectDefaultSettings() throws Exception {
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
}
- private void expectSettings(long persistThreshold, long bucketDuration, long maxHistory)
+ private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
throws Exception {
expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes();
- expect(mSettings.getPersistThreshold()).andReturn(persistThreshold).anyTimes();
- expect(mSettings.getNetworkBucketDuration()).andReturn(bucketDuration).anyTimes();
- expect(mSettings.getNetworkMaxHistory()).andReturn(maxHistory).anyTimes();
- expect(mSettings.getUidBucketDuration()).andReturn(bucketDuration).anyTimes();
- expect(mSettings.getUidMaxHistory()).andReturn(maxHistory).anyTimes();
- expect(mSettings.getTagMaxHistory()).andReturn(maxHistory).anyTimes();
expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes();
+ expect(mSettings.getGlobalAlertBytes()).andReturn(MB_IN_BYTES).anyTimes();
+ expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes();
+
+ final Config config = new Config(bucketDuration, persistBytes, deleteAge, deleteAge);
+ expect(mSettings.getDevConfig()).andReturn(config).anyTimes();
+ expect(mSettings.getUidConfig()).andReturn(config).anyTimes();
+ expect(mSettings.getUidTagConfig()).andReturn(config).anyTimes();
}
private void expectCurrentTime() throws Exception {
@@ -843,27 +863,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void expectNetworkStatsPoll() throws Exception {
- expectNetworkStatsPoll(new String[0], new NetworkStats(getElapsedRealtime(), 0));
- }
-
- private void expectNetworkStatsPoll(String[] tetherIfacePairs, NetworkStats tetherStats)
- throws Exception {
mNetManager.setGlobalAlert(anyLong());
expectLastCall().anyTimes();
- expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).anyTimes();
- expect(mNetManager.getNetworkStatsTethering(eq(tetherIfacePairs)))
- .andReturn(tetherStats).anyTimes();
}
private void assertStatsFilesExist(boolean exist) {
- final File networkFile = new File(mStatsDir, "netstats.bin");
- final File uidFile = new File(mStatsDir, "netstats_uid.bin");
+ final File basePath = new File(mStatsDir, "netstats");
if (exist) {
- assertTrue(networkFile.exists());
- assertTrue(uidFile.exists());
+ assertTrue(basePath.list().length > 0);
} else {
- assertFalse(networkFile.exists());
- assertFalse(uidFile.exists());
+ assertTrue(basePath.list().length == 0);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
new file mode 100644
index 000000000000..7f05f569e596
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsCollectionTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.NetworkIdentity;
+import android.net.NetworkStats;
+import android.net.NetworkTemplate;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.frameworks.servicestests.R;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+/**
+ * Tests for {@link NetworkStatsCollection}.
+ */
+@MediumTest
+public class NetworkStatsCollectionTest extends AndroidTestCase {
+
+ private static final String TEST_FILE = "test.bin";
+ private static final String TEST_IMSI = "310260000000000";
+
+ public void testReadLegacyNetwork() throws Exception {
+ final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+ stageFile(R.raw.netstats_v1, testFile);
+
+ final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
+ collection.readLegacyNetwork(testFile);
+
+ // verify that history read correctly
+ assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
+ 636014522L, 709291L, 88037144L, 518820L);
+
+ // now export into a unified format
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ collection.write(new DataOutputStream(bos));
+
+ // clear structure completely
+ collection.reset();
+ assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
+ 0L, 0L, 0L, 0L);
+
+ // and read back into structure, verifying that totals are same
+ collection.read(new ByteArrayInputStream(bos.toByteArray()));
+ assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
+ 636014522L, 709291L, 88037144L, 518820L);
+ }
+
+ public void testReadLegacyUid() throws Exception {
+ final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+ stageFile(R.raw.netstats_uid_v4, testFile);
+
+ final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
+ collection.readLegacyUid(testFile, false);
+
+ // verify that history read correctly
+ assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
+ 637073904L, 711398L, 88342093L, 521006L);
+
+ // now export into a unified format
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ collection.write(new DataOutputStream(bos));
+
+ // clear structure completely
+ collection.reset();
+ assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
+ 0L, 0L, 0L, 0L);
+
+ // and read back into structure, verifying that totals are same
+ collection.read(new ByteArrayInputStream(bos.toByteArray()));
+ assertSummaryTotal(collection, buildTemplateMobileAll(TEST_IMSI),
+ 637073904L, 711398L, 88342093L, 521006L);
+ }
+
+ public void testReadLegacyUidTags() throws Exception {
+ final File testFile = new File(getContext().getFilesDir(), TEST_FILE);
+ stageFile(R.raw.netstats_uid_v4, testFile);
+
+ final NetworkStatsCollection collection = new NetworkStatsCollection(30 * MINUTE_IN_MILLIS);
+ collection.readLegacyUid(testFile, true);
+
+ // verify that history read correctly
+ assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
+ 77017831L, 100995L, 35436758L, 92344L);
+
+ // now export into a unified format
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ collection.write(new DataOutputStream(bos));
+
+ // clear structure completely
+ collection.reset();
+ assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
+ 0L, 0L, 0L, 0L);
+
+ // and read back into structure, verifying that totals are same
+ collection.read(new ByteArrayInputStream(bos.toByteArray()));
+ assertSummaryTotalIncludingTags(collection, buildTemplateMobileAll(TEST_IMSI),
+ 77017831L, 100995L, 35436758L, 92344L);
+ }
+
+ /**
+ * Copy a {@link Resources#openRawResource(int)} into {@link File} for
+ * testing purposes.
+ */
+ private void stageFile(int rawId, File file) throws Exception {
+ new File(file.getParent()).mkdirs();
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ in = getContext().getResources().openRawResource(rawId);
+ out = new FileOutputStream(file);
+ Streams.copy(in, out);
+ } finally {
+ IoUtils.closeQuietly(in);
+ IoUtils.closeQuietly(out);
+ }
+ }
+
+ public static NetworkIdentitySet buildWifiIdent() {
+ final NetworkIdentitySet set = new NetworkIdentitySet();
+ set.add(new NetworkIdentity(ConnectivityManager.TYPE_WIFI, 0, null, false));
+ return set;
+ }
+
+ private static void assertSummaryTotal(NetworkStatsCollection collection,
+ NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
+ final NetworkStats.Entry entry = collection.getSummary(
+ template, Long.MIN_VALUE, Long.MAX_VALUE).getTotal(null);
+ assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
+ }
+
+ private static void assertSummaryTotalIncludingTags(NetworkStatsCollection collection,
+ NetworkTemplate template, long rxBytes, long rxPackets, long txBytes, long txPackets) {
+ final NetworkStats.Entry entry = collection.getSummary(
+ template, Long.MIN_VALUE, Long.MAX_VALUE).getTotalIncludingTags(null);
+ assertEntry(entry, rxBytes, rxPackets, txBytes, txPackets);
+ }
+
+ private static void assertEntry(
+ NetworkStats.Entry entry, long rxBytes, long rxPackets, long txBytes, long txPackets) {
+ assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+ assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ }
+}
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 3128592ca004..1a4b574ce5dc 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -47,6 +47,9 @@ public class SignalStrength implements Parcelable {
"none", "poor", "moderate", "good", "great"
};
+ /** @hide */
+ public static final int INVALID_SNR = 0x7FFFFFFF;
+
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
private int mCdmaDbm; // This value is the RSSI value
@@ -96,7 +99,7 @@ public class SignalStrength implements Parcelable {
mLteSignalStrength = -1;
mLteRsrp = -1;
mLteRsrq = -1;
- mLteRssnr = -1;
+ mLteRssnr = INVALID_SNR;
mLteCqi = -1;
isGsm = true;
}
@@ -136,7 +139,8 @@ public class SignalStrength implements Parcelable {
int evdoDbm, int evdoEcio, int evdoSnr,
boolean gsm) {
this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
- evdoDbm, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, gsm);
+ evdoDbm, evdoEcio, evdoSnr, -1, -1,
+ -1, INVALID_SNR, -1, gsm);
}
/**
@@ -292,7 +296,7 @@ public class SignalStrength implements Parcelable {
if ((mLteSignalStrength == -1)
&& (mLteRsrp == -1)
&& (mLteRsrq == -1)
- && (mLteRssnr == -1)
+ && (mLteRssnr == INVALID_SNR)
&& (mLteCqi == -1)) {
level = getGsmLevel();
} else {
@@ -327,7 +331,7 @@ public class SignalStrength implements Parcelable {
if ((mLteSignalStrength == -1)
&& (mLteRsrp == -1)
&& (mLteRsrq == -1)
- && (mLteRssnr == -1)
+ && (mLteRssnr == INVALID_SNR)
&& (mLteCqi == -1)) {
asuLevel = getGsmAsuLevel();
} else {
@@ -363,7 +367,7 @@ public class SignalStrength implements Parcelable {
if ((mLteSignalStrength == -1)
&& (mLteRsrp == -1)
&& (mLteRsrq == -1)
- && (mLteRssnr == -1)
+ && (mLteRssnr == INVALID_SNR)
&& (mLteCqi == -1)) {
dBm = getGsmDbm();
} else {
@@ -566,16 +570,31 @@ public class SignalStrength implements Parcelable {
*/
public int getLteLevel() {
int levelLteRsrp = 0;
+ int levelLteRssnr = 0;
if (mLteRsrp == -1) levelLteRsrp = 0;
- else if (mLteRsrp >= -90) levelLteRsrp = SIGNAL_STRENGTH_GREAT;
- else if (mLteRsrp >= -100) levelLteRsrp = SIGNAL_STRENGTH_GOOD;
- else if (mLteRsrp >= -110) levelLteRsrp = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRsrp >= -118) levelLteRsrp = SIGNAL_STRENGTH_POOR;
- else levelLteRsrp = 0;
-
- if (DBG) log("Lte level: "+levelLteRsrp);
- return levelLteRsrp;
+ else if (mLteRsrp >= -95) levelLteRsrp = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRsrp >= -105) levelLteRsrp = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRsrp >= -115) levelLteRsrp = SIGNAL_STRENGTH_MODERATE;
+ else levelLteRsrp = SIGNAL_STRENGTH_POOR;
+
+ if (mLteRssnr == INVALID_SNR) levelLteRssnr = 0;
+ else if (mLteRssnr >= 45) levelLteRssnr = SIGNAL_STRENGTH_GREAT;
+ else if (mLteRssnr >= 10) levelLteRssnr = SIGNAL_STRENGTH_GOOD;
+ else if (mLteRssnr >= -30) levelLteRssnr = SIGNAL_STRENGTH_MODERATE;
+ else levelLteRssnr = SIGNAL_STRENGTH_POOR;
+
+ int level;
+ if (mLteRsrp == -1)
+ level = levelLteRssnr;
+ else if (mLteRssnr == INVALID_SNR)
+ level = levelLteRsrp;
+ else
+ level = (levelLteRssnr < levelLteRsrp) ? levelLteRssnr : levelLteRsrp;
+
+ if (DBG) log("Lte rsrp level: "+levelLteRsrp
+ + " snr level: " + levelLteRssnr + " level: " + level);
+ return level;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 3dd57ee742f2..f825f31dd005 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -373,10 +373,19 @@ public final class CallManager {
AudioManager audioManager = (AudioManager)
context.getSystemService(Context.AUDIO_SERVICE);
- int mode = AudioManager.MODE_NORMAL;
+ // change the audio mode and request/abandon audio focus according to phone state,
+ // but only on audio mode transitions
switch (getState()) {
case RINGING:
- mode = AudioManager.MODE_RINGTONE;
+ if (audioManager.getMode() != AudioManager.MODE_RINGTONE) {
+ // only request audio focus if the ringtone is going to be heard
+ if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
+ if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING");
+ audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+ }
+ audioManager.setMode(AudioManager.MODE_RINGTONE);
+ }
break;
case OFFHOOK:
Phone offhookPhone = getFgPhone();
@@ -386,18 +395,28 @@ public final class CallManager {
offhookPhone = getBgPhone();
}
+ int newAudioMode = AudioManager.MODE_IN_CALL;
if (offhookPhone instanceof SipPhone) {
- // enable IN_COMMUNICATION audio mode for sipPhone
- mode = AudioManager.MODE_IN_COMMUNICATION;
- } else {
- // enable IN_CALL audio mode for telephony
- mode = AudioManager.MODE_IN_CALL;
+ // enable IN_COMMUNICATION audio mode instead for sipPhone
+ newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
+ }
+ if (audioManager.getMode() != newAudioMode) {
+ // request audio focus before setting the new mode
+ if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL");
+ audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
+ audioManager.setMode(newAudioMode);
+ }
+ break;
+ case IDLE:
+ if (audioManager.getMode() != AudioManager.MODE_NORMAL) {
+ audioManager.setMode(AudioManager.MODE_NORMAL);
+ if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus");
+ // abandon audio focus after the mode has been set back to normal
+ audioManager.abandonAudioFocusForCall();
}
break;
}
- // calling audioManager.setMode() multiple times in a short period of
- // time seems to break the audio recorder in in-call mode
- if (audioManager.getMode() != mode) audioManager.setMode(mode);
}
private Context getContext() {
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 1336818661a5..d0e304fc1a79 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -328,8 +328,11 @@ public abstract class DataConnection extends StateMachine {
String reason = null;
if (dp.onCompletedMsg != null) {
+ // Get ApnContext, but only valid on GSM devices this is a string on CDMA devices.
Message msg = dp.onCompletedMsg;
- alreadySent = (ApnContext)msg.obj;
+ if (msg.obj instanceof ApnContext) {
+ alreadySent = (ApnContext)msg.obj;
+ }
reason = dp.reason;
if (VDBG) {
log(String.format("msg=%s msg.obj=%s", msg.toString(),
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 6b73cc5d4bf1..7da23d05e3d9 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -124,7 +124,9 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
@Override
protected void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, false);
+ // TODO Make a constructor only has boolean gsm as parameter
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, SignalStrength.INVALID_SNR, -1, false);
}
@Override
@@ -429,8 +431,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
setSignalStrengthDefaultValues();
} else {
int[] ints = (int[])ar.result;
- int lteCqi = 99, lteRsrp = -1;
- int lteRssi = 99;
+
+ int lteRssi = -1;
+ int lteRsrp = -1;
+ int lteRsrq = -1;
+ int lteRssnr = SignalStrength.INVALID_SNR;
+ int lteCqi = -1;
+
int offset = 2;
int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
int cdmaEcio = (ints[offset + 1] > 0) ? -ints[offset + 1] : -160;
@@ -438,10 +445,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
int evdoEcio = (ints[offset + 3] > 0) ? -ints[offset + 3] : -1;
int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4]
: -1;
+
if (networkType == ServiceState.RADIO_TECHNOLOGY_LTE) {
- lteRssi = (ints[offset + 5] >= 0) ? ints[offset + 5] : 99;
- lteRsrp = (ints[offset + 6] < 0) ? ints[offset + 6] : -1;
- lteCqi = (ints[offset + 7] >= 0) ? ints[offset + 7] : 99;
+ lteRssi = ints[offset+5];
+ lteRsrp = ints[offset+6];
+ lteRsrq = ints[offset+7];
+ lteRssnr = ints[offset+8];
+ lteCqi = ints[offset+9];
}
if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) {
@@ -449,7 +459,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
evdoSnr, false);
} else {
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
- evdoSnr, lteRssi, lteRsrp, -1, -1, lteCqi, true);
+ evdoSnr, lteRssi, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 92e16ce649f0..0ebeabedacfc 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -675,7 +675,9 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, true);
+ // TODO Make a constructor only has boolean gsm as parameter
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, SignalStrength.INVALID_SNR, -1, true);
}
/**
@@ -1013,7 +1015,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
int lteSignalStrength = -1;
int lteRsrp = -1;
int lteRsrq = -1;
- int lteRssnr = -1;
+ int lteRssnr = SignalStrength.INVALID_SNR;
int lteCqi = -1;
if (ar.exception != null) {
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
index a385f5575b48..5b7627295902 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberUtilsTest.java
@@ -511,8 +511,9 @@ public class PhoneNumberUtilsTest extends AndroidTestCase {
@SmallTest
public void testFormatNumber() {
assertEquals("(650) 291-0000", PhoneNumberUtils.formatNumber("650 2910000", "US"));
- assertEquals("123-4567", PhoneNumberUtils.formatNumber("1234567", "US"));
- assertEquals("(800) 466-4114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US"));
+ assertEquals("223-4567", PhoneNumberUtils.formatNumber("2234567", "US"));
+ // formatNumber doesn't format alpha numbers, but keep them as they are.
+ assertEquals("800-GOOG-114", PhoneNumberUtils.formatNumber("800-GOOG-114", "US"));
}
@SmallTest
@@ -592,9 +593,12 @@ public class PhoneNumberUtilsTest extends AndroidTestCase {
// addressing that, they are also classified as "potential" emergency numbers in the US.
assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("91112345", "US"));
assertTrue(PhoneNumberUtils.isPotentialEmergencyNumber("11212345", "US"));
+
// A valid mobile phone number from Singapore shouldn't be classified as an emergency number
// in Singapore, as 911 is not an emergency number there.
- assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
+ // This test fails on devices that have ecclist property preloaded with 911.
+ // assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("91121234", "SG"));
+
// A valid fixed-line phone number from Brazil shouldn't be classified as an emergency number
// in Brazil, as 112 is not an emergency number there.
assertFalse(PhoneNumberUtils.isPotentialEmergencyNumber("1121234567", "BR"));
diff --git a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
index d2e573ce0564..6f0175e48c08 100644
--- a/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
+++ b/telephony/tests/telephonytests/src/com/android/internal/telephony/PhoneNumberWatcherTest.java
@@ -64,7 +64,7 @@ public class PhoneNumberWatcherTest extends AndroidTestCase {
assertEquals(result1, number.toString());
assertEquals(result1.length(), Selection.getSelectionEnd(number));
// Remove last 5 chars
- final String result2 = "(650) 123";
+ final String result2 = "650-123";
textWatcher.beforeTextChanged(number, number.length() - 4, 4, 0);
number.delete(number.length() - 5, number.length());
Selection.setSelection(number, number.length());
@@ -75,26 +75,26 @@ public class PhoneNumberWatcherTest extends AndroidTestCase {
}
public void testInsertChars() {
- final String init = "(650) 23";
- final String expected1 = "(650) 123";
+ final String init = "650-23";
+ final String expected1 = "650-123";
TextWatcher textWatcher = getTextWatcher();
// Insert one char
SpannableStringBuilder number = new SpannableStringBuilder(init);
- textWatcher.beforeTextChanged(number, 4, 0, 1);
- number.insert(4, "1"); // (6501) 23
- Selection.setSelection(number, 5); // make the cursor at right of 1
- textWatcher.onTextChanged(number, 4, 0, 1);
+ textWatcher.beforeTextChanged(number, 3, 0, 1);
+ number.insert(3, "1"); // 6501-23
+ Selection.setSelection(number, 4); // make the cursor at right of 1
+ textWatcher.onTextChanged(number, 3, 0, 1);
textWatcher.afterTextChanged(number);
assertEquals(expected1, number.toString());
// the cursor should still at the right of '1'
- assertEquals(7, Selection.getSelectionEnd(number));
+ assertEquals(5, Selection.getSelectionEnd(number));
// Insert multiple chars
final String expected2 = "(650) 145-6723";
- textWatcher.beforeTextChanged(number, 7, 0, 4);
- number.insert(7, "4567"); // change to (650) 1456723
- Selection.setSelection(number, 11); // the cursor is at the right of '7'.
+ textWatcher.beforeTextChanged(number, 5, 0, 4);
+ number.insert(5, "4567"); // change to 650-1456723
+ Selection.setSelection(number, 9); // the cursor is at the right of '7'.
textWatcher.onTextChanged(number, 7, 0, 4);
textWatcher.afterTextChanged(number);
assertEquals(expected2, number.toString());
@@ -168,7 +168,7 @@ public class PhoneNumberWatcherTest extends AndroidTestCase {
textWatcher.onTextChanged(number, 0, len, 0);
textWatcher.afterTextChanged(number);
- final String expected2 = "(650) 123-4";
+ final String expected2 = "650-1234";
number = new SpannableStringBuilder(init);
textWatcher.beforeTextChanged(number, 9, 0, 1);
number.insert(9, "4"); // (650) 1234
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index e0ce3228c75b..4ff943e23532 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -21,6 +21,7 @@ import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
+import android.content.ICancelationSignal;
import android.content.IContentProvider;
import android.content.OperationApplicationException;
import android.content.pm.PathPermission;
@@ -92,7 +93,7 @@ public class MockContentProvider extends ContentProvider {
@Override
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) throws RemoteException {
+ String sortOrder, ICancelationSignal cancelationSignal) throws RemoteException {
return MockContentProvider.this.query(url, projection, selection,
selectionArgs, sortOrder);
}
@@ -124,6 +125,11 @@ public class MockContentProvider extends ContentProvider {
throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
}
+
+ @Override
+ public ICancelationSignal createCancelationSignal() throws RemoteException {
+ return null;
+ }
}
private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java
index b7733a4d55eb..41bc27d0e5b4 100644
--- a/test-runner/src/android/test/mock/MockIContentProvider.java
+++ b/test-runner/src/android/test/mock/MockIContentProvider.java
@@ -21,6 +21,7 @@ import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.EntityIterator;
import android.content.IContentProvider;
+import android.content.ICancelationSignal;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
@@ -72,7 +73,7 @@ public class MockIContentProvider implements IContentProvider {
}
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
+ String sortOrder, ICancelationSignal cancelationSignal) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@@ -103,4 +104,9 @@ public class MockIContentProvider implements IContentProvider {
throws RemoteException, FileNotFoundException {
throw new UnsupportedOperationException("unimplemented mock method");
}
+
+ @Override
+ public ICancelationSignal createCancelationSignal() throws RemoteException {
+ throw new UnsupportedOperationException("unimplemented mock method");
+ }
}
diff --git a/tests/ActivityTests/res/anim/slow_enter.xml b/tests/ActivityTests/res/anim/slow_enter.xml
new file mode 100644
index 000000000000..0309643f63cb
--- /dev/null
+++ b/tests/ActivityTests/res/anim/slow_enter.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false" >
+ <scale android:fromXScale="0.9" android:toXScale="1.5"
+ android:fromYScale="0.9" android:toYScale="1.5"
+ android:pivotX="50%" android:pivotY="50%"
+ android:interpolator="@interpolator/slow_enter"
+ android:duration="40000" />
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:interpolator="@android:interpolator/decelerate_cubic"
+ android:duration="1000" />
+</set>
diff --git a/tests/ActivityTests/res/anim/slow_exit.xml b/tests/ActivityTests/res/anim/slow_exit.xml
new file mode 100644
index 000000000000..6cd3114a4c1a
--- /dev/null
+++ b/tests/ActivityTests/res/anim/slow_exit.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false" >
+ <scale android:fromXScale="1.0" android:toXScale="0.9"
+ android:fromYScale="1.0" android:toYScale="0.9"
+ android:pivotX="50%" android:pivotY="50%"
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:duration="300" />
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:interpolator="@android:interpolator/decelerate_cubic"
+ android:duration="300"/>
+</set>
diff --git a/tests/ActivityTests/res/interpolator/slow_enter.xml b/tests/ActivityTests/res/interpolator/slow_enter.xml
new file mode 100644
index 000000000000..ddab1aa8b8b4
--- /dev/null
+++ b/tests/ActivityTests/res/interpolator/slow_enter.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:cycles="10" />
diff --git a/tests/ActivityTests/res/values/themes.xml b/tests/ActivityTests/res/values/themes.xml
new file mode 100644
index 000000000000..67f5938ff217
--- /dev/null
+++ b/tests/ActivityTests/res/values/themes.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <style name="SlowDialog" parent="@android:style/Theme.Holo.Dialog">
+ <item name="android:windowAnimationStyle">@style/SlowDialog</item>
+ </style>
+ <style name="SlowDialog">
+ <item name="android:windowEnterAnimation">@anim/slow_enter</item>
+ <item name="android:windowExitAnimation">@anim/slow_exit</item>
+ </style>
+</resources>
diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
index 583c13cd8ae8..ae42e29c5aac 100644
--- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
+++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java
@@ -22,6 +22,7 @@ import java.util.List;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityThread;
+import android.app.AlertDialog;
import android.app.Application;
import android.content.ActivityNotFoundException;
import android.os.Bundle;
@@ -35,6 +36,8 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ScrollView;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -101,6 +104,20 @@ public class ActivityTestMain extends Activity {
}
@Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ menu.add("Animate!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+ @Override public boolean onMenuItemClick(MenuItem item) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(ActivityTestMain.this,
+ R.style.SlowDialog);
+ builder.setTitle("This is a title");
+ builder.show();
+ return true;
+ }
+ });
+ return true;
+ }
+
+ @Override
protected void onStart() {
super.onStart();
buildUi();
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
index f96e68bcdb90..912d863c6d05 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
@@ -84,7 +84,7 @@ public class ImageProcessingTest extends ActivityInstrumentationTestCase2<ImageP
Log.v(TAG, "RenderScript framew time core: " + t + " ms");
}
long avgValue = sum/ITERATION;
- rsWriter.write("Averge frame time: " + avgValue + " ms\n");
+ rsWriter.write("Average frame time: " + avgValue + " ms\n");
Log.v(TAG, "Average frame time: " + avgValue + " ms");
rsWriter.close();
} catch (IOException e) {
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 c0384789ed05..451d53794689 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-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.
@@ -72,6 +72,8 @@ 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_atomic(this, mRes, mCtx));
+ unitTests.add(new UT_struct(this, mRes, mCtx));
unitTests.add(new UT_math(this, mRes, mCtx));
unitTests.add(new UT_fp_mad(this, mRes, mCtx));
/*
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java
new file mode 100644
index 000000000000..267c5b2cf649
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_atomic extends UnitTest {
+ private Resources mRes;
+
+ protected UT_atomic(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Atomics", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_atomic s = new ScriptC_atomic(pRS, mRes, R.raw.atomic);
+ pRS.setMessageHandler(mRsMessage);
+ s.invoke_atomic_test();
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java
new file mode 100644
index 000000000000..2a55686b3d68
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_struct extends UnitTest {
+ private Resources mRes;
+
+ protected UT_struct(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Struct", ctx);
+ mRes = res;
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ ScriptC_struct s = new ScriptC_struct(pRS, mRes, R.raw.struct);
+ pRS.setMessageHandler(mRsMessage);
+
+ ScriptField_Point2 p = new ScriptField_Point2(pRS, 1);
+ ScriptField_Point2.Item i = new ScriptField_Point2.Item();
+ int val = 100;
+ i.x = val;
+ i.y = val;
+ p.set(i, 0, true);
+ s.bind_point2(p);
+ s.invoke_struct_test(val);
+ pRS.finish();
+ waitForMessage();
+
+ val = 200;
+ p.set_x(0, val, true);
+ p.set_y(0, val, true);
+ s.invoke_struct_test(val);
+ pRS.finish();
+ waitForMessage();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs
new file mode 100644
index 000000000000..f0a504196adc
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs
@@ -0,0 +1,77 @@
+#include "shared.rsh"
+
+// Testing atomic operations
+static bool testUMax(uint32_t dst, uint32_t src) {
+ bool failed = false;
+ uint32_t old = dst;
+ uint32_t expect = (dst > src ? dst : src);
+ uint32_t ret = rsAtomicMax(&dst, src);
+ _RS_ASSERT(old == ret);
+ _RS_ASSERT(dst == expect);
+ return failed;
+}
+
+static bool testUMin(uint32_t dst, uint32_t src) {
+ bool failed = false;
+ uint32_t old = dst;
+ uint32_t expect = (dst < src ? dst : src);
+ uint32_t ret = rsAtomicMin(&dst, src);
+ _RS_ASSERT(old == ret);
+ _RS_ASSERT(dst == expect);
+ return failed;
+}
+
+static bool testUCas(uint32_t dst, uint32_t cmp, uint32_t swp) {
+ bool failed = false;
+ uint32_t old = dst;
+ uint32_t expect = (dst == cmp ? swp : dst);
+ uint32_t ret = rsAtomicCas(&dst, cmp, swp);
+ _RS_ASSERT(old == ret);
+ _RS_ASSERT(dst == expect);
+ return failed;
+}
+
+static bool test_atomics() {
+ bool failed = false;
+
+ failed |= testUMax(5, 6);
+ failed |= testUMax(6, 5);
+ failed |= testUMax(5, 0xf0000006);
+ failed |= testUMax(0xf0000006, 5);
+
+ failed |= testUMin(5, 6);
+ failed |= testUMin(6, 5);
+ failed |= testUMin(5, 0xf0000006);
+ failed |= testUMin(0xf0000006, 5);
+
+ failed |= testUCas(4, 4, 5);
+ failed |= testUCas(4, 5, 5);
+ failed |= testUCas(5, 5, 4);
+ failed |= testUCas(5, 4, 4);
+ failed |= testUCas(0xf0000004, 0xf0000004, 0xf0000005);
+ failed |= testUCas(0xf0000004, 0xf0000005, 0xf0000005);
+ failed |= testUCas(0xf0000005, 0xf0000005, 0xf0000004);
+ failed |= testUCas(0xf0000005, 0xf0000004, 0xf0000004);
+
+ if (failed) {
+ rsDebug("test_atomics FAILED", 0);
+ }
+ else {
+ rsDebug("test_atomics PASSED", 0);
+ }
+
+ return failed;
+}
+
+void atomic_test() {
+ bool failed = false;
+ failed |= test_atomics();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs
new file mode 100644
index 000000000000..1cd728e92748
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs
@@ -0,0 +1,37 @@
+#include "shared.rsh"
+
+typedef struct Point2 {
+ int x;
+ int y;
+} Point_2;
+Point_2 *point2;
+
+static bool test_Point_2(int expected) {
+ bool failed = false;
+
+ rsDebug("Point: ", point2[0].x, point2[0].y);
+ _RS_ASSERT(point2[0].x == expected);
+ _RS_ASSERT(point2[0].y == expected);
+
+ if (failed) {
+ rsDebug("test_Point_2 FAILED", 0);
+ }
+ else {
+ rsDebug("test_Point_2 PASSED", 0);
+ }
+
+ return failed;
+}
+
+void struct_test(int expected) {
+ bool failed = false;
+ failed |= test_Point_2(expected);
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/TileBenchmark/res/values/strings.xml b/tests/TileBenchmark/res/values/strings.xml
index 5af52dcbe4b9..6c7055b62345 100644
--- a/tests/TileBenchmark/res/values/strings.xml
+++ b/tests/TileBenchmark/res/values/strings.xml
@@ -49,8 +49,9 @@
<!-- Drop down menu entry - automatically scroll to the end of the page
with scrollBy() [CHAR LIMIT=15] -->
<string name="movement_auto_scroll">Auto-scroll</string>
- <!-- Drop down menu entry - [CHAR LIMIT=15] -->
- <string name="movement_auto_fling">Auto-fling</string>
+ <!-- Drop down menu entry - automatically record for a set time before
+ stopping [CHAR LIMIT=15] -->
+ <string name="movement_timed">Timed</string>
<!-- Drop down menu entry - manually navigate the page(s), hit 'capture'
button [CHAR LIMIT=15] -->
<string name="movement_manual">Manual</string>
@@ -67,14 +68,21 @@
<!-- 75th percentile - 75% of frames fall below this value [CHAR LIMIT=12]
-->
<string name="percentile_75">75%ile</string>
+ <!-- standard deviation [CHAR LIMIT=12] -->
+ <string name="std_dev">StdDev</string>
+ <!-- mean [CHAR LIMIT=12] -->
+ <string name="mean">mean</string>
+
+
+
<!-- Frame rate [CHAR LIMIT=15] -->
<string name="frames_per_second">Frames/sec</string>
<!-- Portion of viewport covered by good tiles [CHAR LIMIT=15] -->
<string name="viewport_coverage">Coverage</string>
<!-- Milliseconds taken to inval, and re-render the page [CHAR LIMIT=15] -->
<string name="render_millis">RenderMillis</string>
- <!-- Number of rendering stalls while running the test [CHAR LIMIT=15] -->
- <string name="render_stalls">Stalls</string>
+ <!-- Animation Framerate [CHAR LIMIT=15] -->
+ <string name="animation_framerate">AnimFramerate</string>
<!-- Format string for stat value overlay [CHAR LIMIT=15] -->
<string name="format_stat">%4.4f</string>
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java
index cc39b75fe52c..6356cc1b9362 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java
@@ -27,17 +27,57 @@ import android.os.Bundle;
import android.os.Environment;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
+import android.webkit.WebSettings;
+import android.widget.Spinner;
public class PerformanceTest extends
ActivityInstrumentationTestCase2<ProfileActivity> {
+ public static class AnimStat {
+ double aggVal = 0;
+ double aggSqrVal = 0;
+ double count = 0;
+ }
+
private class StatAggregator extends PlaybackGraphs {
private HashMap<String, Double> mDataMap = new HashMap<String, Double>();
+ private HashMap<String, AnimStat> mAnimDataMap = new HashMap<String, AnimStat>();
private int mCount = 0;
+
public void aggregate() {
+ boolean inAnimTests = mAnimTests != null;
+ Resources resources = mWeb.getResources();
+ String animFramerateString = resources.getString(R.string.animation_framerate);
+ for (Map.Entry<String, Double> e : mSingleStats.entrySet()) {
+ String name = e.getKey();
+ if (inAnimTests) {
+ if (name.equals(animFramerateString)) {
+ // in animation testing phase, record animation framerate and aggregate
+ // stats, differentiating on values of mAnimTestNr and mDoubleBuffering
+ String fullName = ANIM_TEST_NAMES[mAnimTestNr] + " " + name;
+ fullName += mDoubleBuffering ? " tiled" : " webkit";
+
+ if (!mAnimDataMap.containsKey(fullName)) {
+ mAnimDataMap.put(fullName, new AnimStat());
+ }
+ AnimStat statVals = mAnimDataMap.get(fullName);
+ statVals.aggVal += e.getValue();
+ statVals.aggSqrVal += e.getValue() * e.getValue();
+ statVals.count += 1;
+ }
+ } else {
+ double aggVal = mDataMap.containsKey(name)
+ ? mDataMap.get(name) : 0;
+ mDataMap.put(name, aggVal + e.getValue());
+ }
+ }
+
+ if (inAnimTests) {
+ return;
+ }
+
mCount++;
- Resources resources = mView.getResources();
for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
String metricLabel = resources.getString(
@@ -53,34 +93,47 @@ public class PerformanceTest extends
mDataMap.put(label, aggVal);
}
}
- for (Map.Entry<String, Double> e : mSingleStats.entrySet()) {
- double aggVal = mDataMap.containsKey(e.getKey())
- ? mDataMap.get(e.getKey()) : 0;
- mDataMap.put(e.getKey(), aggVal + e.getValue());
- }
+
}
+ // build the final bundle of results
public Bundle getBundle() {
Bundle b = new Bundle();
- int count = 0 == mCount ? Integer.MAX_VALUE : mCount;
+ int count = (0 == mCount) ? Integer.MAX_VALUE : mCount;
for (Map.Entry<String, Double> e : mDataMap.entrySet()) {
b.putDouble(e.getKey(), e.getValue() / count);
}
+
+ for (Map.Entry<String, AnimStat> e : mAnimDataMap.entrySet()) {
+ String statName = e.getKey();
+ AnimStat statVals = e.getValue();
+
+ double avg = statVals.aggVal/statVals.count;
+ double stdDev = Math.sqrt((statVals.aggSqrVal / statVals.count) - avg * avg);
+
+ b.putDouble(statName, avg);
+ b.putDouble(statName + " STD DEV", stdDev);
+ }
+
return b;
}
}
ProfileActivity mActivity;
- ProfiledWebView mView;
- StatAggregator mStats = new StatAggregator();
+ ProfiledWebView mWeb;
+ Spinner mMovementSpinner;
+ StatAggregator mStats;
private static final String LOGTAG = "PerformanceTest";
private static final String TEST_LOCATION = "webkit/page_cycler";
private static final String URL_PREFIX = "file://";
private static final String URL_POSTFIX = "/index.html?skip=true";
private static final int MAX_ITERATIONS = 4;
- private static final String TEST_DIRS[] = {
- "alexa25_2011"//, "alexa_us", "android", "dom", "intl2", "moz", "moz2"
+ private static final String SCROLL_TEST_DIRS[] = {
+ "alexa25_2011"
+ };
+ private static final String ANIM_TEST_DIRS[] = {
+ "dhtml"
};
public PerformanceTest() {
@@ -91,7 +144,22 @@ public class PerformanceTest extends
protected void setUp() throws Exception {
super.setUp();
mActivity = getActivity();
- mView = (ProfiledWebView) mActivity.findViewById(R.id.web);
+ mWeb = (ProfiledWebView) mActivity.findViewById(R.id.web);
+ mMovementSpinner = (Spinner) mActivity.findViewById(R.id.movement);
+ mStats = new StatAggregator();
+
+ // use mStats as a condition variable between the UI thread and
+ // this(the testing) thread
+ mActivity.setCallback(new ProfileCallback() {
+ @Override
+ public void profileCallback(RunData data) {
+ mStats.setData(data);
+ synchronized (mStats) {
+ mStats.notify();
+ }
+ }
+ });
+
}
private boolean loadUrl(final String url) {
@@ -100,12 +168,13 @@ public class PerformanceTest extends
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
- mView.loadUrl(url);
+ mWeb.loadUrl(url);
}
});
synchronized (mStats) {
mStats.wait();
}
+
mStats.aggregate();
} catch (InterruptedException e) {
e.printStackTrace();
@@ -114,15 +183,30 @@ public class PerformanceTest extends
return true;
}
- private boolean runIteration() {
+ private boolean validTest(String nextTest) {
+ // if testing animations, test must be in mAnimTests
+ if (mAnimTests == null)
+ return true;
+
+ for (String test : mAnimTests) {
+ if (test.equals(nextTest)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean runIteration(String[] testDirs) {
File sdFile = Environment.getExternalStorageDirectory();
- for (String testDirName : TEST_DIRS) {
+ for (String testDirName : testDirs) {
File testDir = new File(sdFile, TEST_LOCATION + "/" + testDirName);
Log.d(LOGTAG, "Testing dir: '" + testDir.getAbsolutePath()
+ "', exists=" + testDir.exists());
+
for (File siteDir : testDir.listFiles()) {
- if (!siteDir.isDirectory())
+ if (!siteDir.isDirectory() || !validTest(siteDir.getName())) {
continue;
+ }
if (!loadUrl(URL_PREFIX + siteDir.getAbsolutePath()
+ URL_POSTFIX)) {
@@ -133,7 +217,44 @@ public class PerformanceTest extends
return true;
}
- public void testMetrics() {
+ private boolean runTestDirs(String[] testDirs) {
+ for (int i = 0; i < MAX_ITERATIONS; i++)
+ if (!runIteration(testDirs)) {
+ return false;
+ }
+ return true;
+ }
+
+ private void pushDoubleBuffering() {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ mWeb.setDoubleBuffering(mDoubleBuffering);
+ }
+ });
+ }
+
+ private void setScrollingTestingMode(final boolean scrolled) {
+ getInstrumentation().runOnMainSync(new Runnable() {
+ public void run() {
+ mMovementSpinner.setSelection(scrolled ? 0 : 2);
+ }
+ });
+ }
+
+
+ private String[] mAnimTests = null;
+ private int mAnimTestNr = -1;
+ private boolean mDoubleBuffering = true;
+ private static final String[] ANIM_TEST_NAMES = {
+ "slow", "fast"
+ };
+ private static final String[][] ANIM_TESTS = {
+ {"scrolling", "replaceimages", "layers5", "layers1"},
+ {"slidingballs", "meter", "slidein", "fadespacing", "colorfade",
+ "mozilla", "movingtext", "diagball", "zoom", "imageslide"},
+ };
+
+ private boolean checkMedia() {
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)
@@ -141,27 +262,43 @@ public class PerformanceTest extends
Log.d(LOGTAG, "ARG Can't access sd card!");
// Can't read the SD card, fail and die!
getInstrumentation().sendStatus(1, null);
- return;
+ return false;
}
+ return true;
+ }
- // use mGraphs as a condition variable between the UI thread and
- // this(the testing) thread
- mActivity.setCallback(new ProfileCallback() {
- @Override
- public void profileCallback(RunData data) {
- Log.d(LOGTAG, "test completion callback");
- mStats.setData(data);
- synchronized (mStats) {
- mStats.notify();
+ public void testMetrics() {
+ setScrollingTestingMode(true);
+ if (checkMedia() && runTestDirs(SCROLL_TEST_DIRS)) {
+ getInstrumentation().sendStatus(0, mStats.getBundle());
+ } else {
+ getInstrumentation().sendStatus(1, null);
+ }
+ }
+
+ private boolean runAnimationTests() {
+ for (int doubleBuffer = 0; doubleBuffer <= 1; doubleBuffer++) {
+ mDoubleBuffering = doubleBuffer == 1;
+ pushDoubleBuffering();
+ for (mAnimTestNr = 0; mAnimTestNr < ANIM_TESTS.length; mAnimTestNr++) {
+ mAnimTests = ANIM_TESTS[mAnimTestNr];
+ if (!runTestDirs(ANIM_TEST_DIRS)) {
+ return false;
}
}
- });
+ }
+ return true;
+ }
- for (int i = 0; i < MAX_ITERATIONS; i++)
- if (!runIteration()) {
- getInstrumentation().sendStatus(1, null);
- return;
- }
- getInstrumentation().sendStatus(0, mStats.getBundle());
+ public void testAnimations() {
+ // instead of autoscrolling, load each page until either an timer fires,
+ // or the animation signals complete via javascript
+ setScrollingTestingMode(false);
+
+ if (checkMedia() && runAnimationTests()) {
+ getInstrumentation().sendStatus(0, mStats.getBundle());
+ } else {
+ getInstrumentation().sendStatus(1, null);
+ }
}
}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
index 9ea90f8d512d..a3ae9be579ec 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
@@ -80,7 +80,7 @@ public class PlaybackGraphs {
for (int tileID = 1; tileID < frame.length; tileID++) {
TileData data = frame[tileID];
double coverage = viewportCoverage(frame[0], data);
- total += coverage * (data.isReady ? 1 : 0);
+ total += coverage * (data.isReady ? 100 : 0);
totalCount += coverage;
}
if (totalCount == 0) {
@@ -91,7 +91,7 @@ public class PlaybackGraphs {
@Override
public double getMax() {
- return 1;
+ return 100;
}
@Override
@@ -108,6 +108,9 @@ public class PlaybackGraphs {
}
public static double getPercentile(double sortedValues[], double ratioAbove) {
+ if (sortedValues.length == 0)
+ return -1;
+
double index = ratioAbove * (sortedValues.length - 1);
int intIndex = (int) Math.floor(index);
if (index == intIndex) {
@@ -118,6 +121,31 @@ public class PlaybackGraphs {
+ sortedValues[intIndex + 1] * (alpha);
}
+ public static double getMean(double sortedValues[]) {
+ if (sortedValues.length == 0)
+ return -1;
+
+ double agg = 0;
+ for (double val : sortedValues) {
+ agg += val;
+ }
+ return agg / sortedValues.length;
+ }
+
+ public static double getStdDev(double sortedValues[]) {
+ if (sortedValues.length == 0)
+ return -1;
+
+ double agg = 0;
+ double sqrAgg = 0;
+ for (double val : sortedValues) {
+ agg += val;
+ sqrAgg += val*val;
+ }
+ double mean = agg / sortedValues.length;
+ return Math.sqrt((sqrAgg / sortedValues.length) - (mean * mean));
+ }
+
protected static StatGen[] Stats = new StatGen[] {
new StatGen() {
@Override
@@ -149,6 +177,26 @@ public class PlaybackGraphs {
public int getLabelId() {
return R.string.percentile_75;
}
+ }, new StatGen() {
+ @Override
+ public double getValue(double[] sortedValues) {
+ return getStdDev(sortedValues);
+ }
+
+ @Override
+ public int getLabelId() {
+ return R.string.std_dev;
+ }
+ }, new StatGen() {
+ @Override
+ public double getValue(double[] sortedValues) {
+ return getMean(sortedValues);
+ }
+
+ @Override
+ public int getLabelId() {
+ return R.string.mean;
+ }
},
};
@@ -159,40 +207,47 @@ public class PlaybackGraphs {
}
private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>();
- protected double[][] mStats = new double[Metrics.length][Stats.length];
+ protected final double[][] mStats = new double[Metrics.length][Stats.length];
protected HashMap<String, Double> mSingleStats;
+ private void gatherFrameMetric(int metricIndex, double metricValues[], RunData data) {
+ // create graph out of rectangles, one per frame
+ int lastBar = 0;
+ for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) {
+ TileData frame[] = data.frames[frameIndex];
+ int newBar = (frame[0].top + frame[0].bottom) / 2;
+
+ MetricGen s = Metrics[metricIndex];
+ double absoluteValue = s.getValue(frame);
+ double relativeValue = absoluteValue / s.getMax();
+ relativeValue = Math.min(1,relativeValue);
+ relativeValue = Math.max(0,relativeValue);
+ int rightPos = (int) (-BAR_WIDTH * metricIndex);
+ int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue));
+
+ ShapeDrawable graphBar = new ShapeDrawable();
+ graphBar.getPaint().setColor(Color.BLUE);
+ graphBar.setBounds(leftPos, lastBar, rightPos, newBar);
+
+ mShapes.add(graphBar);
+ metricValues[frameIndex] = absoluteValue;
+ lastBar = newBar;
+ }
+ }
+
public void setData(RunData data) {
mShapes.clear();
double metricValues[] = new double[data.frames.length];
+ mSingleStats = data.singleStats;
+
if (data.frames.length == 0) {
return;
}
for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) {
- // create graph out of rectangles, one per frame
- int lastBar = 0;
- for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) {
- TileData frame[] = data.frames[frameIndex];
- int newBar = (frame[0].top + frame[0].bottom) / 2;
-
- MetricGen s = Metrics[metricIndex];
- double absoluteValue = s.getValue(frame);
- double relativeValue = absoluteValue / s.getMax();
- relativeValue = Math.min(1,relativeValue);
- relativeValue = Math.max(0,relativeValue);
- int rightPos = (int) (-BAR_WIDTH * metricIndex);
- int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue));
-
- ShapeDrawable graphBar = new ShapeDrawable();
- graphBar.getPaint().setColor(Color.BLUE);
- graphBar.setBounds(leftPos, lastBar, rightPos, newBar);
-
- mShapes.add(graphBar);
- metricValues[frameIndex] = absoluteValue;
- lastBar = newBar;
- }
+ // calculate metric based on list of frames
+ gatherFrameMetric(metricIndex, metricValues, data);
// store aggregate statistics per metric (median, and similar)
Arrays.sort(metricValues);
@@ -200,8 +255,6 @@ public class PlaybackGraphs {
mStats[metricIndex][statIndex] =
Stats[statIndex].getValue(metricValues);
}
-
- mSingleStats = data.singleStats;
}
}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
index d38d006f1546..2e771577a043 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
@@ -22,11 +22,12 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.util.Log;
import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
-import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
@@ -49,6 +50,8 @@ import java.io.ObjectOutputStream;
*/
public class ProfileActivity extends Activity {
+ private static final int TIMED_RECORD_MILLIS = 2000;
+
public interface ProfileCallback {
public void profileCallback(RunData data);
}
@@ -65,6 +68,7 @@ public class ProfileActivity extends Activity {
LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
+ TimedLoggingWebViewClient mTimedLoggingWebViewClient = new TimedLoggingWebViewClient();
private enum TestingState {
NOT_TESTING,
@@ -93,18 +97,18 @@ public class ProfileActivity extends Activity {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
String movementStr = parent.getItemAtPosition(position).toString();
- if (movementStr == getResources().getString(
- R.string.movement_auto_scroll)
- || movementStr == getResources().getString(
- R.string.movement_auto_fling)) {
+ if (movementStr == getResources().getString(R.string.movement_auto_scroll)) {
mWeb.setWebViewClient(mAutoLoggingWebViewClient);
mCaptureButton.setEnabled(false);
mVelocitySpinner.setEnabled(true);
- } else if (movementStr == getResources().getString(
- R.string.movement_manual)) {
+ } else if (movementStr == getResources().getString(R.string.movement_manual)) {
mWeb.setWebViewClient(mLoggingWebViewClient);
mCaptureButton.setEnabled(true);
mVelocitySpinner.setEnabled(false);
+ } else if (movementStr == getResources().getString(R.string.movement_timed)) {
+ mWeb.setWebViewClient(mTimedLoggingWebViewClient);
+ mCaptureButton.setEnabled(false);
+ mVelocitySpinner.setEnabled(false);
}
}
@@ -124,16 +128,46 @@ public class ProfileActivity extends Activity {
super.onPageStarted(view, url, favicon);
mUrl.setText(url);
}
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ view.requestFocus();
+ ((ProfiledWebView)view).onPageFinished();
+ }
}
private class AutoLoggingWebViewClient extends LoggingWebViewClient {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ startViewProfiling(true);
+ }
@Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ super.onPageStarted(view, url, favicon);
+ setTestingState(TestingState.PRE_TESTING);
+ }
+ }
+
+ private class TimedLoggingWebViewClient extends LoggingWebViewClient {
+ @Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
- view.requestFocus();
+ startViewProfiling(false);
- startViewProfiling(true);
+ // after a fixed time after page finished, stop testing
+ new CountDownTimer(TIMED_RECORD_MILLIS, TIMED_RECORD_MILLIS) {
+ @Override
+ public void onTick(long millisUntilFinished) {
+ }
+
+ @Override
+ public void onFinish() {
+ mWeb.stopScrollTest();
+ }
+ }.start();
}
@Override
@@ -178,11 +212,13 @@ public class ProfileActivity extends Activity {
mMovementSpinner.setEnabled(false);
break;
case START_TESTING:
+ mCaptureButton.setChecked(true);
mUrl.setBackgroundResource(R.color.background_start_testing);
mInspectButton.setEnabled(false);
mMovementSpinner.setEnabled(false);
break;
case STOP_TESTING:
+ mCaptureButton.setChecked(false);
mUrl.setBackgroundResource(R.color.background_stop_testing);
break;
case SAVED_TESTING:
@@ -195,7 +231,6 @@ public class ProfileActivity extends Activity {
/** auto - automatically scroll. */
private void startViewProfiling(boolean auto) {
// toggle capture button to indicate capture state to user
- mCaptureButton.setChecked(true);
mWeb.startScrollTest(mCallback, auto);
setTestingState(TestingState.START_TESTING);
}
@@ -217,7 +252,7 @@ public class ProfileActivity extends Activity {
public void profileCallback(RunData data) {
new StoreFileTask().execute(new Pair<String, RunData>(
TEMP_FILENAME, data));
- mCaptureButton.setChecked(false);
+ Log.d("ProfileActivity", "stored " + data.frames.length + " frames in file");
setTestingState(TestingState.STOP_TESTING);
}
});
@@ -245,8 +280,8 @@ public class ProfileActivity extends Activity {
// Movement spinner
String content[] = {
getResources().getString(R.string.movement_auto_scroll),
- getResources().getString(R.string.movement_auto_fling),
- getResources().getString(R.string.movement_manual)
+ getResources().getString(R.string.movement_manual),
+ getResources().getString(R.string.movement_timed)
};
adapter = new ArrayAdapter<CharSequence>(this,
android.R.layout.simple_spinner_item, content);
@@ -270,13 +305,7 @@ public class ProfileActivity extends Activity {
});
// Custom profiling WebView
- WebSettings settings = mWeb.getSettings();
- settings.setJavaScriptEnabled(true);
- settings.setSupportZoom(true);
- settings.setEnableSmoothTransition(true);
- settings.setBuiltInZoomControls(true);
- settings.setLoadWithOverviewMode(true);
- settings.setProperty("use_minimal_memory", "false"); // prefetch tiles, as browser does
+ mWeb.init(this);
mWeb.setWebViewClient(new LoggingWebViewClient());
// URL text entry
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
index 83f166844d13..a706f781cfb1 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
@@ -20,21 +20,28 @@ import android.content.Context;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.util.Log;
+import android.webkit.WebSettings;
import android.webkit.WebView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
import com.test.tilebenchmark.ProfileActivity.ProfileCallback;
import com.test.tilebenchmark.RunData.TileData;
public class ProfiledWebView extends WebView {
+ private static final String LOGTAG = "ProfiledWebView";
+
private int mSpeed;
private boolean mIsTesting = false;
private boolean mIsScrolling = false;
private ProfileCallback mCallback;
private long mContentInvalMillis;
- private boolean mHadToBeForced = false;
private static final int LOAD_STALL_MILLIS = 2000; // nr of millis after load,
// before test is forced
+ private double mLoadTime;
+ private double mAnimationTime;
public ProfiledWebView(Context context) {
super(context);
@@ -53,6 +60,39 @@ public class ProfiledWebView extends WebView {
super(context, attrs, defStyle, privateBrowsing);
}
+ private class JavaScriptInterface {
+ Context mContext;
+
+ /** Instantiate the interface and set the context */
+ JavaScriptInterface(Context c) {
+ mContext = c;
+ }
+
+ /** Show a toast from the web page */
+ public void animationComplete() {
+ Toast.makeText(mContext, "Animation complete!", Toast.LENGTH_SHORT).show();
+ //Log.d(LOGTAG, "anim complete");
+ mAnimationTime = System.currentTimeMillis();
+ }
+ }
+
+ public void init(Context c) {
+ WebSettings settings = getSettings();
+ settings.setJavaScriptEnabled(true);
+ settings.setSupportZoom(true);
+ settings.setEnableSmoothTransition(true);
+ settings.setBuiltInZoomControls(true);
+ settings.setLoadWithOverviewMode(true);
+ settings.setProperty("use_minimal_memory", "false"); // prefetch tiles, as browser does
+ addJavascriptInterface(new JavaScriptInterface(c), "Android");
+ mAnimationTime = 0;
+ mLoadTime = 0;
+ }
+
+ public void onPageFinished() {
+ mLoadTime = System.currentTimeMillis();
+ }
+
@Override
protected void onDraw(android.graphics.Canvas canvas) {
if (mIsTesting && mIsScrolling) {
@@ -72,9 +112,12 @@ public class ProfiledWebView extends WebView {
* scrolling, invalidate all content and redraw it, measuring time taken.
*/
public void startScrollTest(ProfileCallback callback, boolean autoScrolling) {
- mIsScrolling = autoScrolling;
mCallback = callback;
mIsTesting = false;
+ mIsScrolling = false;
+ WebSettings settings = getSettings();
+ settings.setProperty("tree_updates", "0");
+
if (autoScrolling) {
// after a while, force it to start even if the pages haven't swapped
@@ -86,13 +129,18 @@ public class ProfiledWebView extends WebView {
@Override
public void onFinish() {
// invalidate all content, and kick off redraw
+ Log.d("ProfiledWebView",
+ "kicking off test with callback registration, and tile discard...");
registerPageSwapCallback();
discardAllTextures();
invalidate();
-
+ mIsScrolling = true;
mContentInvalMillis = System.currentTimeMillis();
}
}.start();
+ } else {
+ mIsTesting = true;
+ tileProfilingStart();
}
}
@@ -102,13 +150,35 @@ public class ProfiledWebView extends WebView {
*/
@Override
protected void pageSwapCallback(boolean startAnim) {
- mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
- super.pageSwapCallback(startAnim);
- Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis
- + "millis");
- mIsTesting = true;
- invalidate(); // ensure a redraw so that auto-scrolling can occur
- tileProfilingStart();
+ if (!mIsTesting && mIsScrolling) {
+ // kick off testing
+ mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
+ super.pageSwapCallback(startAnim);
+ Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis + "millis");
+ mIsTesting = true;
+ invalidate(); // ensure a redraw so that auto-scrolling can occur
+ tileProfilingStart();
+ }
+ }
+
+ private double animFramerate() {
+ WebSettings settings = getSettings();
+ String updatesString = settings.getProperty("tree_updates");
+ int updates = (updatesString == null) ? -1 : Integer.parseInt(updatesString);
+
+ double animationTime;
+ if (mAnimationTime == 0) {
+ animationTime = System.currentTimeMillis() - mLoadTime;
+ } else {
+ animationTime = mAnimationTime - mLoadTime;
+ }
+
+ return updates * 1000 / animationTime;
+ }
+
+ public void setDoubleBuffering(boolean useDoubleBuffering) {
+ WebSettings settings = getSettings();
+ settings.setProperty("use_double_buffering", useDoubleBuffering ? "true" : "false");
}
/*
@@ -127,11 +197,12 @@ public class ProfiledWebView extends WebView {
// record the time spent (before scrolling) rendering the page
data.singleStats.put(getResources().getString(R.string.render_millis),
(double)mContentInvalMillis);
- // record if the page render timed out
- Log.d("ProfiledWebView", "hadtobeforced = " + mHadToBeForced);
- data.singleStats.put(getResources().getString(R.string.render_stalls),
- mHadToBeForced ? 1.0 : 0.0);
- mHadToBeForced = false;
+
+ // record framerate
+ double framerate = animFramerate();
+ Log.d(LOGTAG, "anim framerate was "+framerate);
+ data.singleStats.put(getResources().getString(R.string.animation_framerate),
+ framerate);
for (int frame = 0; frame < data.frames.length; frame++) {
data.frames[frame] = new TileData[
@@ -159,6 +230,8 @@ public class ProfiledWebView extends WebView {
@Override
public void loadUrl(String url) {
+ mAnimationTime = 0;
+ mLoadTime = 0;
if (!url.startsWith("http://") && !url.startsWith("file://")) {
url = "http://" + url;
}
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index f0c215eeffa5..6ce665b467f1 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1084,12 +1084,17 @@ bool AaptGroupEntry::getDensityName(const char* name,
if (out) out->density = ResTable_config::DENSITY_HIGH;
return true;
}
-
+
if (strcmp(name, "xhdpi") == 0) {
- if (out) out->density = ResTable_config::DENSITY_MEDIUM*2;
+ if (out) out->density = ResTable_config::DENSITY_XHIGH;
return true;
}
-
+
+ if (strcmp(name, "xxhdpi") == 0) {
+ if (out) out->density = ResTable_config::DENSITY_XXHIGH;
+ return true;
+ }
+
char* c = (char*)name;
while (*c >= '0' && *c <= '9') {
c++;
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index d5345b277caf..c5a397c73390 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -53,17 +53,6 @@ enum {
AXIS_END = AXIS_VERSION,
};
-enum {
- SDK_CUPCAKE = 3,
- SDK_DONUT = 4,
- SDK_ECLAIR = 5,
- SDK_ECLAIR_0_1 = 6,
- SDK_MR1 = 7,
- SDK_FROYO = 8,
- SDK_HONEYCOMB_MR2 = 13,
- SDK_ICE_CREAM_SANDWICH = 14,
-};
-
/**
* This structure contains a specific variation of a single file out
* of all the variations it can have that we can have.
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 2d1060ba23a0..8e3a1c9d11af 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -14,6 +14,18 @@
#include <utils/String8.h>
#include <utils/Vector.h>
+enum {
+ SDK_CUPCAKE = 3,
+ SDK_DONUT = 4,
+ SDK_ECLAIR = 5,
+ SDK_ECLAIR_0_1 = 6,
+ SDK_MR1 = 7,
+ SDK_FROYO = 8,
+ SDK_HONEYCOMB_MR2 = 13,
+ SDK_ICE_CREAM_SANDWICH = 14,
+ SDK_ICE_CREAM_SANDWICH_MR1 = 15,
+};
+
/*
* Things we can do.
*/
@@ -82,7 +94,6 @@ public:
void setRequireLocalization(bool val) { mRequireLocalization = val; }
bool getPseudolocalize(void) const { return mPseudolocalize; }
void setPseudolocalize(bool val) { mPseudolocalize = val; }
- bool getWantUTF16(void) const { return mWantUTF16; }
void setWantUTF16(bool val) { mWantUTF16 = val; }
bool getValues(void) const { return mValues; }
void setValues(bool val) { mValues = val; }
@@ -103,6 +114,10 @@ public:
bool getGenDependencies() { return mGenDependencies; }
void setGenDependencies(bool val) { mGenDependencies = val; }
+ bool getUTF16StringsOption() {
+ return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
+ }
+
/*
* Input options.
*/
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 89942de57eaa..607056a6c1f2 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -479,6 +479,11 @@ int doDump(Bundle* bundle)
#ifndef HAVE_ANDROID_OS
res.print(bundle->getValues());
#endif
+
+ } else if (strcmp("strings", option) == 0) {
+ const ResStringPool* pool = res.getTableStringBlock(0);
+ printStringPool(pool);
+
} else if (strcmp("xmltree", option) == 0) {
if (bundle->getFileSpecCount() < 3) {
fprintf(stderr, "ERROR: no dump xmltree resource file specified\n");
@@ -1382,7 +1387,7 @@ int doDump(Bundle* bundle)
delete dir;
}
} else if (strcmp("badger", option) == 0) {
- printf(CONSOLE_DATA);
+ printf("%s", CONSOLE_DATA);
} else if (strcmp("configurations", option) == 0) {
Vector<ResTable_config> configs;
res.getConfigurations(&configs);
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 1ecf7daef123..c0fe5380afa5 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -847,8 +847,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
* request UTF-16 encoding and the parameters of this package
* allow UTF-8 to be used.
*/
- if (!bundle->getWantUTF16()
- && bundle->isMinSdkAtLeast(SDK_FROYO)) {
+ if (!bundle->getUTF16StringsOption()) {
xmlFlags |= XML_COMPILE_UTF8;
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index fdb39ca08e9f..f59bba2815a2 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2047,7 +2047,8 @@ bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
uint32_t attrID,
const Vector<StringPool::entry_style_span>* style,
String16* outStr, void* accessorCookie,
- uint32_t attrType)
+ uint32_t attrType, const String8* configTypeName,
+ const ConfigDescription* config)
{
String16 finalStr;
@@ -2075,10 +2076,19 @@ bool ResourceTable::stringToValue(Res_value* outValue, StringPool* pool,
if (outValue->dataType == outValue->TYPE_STRING) {
// Should do better merging styles.
if (pool) {
+ String8 configStr;
+ if (config != NULL) {
+ configStr = config->toString();
+ } else {
+ configStr = "(null)";
+ }
+ NOISY(printf("Adding to pool string style #%d config %s: %s\n",
+ style != NULL ? style->size() : 0,
+ configStr.string(), String8(finalStr).string()));
if (style != NULL && style->size() > 0) {
- outValue->data = pool->add(finalStr, *style);
+ outValue->data = pool->add(finalStr, *style, configTypeName, config);
} else {
- outValue->data = pool->add(finalStr, true);
+ outValue->data = pool->add(finalStr, true, configTypeName, config);
}
} else {
// Caller will fill this in later.
@@ -2537,16 +2547,19 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
return err;
}
+ const ConfigDescription nullConfig;
+
const size_t N = mOrderedPackages.size();
size_t pi;
const static String16 mipmap16("mipmap");
- bool useUTF8 = !bundle->getWantUTF16() && bundle->isMinSdkAtLeast(SDK_FROYO);
+ bool useUTF8 = !bundle->getUTF16StringsOption();
// Iterate through all data, collecting all values (strings,
// references, etc).
StringPool valueStrings = StringPool(false, useUTF8);
+ Vector<sp<Entry> > allEntries;
for (pi=0; pi<N; pi++) {
sp<Package> p = mOrderedPackages.itemAt(pi);
if (p->getTypes().size() == 0) {
@@ -2567,6 +2580,19 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
const String16 typeName(t->getName());
typeStrings.add(typeName, false);
+ // This is a hack to tweak the sorting order of the final strings,
+ // to put stuff that is generally not language-specific first.
+ String8 configTypeName(typeName);
+ if (configTypeName == "drawable" || configTypeName == "layout"
+ || configTypeName == "color" || configTypeName == "anim"
+ || configTypeName == "interpolator" || configTypeName == "animator"
+ || configTypeName == "xml" || configTypeName == "menu"
+ || configTypeName == "mipmap" || configTypeName == "raw") {
+ configTypeName = "1complex";
+ } else {
+ configTypeName = "2value";
+ }
+
const bool filterable = (typeName != mipmap16);
const size_t N = t->getOrderedConfigs().size();
@@ -2586,10 +2612,21 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
continue;
}
e->setNameIndex(keyStrings.add(e->getName(), true));
- status_t err = e->prepareFlatten(&valueStrings, this);
+
+ // If this entry has no values for other configs,
+ // and is the default config, then it is special. Otherwise
+ // we want to add it with the config info.
+ ConfigDescription* valueConfig = NULL;
+ if (N != 1 || config == nullConfig) {
+ valueConfig = &config;
+ }
+
+ status_t err = e->prepareFlatten(&valueStrings, this,
+ &configTypeName, &config);
if (err != NO_ERROR) {
return err;
}
+ allEntries.add(e);
}
}
}
@@ -2598,6 +2635,17 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
p->setKeyStrings(keyStrings.createStringBlock());
}
+ if (bundle->getOutputAPKFile() != NULL) {
+ // Now we want to sort the value strings for better locality. This will
+ // cause the positions of the strings to change, so we need to go back
+ // through out resource entries and update them accordingly. Only need
+ // to do this if actually writing the output file.
+ valueStrings.sortByConfig();
+ for (pi=0; pi<allEntries.size(); pi++) {
+ allEntries[pi]->remapStringValue(&valueStrings);
+ }
+ }
+
ssize_t strAmt = 0;
// Now build the array of package chunks.
@@ -3137,14 +3185,16 @@ status_t ResourceTable::Entry::assignResourceIds(ResourceTable* table,
return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
}
-status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table)
+status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable* table,
+ const String8* configTypeName, const ConfigDescription* config)
{
if (mType == TYPE_ITEM) {
Item& it = mItem;
AccessorCookie ac(it.sourcePos, String8(mName), String8(it.value));
if (!table->stringToValue(&it.parsedValue, strings,
it.value, false, true, 0,
- &it.style, NULL, &ac, mItemFormat)) {
+ &it.style, NULL, &ac, mItemFormat,
+ configTypeName, config)) {
return UNKNOWN_ERROR;
}
} else if (mType == TYPE_BAG) {
@@ -3155,7 +3205,8 @@ status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable
AccessorCookie ac(it.sourcePos, String8(key), String8(it.value));
if (!table->stringToValue(&it.parsedValue, strings,
it.value, false, true, it.bagKeyId,
- &it.style, NULL, &ac, it.format)) {
+ &it.style, NULL, &ac, it.format,
+ configTypeName, config)) {
return UNKNOWN_ERROR;
}
}
@@ -3167,6 +3218,29 @@ status_t ResourceTable::Entry::prepareFlatten(StringPool* strings, ResourceTable
return NO_ERROR;
}
+status_t ResourceTable::Entry::remapStringValue(StringPool* strings)
+{
+ if (mType == TYPE_ITEM) {
+ Item& it = mItem;
+ if (it.parsedValue.dataType == Res_value::TYPE_STRING) {
+ it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);
+ }
+ } else if (mType == TYPE_BAG) {
+ const size_t N = mBag.size();
+ for (size_t i=0; i<N; i++) {
+ Item& it = mBag.editValueAt(i);
+ if (it.parsedValue.dataType == Res_value::TYPE_STRING) {
+ it.parsedValue.data = strings->mapOriginalPosToNewPos(it.parsedValue.data);
+ }
+ }
+ } else {
+ mPos.error("Error: entry %s is not a single item or a bag.\n",
+ String8(mName).string());
+ return UNKNOWN_ERROR;
+ }
+ return NO_ERROR;
+}
+
ssize_t ResourceTable::Entry::flatten(Bundle* bundle, const sp<AaptFile>& data, bool isPublic)
{
size_t amt = 0;
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index 8123bb3d4226..a3e066690fba 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -76,6 +76,37 @@ public:
class Type;
class Entry;
+ struct ConfigDescription : public ResTable_config {
+ ConfigDescription() {
+ memset(this, 0, sizeof(*this));
+ size = sizeof(ResTable_config);
+ }
+ ConfigDescription(const ResTable_config&o) {
+ *static_cast<ResTable_config*>(this) = o;
+ size = sizeof(ResTable_config);
+ }
+ ConfigDescription(const ConfigDescription&o) {
+ *static_cast<ResTable_config*>(this) = o;
+ }
+
+ ConfigDescription& operator=(const ResTable_config& o) {
+ *static_cast<ResTable_config*>(this) = o;
+ size = sizeof(ResTable_config);
+ return *this;
+ }
+ ConfigDescription& operator=(const ConfigDescription& o) {
+ *static_cast<ResTable_config*>(this) = o;
+ return *this;
+ }
+
+ inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }
+ inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }
+ inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }
+ inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }
+ inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }
+ inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }
+ };
+
ResourceTable(Bundle* bundle, const String16& assetsPackage);
status_t addIncludedResources(Bundle* bundle, const sp<AaptAssets>& assets);
@@ -183,7 +214,9 @@ public:
uint32_t attrID,
const Vector<StringPool::entry_style_span>* style = NULL,
String16* outStr = NULL, void* accessorCookie = NULL,
- uint32_t attrType = ResTable_map::TYPE_ANY);
+ uint32_t attrType = ResTable_map::TYPE_ANY,
+ const String8* configTypeName = NULL,
+ const ConfigDescription* config = NULL);
status_t assignResourceIds();
status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
@@ -305,7 +338,10 @@ public:
status_t assignResourceIds(ResourceTable* table,
const String16& package);
- status_t prepareFlatten(StringPool* strings, ResourceTable* table);
+ status_t prepareFlatten(StringPool* strings, ResourceTable* table,
+ const String8* configTypeName, const ConfigDescription* config);
+
+ status_t remapStringValue(StringPool* strings);
ssize_t flatten(Bundle*, const sp<AaptFile>& data, bool isPublic);
@@ -322,37 +358,6 @@ public:
uint32_t mParentId;
SourcePos mPos;
};
-
- struct ConfigDescription : public ResTable_config {
- ConfigDescription() {
- memset(this, 0, sizeof(*this));
- size = sizeof(ResTable_config);
- }
- ConfigDescription(const ResTable_config&o) {
- *static_cast<ResTable_config*>(this) = o;
- size = sizeof(ResTable_config);
- }
- ConfigDescription(const ConfigDescription&o) {
- *static_cast<ResTable_config*>(this) = o;
- }
-
- ConfigDescription& operator=(const ResTable_config& o) {
- *static_cast<ResTable_config*>(this) = o;
- size = sizeof(ResTable_config);
- return *this;
- }
- ConfigDescription& operator=(const ConfigDescription& o) {
- *static_cast<ResTable_config*>(this) = o;
- return *this;
- }
-
- inline bool operator<(const ConfigDescription& o) const { return compare(o) < 0; }
- inline bool operator<=(const ConfigDescription& o) const { return compare(o) <= 0; }
- inline bool operator==(const ConfigDescription& o) const { return compare(o) == 0; }
- inline bool operator!=(const ConfigDescription& o) const { return compare(o) != 0; }
- inline bool operator>=(const ConfigDescription& o) const { return compare(o) >= 0; }
- inline bool operator>(const ConfigDescription& o) const { return compare(o) > 0; }
- };
class ConfigList : public RefBase {
public:
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 9a0a1c46251b..fe88e37c159f 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -5,8 +5,10 @@
//
#include "StringPool.h"
+#include "ResourceTable.h"
#include <utils/ByteOrder.h>
+#include <utils/SortedVector.h>
#if HAVE_PRINTF_ZD
# define ZD "%zd"
@@ -30,16 +32,70 @@ void strcpy16_htod(uint16_t* dst, const uint16_t* src)
void printStringPool(const ResStringPool* pool)
{
+ SortedVector<const void*> uniqueStrings;
+ const size_t N = pool->size();
+ for (size_t i=0; i<N; i++) {
+ size_t len;
+ if (pool->isUTF8()) {
+ uniqueStrings.add(pool->string8At(i, &len));
+ } else {
+ uniqueStrings.add(pool->stringAt(i, &len));
+ }
+ }
+
+ printf("String pool of " ZD " unique %s %s strings, " ZD " entries and "
+ ZD " styles using " ZD " bytes:\n",
+ (ZD_TYPE)uniqueStrings.size(), pool->isUTF8() ? "UTF-8" : "UTF-16",
+ pool->isSorted() ? "sorted" : "non-sorted",
+ (ZD_TYPE)N, (ZD_TYPE)pool->styleCount(), (ZD_TYPE)pool->bytes());
+
const size_t NS = pool->size();
for (size_t s=0; s<NS; s++) {
- size_t len;
- const char *str = (const char*)pool->string8At(s, &len);
- if (str == NULL) {
- str = String8(pool->stringAt(s, &len)).string();
+ String8 str = pool->string8ObjectAt(s);
+ printf("String #" ZD ": %s\n", (ZD_TYPE) s, str.string());
+ }
+}
+
+String8 StringPool::entry::makeConfigsString() const {
+ String8 configStr(configTypeName);
+ if (configStr.size() > 0) configStr.append(" ");
+ if (configs.size() > 0) {
+ for (size_t j=0; j<configs.size(); j++) {
+ if (j > 0) configStr.append(", ");
+ configStr.append(configs[j].toString());
}
+ } else {
+ configStr = "(none)";
+ }
+ return configStr;
+}
- printf("String #" ZD ": %s\n", (ZD_TYPE) s, str);
+int StringPool::entry::compare(const entry& o) const {
+ // Strings with styles go first, to reduce the size of the
+ // styles array.
+ if (hasStyles) {
+ return o.hasStyles ? 0 : -1;
+ }
+ if (o.hasStyles) {
+ return 1;
+ }
+ int comp = configTypeName.compare(o.configTypeName);
+ if (comp != 0) {
+ return comp;
}
+ const size_t LHN = configs.size();
+ const size_t RHN = o.configs.size();
+ size_t i=0;
+ while (i < LHN && i < RHN) {
+ comp = configs[i].compareLogical(o.configs[i]);
+ if (comp != 0) {
+ return comp;
+ }
+ i++;
+ }
+ if (LHN < RHN) return -1;
+ else if (LHN > RHN) return 1;
+ return 0;
}
StringPool::StringPool(bool sorted, bool utf8)
@@ -47,14 +103,16 @@ StringPool::StringPool(bool sorted, bool utf8)
{
}
-ssize_t StringPool::add(const String16& value, bool mergeDuplicates)
+ssize_t StringPool::add(const String16& value, bool mergeDuplicates,
+ const String8* configTypeName, const ResTable_config* config)
{
- return add(String16(), value, mergeDuplicates);
+ return add(String16(), value, mergeDuplicates, configTypeName, config);
}
-ssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans)
+ssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& spans,
+ const String8* configTypeName, const ResTable_config* config)
{
- ssize_t res = add(String16(), value, false);
+ ssize_t res = add(String16(), value, false, configTypeName, config);
if (res >= 0) {
addStyleSpans(res, spans);
}
@@ -62,7 +120,7 @@ ssize_t StringPool::add(const String16& value, const Vector<entry_style_span>& s
}
ssize_t StringPool::add(const String16& ident, const String16& value,
- bool mergeDuplicates)
+ bool mergeDuplicates, const String8* configTypeName, const ResTable_config* config)
{
if (ident.size() > 0) {
ssize_t idx = mIdents.valueFor(ident);
@@ -84,20 +142,43 @@ ssize_t StringPool::add(const String16& ident, const String16& value,
}
}
+ if (configTypeName != NULL) {
+ entry& ent = mEntries.editItemAt(eidx);
+ NOISY(printf("*** adding config type name %s, was %s\n",
+ configTypeName->string(), ent.configTypeName.string()));
+ if (ent.configTypeName.size() <= 0) {
+ ent.configTypeName = *configTypeName;
+ } else if (ent.configTypeName != *configTypeName) {
+ ent.configTypeName = " ";
+ }
+ }
+
+ if (config != NULL) {
+ // Add this to the set of configs associated with the string.
+ entry& ent = mEntries.editItemAt(eidx);
+ size_t addPos;
+ for (addPos=0; addPos<ent.configs.size(); addPos++) {
+ int cmp = ent.configs.itemAt(addPos).compareLogical(*config);
+ if (cmp >= 0) {
+ if (cmp > 0) {
+ NOISY(printf("*** inserting config: %s\n", config->toString().string()));
+ ent.configs.insertAt(*config, addPos);
+ }
+ break;
+ }
+ }
+ if (addPos >= ent.configs.size()) {
+ NOISY(printf("*** adding config: %s\n", config->toString().string()));
+ ent.configs.add(*config);
+ }
+ }
+
const bool first = vidx < 0;
if (first || !mergeDuplicates) {
pos = mEntryArray.add(eidx);
if (first) {
vidx = mValues.add(value, pos);
- const size_t N = mEntryArrayToValues.size();
- for (size_t i=0; i<N; i++) {
- size_t& e = mEntryArrayToValues.editItemAt(i);
- if ((ssize_t)e >= vidx) {
- e++;
- }
- }
}
- mEntryArrayToValues.add(vidx);
if (!mSorted) {
entry& ent = mEntries.editItemAt(eidx);
ent.indices.add(pos);
@@ -147,6 +228,7 @@ status_t StringPool::addStyleSpan(size_t idx, const entry_style_span& span)
entry_style& style = mEntryStyleArray.editItemAt(idx);
style.spans.add(span);
+ mEntries.editItemAt(mEntryArray[idx]).hasStyles = true;
return NO_ERROR;
}
@@ -169,6 +251,132 @@ size_t StringPool::countIdentifiers() const
return mIdents.size();
}
+int StringPool::config_sort(const size_t* lhs, const size_t* rhs, void* state)
+{
+ StringPool* pool = (StringPool*)state;
+ const entry& lhe = pool->mEntries[pool->mEntryArray[*lhs]];
+ const entry& rhe = pool->mEntries[pool->mEntryArray[*rhs]];
+ return lhe.compare(rhe);
+}
+
+void StringPool::sortByConfig()
+{
+ LOG_ALWAYS_FATAL_IF(mSorted, "Can't sort string pool containing identifiers.");
+ LOG_ALWAYS_FATAL_IF(mIdents.size() > 0, "Can't sort string pool containing identifiers.");
+ LOG_ALWAYS_FATAL_IF(mOriginalPosToNewPos.size() > 0, "Can't sort string pool after already sorted.");
+
+ const size_t N = mEntryArray.size();
+
+ // This is a vector that starts out with a 1:1 mapping to entries
+ // in the array, which we will sort to come up with the desired order.
+ // At that point it maps from the new position in the array to the
+ // original position the entry appeared.
+ Vector<size_t> newPosToOriginalPos;
+ for (size_t i=0; i<mEntryArray.size(); i++) {
+ newPosToOriginalPos.add(i);
+ }
+
+ // Sort the array.
+ NOISY(printf("SORTING STRINGS BY CONFIGURATION...\n"));
+ newPosToOriginalPos.sort(config_sort, this);
+ NOISY(printf("DONE SORTING STRINGS BY CONFIGURATION.\n"));
+
+ // Create the reverse mapping from the original position in the array
+ // to the new position where it appears in the sorted array. This is
+ // so that clients can re-map any positions they had previously stored.
+ mOriginalPosToNewPos = newPosToOriginalPos;
+ for (size_t i=0; i<N; i++) {
+ mOriginalPosToNewPos.editItemAt(newPosToOriginalPos[i]) = i;
+ }
+
+#if 0
+ SortedVector<entry> entries;
+
+ for (size_t i=0; i<N; i++) {
+ printf("#%d was %d: %s\n", i, newPosToOriginalPos[i],
+ mEntries[mEntryArray[newPosToOriginalPos[i]]].makeConfigsString().string());
+ entries.add(mEntries[mEntryArray[i]]);
+ }
+
+ for (size_t i=0; i<entries.size(); i++) {
+ printf("Sorted config #%d: %s\n", i,
+ entries[i].makeConfigsString().string());
+ }
+#endif
+
+ // Now we rebuild the arrays.
+ Vector<entry> newEntries;
+ Vector<size_t> newEntryArray;
+ Vector<entry_style> newEntryStyleArray;
+ DefaultKeyedVector<size_t, size_t> origOffsetToNewOffset;
+
+ for (size_t i=0; i<N; i++) {
+ // We are filling in new offset 'i'; oldI is where we can find it
+ // in the original data structure.
+ size_t oldI = newPosToOriginalPos[i];
+ // This is the actual entry associated with the old offset.
+ const entry& oldEnt = mEntries[mEntryArray[oldI]];
+ // This is the same entry the last time we added it to the
+ // new entry array, if any.
+ ssize_t newIndexOfOffset = origOffsetToNewOffset.indexOfKey(oldI);
+ size_t newOffset;
+ if (newIndexOfOffset < 0) {
+ // This is the first time we have seen the entry, so add
+ // it.
+ newOffset = newEntries.add(oldEnt);
+ newEntries.editItemAt(newOffset).indices.clear();
+ } else {
+ // We have seen this entry before, use the existing one
+ // instead of adding it again.
+ newOffset = origOffsetToNewOffset.valueAt(newIndexOfOffset);
+ }
+ // Update the indices to include this new position.
+ newEntries.editItemAt(newOffset).indices.add(i);
+ // And add the offset of the entry to the new entry array.
+ newEntryArray.add(newOffset);
+ // Add any old style to the new style array.
+ if (mEntryStyleArray.size() > 0) {
+ if (oldI < mEntryStyleArray.size()) {
+ newEntryStyleArray.add(mEntryStyleArray[oldI]);
+ } else {
+ newEntryStyleArray.add(entry_style());
+ }
+ }
+ }
+
+ // Now trim any entries at the end of the new style array that are
+ // not needed.
+ for (ssize_t i=newEntryStyleArray.size()-1; i>=0; i--) {
+ const entry_style& style = newEntryStyleArray[i];
+ if (style.spans.size() > 0) {
+ // That's it.
+ break;
+ }
+ // This one is not needed; remove.
+ newEntryStyleArray.removeAt(i);
+ }
+
+ // All done, install the new data structures and upate mValues with
+ // the new positions.
+ mEntries = newEntries;
+ mEntryArray = newEntryArray;
+ mEntryStyleArray = newEntryStyleArray;
+ mValues.clear();
+ for (size_t i=0; i<mEntries.size(); i++) {
+ const entry& ent = mEntries[i];
+ mValues.add(ent.value, ent.indices[0]);
+ }
+
+#if 0
+ printf("FINAL SORTED STRING CONFIGS:\n");
+ for (size_t i=0; i<mEntries.size(); i++) {
+ const entry& ent = mEntries[i];
+ printf("#" ZD " %s: %s\n", (ZD_TYPE)i, ent.makeConfigsString().string(),
+ String8(ent.value).string());
+ }
+#endif
+}
+
sp<AaptFile> StringPool::createStringBlock()
{
sp<AaptFile> pool = new AaptFile(String8(), AaptGroupEntry(),
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 727525976cd9..255bdbfc0a7f 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -40,12 +40,28 @@ class StringPool
public:
struct entry {
entry() : offset(0) { }
- entry(const String16& _value) : value(_value), offset(0) { }
- entry(const entry& o) : value(o.value), offset(o.offset), indices(o.indices) { }
+ entry(const String16& _value) : value(_value), offset(0), hasStyles(false) { }
+ entry(const entry& o) : value(o.value), offset(o.offset),
+ hasStyles(o.hasStyles), indices(o.indices),
+ configTypeName(o.configTypeName), configs(o.configs) { }
String16 value;
size_t offset;
+ bool hasStyles;
Vector<size_t> indices;
+ String8 configTypeName;
+ Vector<ResTable_config> configs;
+
+ String8 makeConfigsString() const;
+
+ int compare(const entry& o) const;
+
+ inline bool operator<(const entry& o) const { return compare(o) < 0; }
+ inline bool operator<=(const entry& o) const { return compare(o) <= 0; }
+ inline bool operator==(const entry& o) const { return compare(o) == 0; }
+ inline bool operator!=(const entry& o) const { return compare(o) != 0; }
+ inline bool operator>=(const entry& o) const { return compare(o) >= 0; }
+ inline bool operator>(const entry& o) const { return compare(o) > 0; }
};
struct entry_style_span {
@@ -84,12 +100,15 @@ public:
* if this string pool is sorted, the returned index will not be valid
* when the pool is finally written.
*/
- ssize_t add(const String16& value, bool mergeDuplicates = false);
+ ssize_t add(const String16& value, bool mergeDuplicates = false,
+ const String8* configTypeName = NULL, const ResTable_config* config = NULL);
- ssize_t add(const String16& value, const Vector<entry_style_span>& spans);
+ ssize_t add(const String16& value, const Vector<entry_style_span>& spans,
+ const String8* configTypeName = NULL, const ResTable_config* config = NULL);
ssize_t add(const String16& ident, const String16& value,
- bool mergeDuplicates = false);
+ bool mergeDuplicates = false,
+ const String8* configTypeName = NULL, const ResTable_config* config = NULL);
status_t addStyleSpan(size_t idx, const String16& name,
uint32_t start, uint32_t end);
@@ -102,6 +121,18 @@ public:
size_t countIdentifiers() const;
+ // Sort the contents of the string block by the configuration associated
+ // with each item. After doing this you can use mapOriginalPosToNewPos()
+ // to find out the new position given the position originall returned by
+ // add().
+ void sortByConfig();
+
+ // For use after sortByConfig() to map from the original position of
+ // a string to its new sorted position.
+ size_t mapOriginalPosToNewPos(size_t originalPos) const {
+ return mOriginalPosToNewPos.itemAt(originalPos);
+ }
+
sp<AaptFile> createStringBlock();
status_t writeStringBlock(const sp<AaptFile>& pool);
@@ -125,27 +156,41 @@ public:
const Vector<size_t>* offsetsForString(const String16& val) const;
private:
+ static int config_sort(const size_t* lhs, const size_t* rhs, void* state);
+
const bool mSorted;
const bool mUTF8;
- // Raw array of unique strings, in some arbitrary order.
+
+ // The following data structures represent the actual structures
+ // that will be generated for the final string pool.
+
+ // Raw array of unique strings, in some arbitrary order. This is the
+ // actual strings that appear in the final string pool, in the order
+ // that they will be written.
Vector<entry> mEntries;
// Array of indices into mEntries, in the order they were
// added to the pool. This can be different than mEntries
// if the same string was added multiple times (it will appear
// once in mEntries, with multiple occurrences in this array).
+ // This is the lookup array that will be written for finding
+ // the string for each offset/position in the string pool.
Vector<size_t> mEntryArray;
// Optional style span information associated with each index of
// mEntryArray.
Vector<entry_style> mEntryStyleArray;
- // Mapping from indices in mEntryArray to indices in mValues.
- Vector<size_t> mEntryArrayToValues;
+
+ // The following data structures are used for book-keeping as the
+ // string pool is constructed.
+
// Unique set of all the strings added to the pool, mapped to
// the first index of mEntryArray where the value was added.
DefaultKeyedVector<String16, ssize_t> mValues;
// Unique set of all (optional) identifiers of strings in the
// pool, mapping to indices in mEntries.
DefaultKeyedVector<String16, ssize_t> mIdents;
-
+ // This array maps from the original position a string was placed at
+ // in mEntryArray to its new position after being sorted with sortByConfig().
+ Vector<size_t> mOriginalPosToNewPos;
};
#endif
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index c91a3bf91c51..c64ab657ac05 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -19,6 +19,7 @@ package com.android.layoutlib.bridge.android;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
+import android.content.ICancelationSignal;
import android.content.IContentProvider;
import android.content.OperationApplicationException;
import android.content.res.AssetFileDescriptor;
@@ -90,8 +91,8 @@ public final class BridgeContentProvider implements IContentProvider {
}
@Override
- public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4)
- throws RemoteException {
+ public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4,
+ ICancelationSignal arg5) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
@@ -122,4 +123,9 @@ public final class BridgeContentProvider implements IContentProvider {
return null;
}
+ @Override
+ public ICancelationSignal createCancelationSignal() throws RemoteException {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 8c9e472f74b5..b8b7c0eaaae1 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1625,6 +1625,10 @@ public class WifiStateMachine extends StateMachine {
private void handleNetworkDisconnect() {
if (DBG) log("Stopping DHCP and clearing IP");
+ /* In case we were in middle of DHCP operation
+ restore back powermode */
+ handlePostDhcpSetup();
+
/*
* stop DHCP
*/