summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-06-16 12:38:55 -0700
committerMathias Agopian <mathias@google.com>2009-06-16 12:38:55 -0700
commit69f066c8fc42b9f0acc5c41f8ffd972f8d6d0584 (patch)
tree3a8bc941200fa85a32a21657ac69ec9beb9a6463
parent151e859e0fc3a930bdf6d270d275e69e9eba0cbf (diff)
parentb0b160ae50497966666bcdcaf974eca2643acfd3 (diff)
downloadframeworks_base-69f066c8fc42b9f0acc5c41f8ffd972f8d6d0584.zip
frameworks_base-69f066c8fc42b9f0acc5c41f8ffd972f8d6d0584.tar.gz
frameworks_base-69f066c8fc42b9f0acc5c41f8ffd972f8d6d0584.tar.bz2
Merge commit 'goog/master' into merge_master
-rw-r--r--Android.mk15
-rw-r--r--api/4.xml33
-rw-r--r--api/current.xml2343
-rw-r--r--camera/libcameraservice/CameraService.cpp14
-rw-r--r--cmds/bmgr/Android.mk15
-rw-r--r--cmds/bmgr/MODULE_LICENSE_APACHE20
-rw-r--r--cmds/bmgr/NOTICE190
-rwxr-xr-xcmds/bmgr/bmgr7
-rw-r--r--cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java167
-rw-r--r--cmds/keystore/Android.mk21
-rw-r--r--cmds/keystore/commands.c141
-rw-r--r--cmds/keystore/keystore.c255
-rw-r--r--cmds/keystore/keystore.h57
-rw-r--r--core/java/android/accounts/AccountAuthenticatorCache.java34
-rw-r--r--core/java/android/accounts/AccountManager.java10
-rw-r--r--core/java/android/accounts/AccountManagerService.java11
-rw-r--r--core/java/android/accounts/AuthenticatorBindHelper.java5
-rw-r--r--core/java/android/accounts/AuthenticatorDescription.aidl19
-rw-r--r--core/java/android/accounts/AuthenticatorDescription.java69
-rw-r--r--core/java/android/accounts/IAccountManager.aidl3
-rw-r--r--core/java/android/app/Activity.java52
-rw-r--r--core/java/android/app/ApplicationContext.java6
-rw-r--r--core/java/android/app/FullBackupAgent.java5
-rw-r--r--core/java/android/app/ISearchManager.aidl14
-rw-r--r--core/java/android/app/ISearchManagerCallback.aidl (renamed from core/java/android/bluetooth/IBluetoothDeviceCallback.aidl)16
-rw-r--r--core/java/android/app/SearchDialog.java164
-rw-r--r--core/java/android/app/SearchManager.java253
-rw-r--r--core/java/android/app/SuggestionsAdapter.java182
-rw-r--r--core/java/android/backup/BackupDataInput.java103
-rw-r--r--core/java/android/backup/BackupDataOutput.java22
-rw-r--r--core/java/android/backup/BackupManager.java25
-rw-r--r--core/java/android/backup/FileBackupHelper.java75
-rw-r--r--core/java/android/backup/IBackupManager.aidl26
-rw-r--r--core/java/android/backup/IRestoreSession.aidl52
-rw-r--r--core/java/android/backup/RestoreHelper.java23
-rw-r--r--core/java/android/backup/RestoreHelperDistributor.java28
-rw-r--r--core/java/android/backup/RestoreSet.aidl19
-rw-r--r--core/java/android/backup/RestoreSet.java87
-rw-r--r--core/java/android/backup/SharedPreferencesBackupHelper.java27
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java192
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java62
-rw-r--r--core/java/android/bluetooth/IBluetoothDevice.aidl26
-rw-r--r--core/java/android/content/AbstractTableMerger.java52
-rw-r--r--core/java/android/content/ContentProviderOperation.java6
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/ContextWrapper.java5
-rw-r--r--core/java/android/content/SyncAdaptersCache.java24
-rw-r--r--core/java/android/content/SyncManager.java2
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java17
-rwxr-xr-xcore/java/android/content/pm/ConfigurationInfo.java30
-rw-r--r--core/java/android/content/pm/PackageParser.java12
-rw-r--r--core/java/android/content/pm/RegisteredServicesCache.java6
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java22
-rw-r--r--core/java/android/content/res/Resources.java6
-rwxr-xr-xcore/java/android/gesture/Gesture.java29
-rw-r--r--core/java/android/gesture/GestureLibraries.java10
-rwxr-xr-xcore/java/android/gesture/GestureOverlayView.java63
-rw-r--r--core/java/android/gesture/GestureStore.java12
-rw-r--r--core/java/android/gesture/InstanceLearner.java38
-rw-r--r--core/java/android/gesture/LetterRecognizer.java279
-rw-r--r--core/java/android/gesture/LetterRecognizers.java65
-rw-r--r--core/java/android/gesture/package.html5
-rw-r--r--core/java/android/net/http/Request.java9
-rw-r--r--core/java/android/provider/Browser.java38
-rw-r--r--core/java/android/provider/Calendar.java3
-rw-r--r--core/java/android/provider/ContactsContract.java280
-rw-r--r--core/java/android/provider/Im.java33
-rw-r--r--core/java/android/provider/Settings.java49
-rw-r--r--core/java/android/provider/SocialContract.java12
-rw-r--r--core/java/android/provider/Telephony.java8
-rw-r--r--core/java/android/server/BluetoothA2dpService.java403
-rw-r--r--core/java/android/server/BluetoothDeviceService.java702
-rw-r--r--core/java/android/server/BluetoothEventLoop.java266
-rw-r--r--core/java/android/server/search/SearchManagerService.java211
-rw-r--r--core/java/android/server/search/SearchableInfo.java36
-rw-r--r--core/java/android/speech/IRecognitionListener.aidl6
-rw-r--r--core/java/android/speech/RecognitionResult.java11
-rwxr-xr-xcore/java/android/speech/tts/ITts.aidl (renamed from tts/java/android/tts/ITts.aidl)116
-rwxr-xr-xcore/java/android/speech/tts/ITtsCallback.aidl (renamed from tts/java/android/tts/ITtsCallback.aidl)2
-rwxr-xr-xcore/java/android/speech/tts/TextToSpeech.java (renamed from tts/java/android/tts/Tts.java)353
-rw-r--r--core/java/android/test/AndroidTestCase.java72
-rw-r--r--core/java/android/text/LoginFilter.java41
-rw-r--r--core/java/android/text/TextUtils.java11
-rw-r--r--core/java/android/text/format/DateFormat.java66
-rw-r--r--core/java/android/text/format/DateUtils.java24
-rw-r--r--core/java/android/text/format/Formatter.java10
-rw-r--r--core/java/android/util/DisplayMetrics.java33
-rw-r--r--core/java/android/util/EventLog.java8
-rw-r--r--core/java/android/view/MotionEvent.java141
-rw-r--r--core/java/android/view/View.java103
-rw-r--r--core/java/android/view/ViewGroup.java67
-rw-r--r--core/java/android/view/ViewRoot.java173
-rw-r--r--core/java/android/view/WindowManager.java63
-rw-r--r--core/java/android/webkit/JWebCoreJavaBridge.java15
-rw-r--r--core/java/android/webkit/WebSettings.java23
-rw-r--r--core/java/android/webkit/WebView.java379
-rw-r--r--core/java/android/webkit/WebViewCore.java172
-rw-r--r--core/java/android/widget/AbsListView.java327
-rw-r--r--core/java/android/widget/AlphabetIndexer.java43
-rw-r--r--core/java/android/widget/AutoCompleteTextView.java11
-rw-r--r--core/java/android/widget/MultiAutoCompleteTextView.java2
-rw-r--r--core/java/android/widget/SimpleCursorTreeAdapter.java114
-rw-r--r--core/java/android/widget/TabHost.java38
-rw-r--r--core/java/android/widget/TabWidget.java110
-rw-r--r--core/java/android/widget/ViewSwitcher.java2
-rw-r--r--core/java/com/android/internal/backup/AdbTransport.java28
-rw-r--r--core/java/com/android/internal/backup/GoogleTransport.java30
-rw-r--r--core/java/com/android/internal/backup/IBackupTransport.aidl57
-rw-r--r--core/java/com/android/internal/backup/LocalTransport.java182
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java135
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java95
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java2
-rw-r--r--core/java/com/google/android/util/GoogleWebContentHelper.java4
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android_backup_BackupDataInput.cpp173
-rw-r--r--core/jni/android_backup_BackupDataOutput.cpp51
-rw-r--r--core/jni/android_backup_FileBackupHelper.cpp28
-rw-r--r--core/jni/android_bluetooth_common.cpp363
-rw-r--r--core/jni/android_bluetooth_common.h17
-rw-r--r--core/jni/android_hardware_Camera.cpp14
-rw-r--r--core/jni/android_location_GpsLocationProvider.cpp7
-rw-r--r--core/jni/android_net_wifi_Wifi.cpp17
-rw-r--r--core/jni/android_server_BluetoothA2dpService.cpp322
-rw-r--r--core/jni/android_server_BluetoothDeviceService.cpp954
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp637
-rw-r--r--core/jni/android_util_Process.cpp54
-rw-r--r--core/jni/com_google_android_gles_jni_GLImpl.cpp45
-rw-r--r--core/res/AndroidManifest.xml20
-rw-r--r--core/res/res/anim/slide_in_up.xml (renamed from tests/sketch/res/layout/overlaydemo.xml)14
-rw-r--r--[-rwxr-xr-x]core/res/res/anim/slide_out_down.xml (renamed from tests/sketch/res/values/strings.xml)26
-rw-r--r--core/res/res/raw/latin_lowercasebin28496 -> 0 bytes
-rw-r--r--core/res/res/values-ar-rEG/donottranslate-cldr.xml40
-rw-r--r--core/res/res/values-bg-rBG/donottranslate-cldr.xml44
-rw-r--r--core/res/res/values-ca-rES/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-cs-rCZ/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-cs/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-cs/strings.xml40
-rw-r--r--core/res/res/values-da-rDK/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-de-rAT/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-de-rCH/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-de-rDE/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-de-rLI/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-de/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-de/strings.xml40
-rw-r--r--core/res/res/values-el-rGR/donottranslate-cldr.xml40
-rw-r--r--core/res/res/values-en-rAU/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rAU/strings.xml36
-rw-r--r--core/res/res/values-en-rCA/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rGB/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rIE/donottranslate-cldr.xml44
-rw-r--r--core/res/res/values-en-rIN/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rNZ/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rSG/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rSG/strings.xml36
-rw-r--r--core/res/res/values-en-rUS/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-en-rUS/strings.xml4
-rw-r--r--core/res/res/values-en-rZA/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values-es-rES/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-es-rUS/donottranslate-cldr.xml38
-rw-r--r--core/res/res/values-es-rUS/strings.xml40
-rw-r--r--core/res/res/values-es/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-es/strings.xml40
-rw-r--r--core/res/res/values-fi-rFI/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-fr-rBE/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-fr-rCA/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-fr-rCH/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-fr-rFR/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-fr/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-fr/strings.xml41
-rw-r--r--core/res/res/values-he-rIL/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-hi-rIN/donottranslate-cldr.xml38
-rw-r--r--core/res/res/values-hu-rHU/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-id-rID/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-it-rCH/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-it-rIT/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-it/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-it/strings.xml40
-rw-r--r--core/res/res/values-ja-rJP/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ja/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ja/strings.xml40
-rw-r--r--core/res/res/values-ko-rKR/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ko/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ko/strings.xml40
-rw-r--r--core/res/res/values-lt-rLT/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-lv-rLV/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-mcc204-pt/strings.xml19
-rw-r--r--core/res/res/values-mcc230-pt/strings.xml19
-rw-r--r--core/res/res/values-mcc232-pt/strings.xml19
-rw-r--r--core/res/res/values-mcc234-pt/strings.xml19
-rw-r--r--core/res/res/values-mcc260-pt/strings.xml19
-rw-r--r--core/res/res/values-mcc262-pt/strings.xml19
-rw-r--r--core/res/res/values-nb/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-nb/strings.xml40
-rw-r--r--core/res/res/values-nl-rBE/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-nl-rNL/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-nl/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-nl/strings.xml40
-rw-r--r--core/res/res/values-pl-rPL/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-pl/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-pl/strings.xml40
-rw-r--r--core/res/res/values-pt-rBR/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-pt-rPT/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-pt/donottranslate-cldr.xml146
-rw-r--r--core/res/res/values-pt/strings.xml793
-rw-r--r--core/res/res/values-ro-rRO/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ru-rRU/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ru/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-ru/strings.xml40
-rw-r--r--core/res/res/values-sk-rSK/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-sl-rSI/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-sr-rRS/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-sv-rSE/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-th-rTH/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-tr-rTR/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-uk-rUA/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-vi-rVN/donottranslate-cldr.xml42
-rw-r--r--core/res/res/values-zh-rCN/donottranslate-cldr.xml40
-rw-r--r--core/res/res/values-zh-rCN/strings.xml40
-rw-r--r--core/res/res/values-zh-rTW/donottranslate-cldr.xml40
-rw-r--r--core/res/res/values-zh-rTW/strings.xml40
-rw-r--r--core/res/res/values/arrays.xml2
-rw-r--r--core/res/res/values/attrs.xml45
-rw-r--r--core/res/res/values/attrs_manifest.xml19
-rw-r--r--core/res/res/values/colors.xml1
-rw-r--r--core/res/res/values/donottranslate-cldr.xml48
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--core/res/res/values/strings.xml155
-rw-r--r--core/res/res/values/styles.xml6
-rw-r--r--core/res/res/values/themes.xml3
-rw-r--r--core/res/res/xml/power_profile.xml (renamed from core/res/res/xml/power_profile_default.xml)33
-rw-r--r--docs/html/index.jd54
-rw-r--r--docs/html/search.jd2
-rw-r--r--include/media/IMediaPlayerService.h3
-rw-r--r--include/media/MediaPlayerInterface.h1
-rw-r--r--include/media/mediaplayer.h2
-rw-r--r--include/media/mediarecorder.h38
-rw-r--r--include/tts/TtsEngine.h134
-rw-r--r--include/utils/BackupHelpers.h4
-rw-r--r--keystore/java/android/security/Keystore.java153
-rw-r--r--keystore/java/android/security/ServiceCommand.java178
-rw-r--r--libs/audioflinger/Android.mk3
-rw-r--r--libs/rs/Android.mk74
-rw-r--r--libs/rs/java/Fountain/Android.mk8
-rw-r--r--libs/rs/java/Fountain/res/raw/fountain.c12
-rw-r--r--libs/rs/java/Fountain/src/com/android/fountain/Fountain.java3
-rw-r--r--libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java137
-rw-r--r--libs/rs/java/Fountain/src/com/android/fountain/FountainView.java114
-rw-r--r--libs/rs/java/RenderScript/Android.mk28
-rw-r--r--libs/rs/java/RenderScript/android/renderscript/Matrix.java188
-rw-r--r--libs/rs/java/RenderScript/android/renderscript/ProgramVertexAlloc.java112
-rw-r--r--libs/rs/java/RenderScript/android/renderscript/RSSurfaceView.java (renamed from libs/rs/java/Fountain/src/com/android/fountain/RSSurfaceView.java)2
-rw-r--r--libs/rs/java/RenderScript/android/renderscript/RenderScript.java (renamed from libs/rs/java/Fountain/src/com/android/fountain/RenderScript.java)129
-rw-r--r--libs/rs/java/Rollo/Android.mk25
-rw-r--r--libs/rs/java/Rollo/AndroidManifest.xml13
-rw-r--r--libs/rs/java/Rollo/res/raw/rollo.c13
-rw-r--r--libs/rs/java/Rollo/src/com/android/rollo/Rollo.java90
-rw-r--r--libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java65
-rw-r--r--libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java150
-rw-r--r--libs/rs/java/Rollo/src/com/android/rollo/RolloView.java82
-rw-r--r--libs/rs/jni/Android.mk36
-rw-r--r--libs/rs/jni/RenderScript_jni.cpp163
-rw-r--r--libs/rs/rs.spec21
-rw-r--r--libs/rs/rsContext.cpp104
-rw-r--r--libs/rs/rsContext.h13
-rw-r--r--libs/rs/rsObjectBase.cpp22
-rw-r--r--libs/rs/rsObjectBase.h32
-rw-r--r--libs/rs/rsProgramFragment.cpp8
-rw-r--r--libs/rs/rsProgramFragment.h2
-rw-r--r--libs/rs/rsProgramFragmentStore.cpp13
-rw-r--r--libs/rs/rsProgramFragmentStore.h2
-rw-r--r--libs/rs/rsProgramVertex.cpp9
-rw-r--r--libs/rs/rsProgramVertex.h1
-rw-r--r--libs/rs/rsScript.cpp11
-rw-r--r--libs/rs/rsScript.h23
-rw-r--r--libs/rs/rsScriptC.cpp154
-rw-r--r--libs/rs/rsScriptC.h25
-rw-r--r--libs/rs/rsTriangleMesh.h2
-rw-r--r--libs/utils/BackupData.cpp2
-rw-r--r--libs/utils/BackupHelpers.cpp319
-rw-r--r--location/java/com/android/internal/location/GpsLocationProvider.java7
-rw-r--r--media/java/android/media/AudioService.java61
-rw-r--r--media/java/android/media/MediaPlayer.java357
-rw-r--r--media/java/android/media/MediaRecorder.java76
-rw-r--r--media/jni/android_media_MediaPlayer.cpp10
-rw-r--r--media/jni/android_media_MediaRecorder.cpp33
-rw-r--r--media/libmedia/IMediaPlayerService.cpp1
-rw-r--r--media/libmedia/mediaplayer.cpp4
-rw-r--r--media/libmedia/mediarecorder.cpp8
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java8
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java7
-rw-r--r--opengl/java/com/google/android/gles_jni/GLImpl.java33
-rwxr-xr-xopengl/tools/glgen/gen17
-rw-r--r--opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp45
-rw-r--r--opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl33
-rw-r--r--packages/SettingsProvider/AndroidManifest.xml6
-rw-r--r--packages/SettingsProvider/res/values/strings.xml23
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java4
-rw-r--r--packages/TtsService/Android.mk13
-rwxr-xr-xpackages/TtsService/AndroidManifest.xml15
-rw-r--r--packages/TtsService/MODULE_LICENSE_APACHE20
-rw-r--r--packages/TtsService/NOTICE190
-rwxr-xr-xpackages/TtsService/jni/Android.mk (renamed from tts/jni/Android.mk)0
-rw-r--r--[-rwxr-xr-x]packages/TtsService/jni/android_tts_SynthProxy.cpp (renamed from tts/jni/android_tts_SynthProxy.cpp)39
-rwxr-xr-xpackages/TtsService/src/android/tts/SynthProxy.java (renamed from tts/java/android/tts/SynthProxy.java)0
-rwxr-xr-xpackages/TtsService/src/android/tts/TtsService.java (renamed from tts/java/android/tts/TtsService.java)85
-rw-r--r--packages/VpnServices/Android.mk16
-rw-r--r--packages/VpnServices/AndroidManifest.xml22
-rw-r--r--packages/VpnServices/MODULE_LICENSE_APACHE20
-rw-r--r--packages/VpnServices/NOTICE190
-rw-r--r--packages/VpnServices/res/drawable/vpn_connected.pngbin0 -> 757 bytes
-rw-r--r--packages/VpnServices/res/drawable/vpn_disconnected.pngbin0 -> 717 bytes
-rwxr-xr-xpackages/VpnServices/res/values/strings.xml8
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java258
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java65
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/L2tpService.java42
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/NormalProcessProxy.java85
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/ProcessProxy.java210
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/VpnService.java627
-rw-r--r--packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java104
-rw-r--r--services/java/com/android/server/BackupManagerService.java712
-rw-r--r--services/java/com/android/server/LocationManagerService.java5
-rw-r--r--services/java/com/android/server/PackageManagerService.java50
-rw-r--r--services/java/com/android/server/SystemServer.java12
-rw-r--r--services/java/com/android/server/WifiService.java77
-rw-r--r--services/java/com/android/server/WindowManagerService.java1178
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java94
-rw-r--r--telephony/java/android/telephony/JapanesePhoneNumberFormatter.java14
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.aidl16
-rw-r--r--telephony/java/android/telephony/NeighboringCellInfo.java14
-rw-r--r--telephony/java/android/telephony/SmsMessage.java34
-rw-r--r--telephony/java/android/telephony/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/BaseCommands.java63
-rw-r--r--telephony/java/com/android/internal/telephony/Call.java52
-rw-r--r--telephony/java/com/android/internal/telephony/CallTracker.java29
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfo.java52
-rw-r--r--telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java134
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java96
-rw-r--r--telephony/java/com/android/internal/telephony/Connection.java8
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java94
-rw-r--r--telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl4
-rw-r--r--telephony/java/com/android/internal/telephony/IccVmFixedException.java2
-rw-r--r--telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java2
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java111
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java46
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java44
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java326
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java10
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java58
-rw-r--r--telephony/java/com/android/internal/telephony/SmsResponse.java8
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyIntents.java10
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java5
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushOverSms.java2
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CDMAPhone.java53
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCall.java4
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java171
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java285
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java43
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java232
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java44
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/EriManager.java24
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/FeatureCode.java14
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimRecords.java102
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java11
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/SmsMessage.java11
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java50
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/UserData.java8
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmConnection.java28
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java71
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java14
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/PdpConnection.java75
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/RestrictedState.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMRecords.java10
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java133
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java16
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/package.html2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java40
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java6
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/Input.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/Menu.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java8
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/StkService.java25
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java26
-rw-r--r--telephony/java/com/android/internal/telephony/test/ModelInterpreter.java70
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java33
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java66
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java2
-rw-r--r--test-runner/android/test/mock/MockContext.java5
-rw-r--r--tests/AndroidTests/AndroidManifest.xml15
-rw-r--r--tests/AndroidTests/res/values/strings.xml3
-rw-r--r--tests/AndroidTests/res/xml/searchable.xml11
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java182
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/SearchableActivity.java (renamed from tests/sketch/src/com/android/gesture/example/ContactItem.java)22
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java12
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java110
-rw-r--r--tests/DumpRenderTree/assets/results/layout_tests_failed.txt978
-rw-r--r--tests/DumpRenderTree/assets/results/layout_tests_nontext.txt2427
-rw-r--r--tests/DumpRenderTree/assets/results/layout_tests_passed.txt1244
-rwxr-xr-xtests/DumpRenderTree/assets/run_layout_tests.py41
-rwxr-xr-xtests/DumpRenderTree/assets/run_reliability_tests.py62
-rwxr-xr-xtests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java5
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java55
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java102
-rw-r--r--tests/backup/backup_helper_test.cpp2
-rw-r--r--tests/backup/src/com/android/backuptest/BackupTestAgent.java3
-rw-r--r--tests/permission/Android.mk14
-rw-r--r--tests/permission/AndroidManifest.xml33
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java182
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java141
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java50
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/SettingsPermissionsTests.java54
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java409
-rw-r--r--tests/sketch/Android.mk8
-rwxr-xr-xtests/sketch/AndroidManifest.xml45
-rwxr-xr-xtests/sketch/res/drawable/icon.pngbin3180 -> 0 bytes
-rwxr-xr-xtests/sketch/res/layout/demo.xml35
-rwxr-xr-xtests/sketch/res/layout/gestureviewer.xml59
-rwxr-xr-xtests/sketch/res/layout/newgesture_dialog.xml34
-rw-r--r--tests/sketch/src/com/android/gesture/example/ContactAdapter.java100
-rw-r--r--tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java108
-rw-r--r--tests/sketch/src/com/android/gesture/example/GestureEntry.java211
-rwxr-xr-xtests/sketch/src/com/android/gesture/example/GestureLibViewer.java184
-rw-r--r--tests/sketch/tools/Converter.java225
-rw-r--r--tools/aapt/Resource.cpp31
-rw-r--r--tools/aapt/ResourceTable.cpp43
-rw-r--r--tools/aapt/ResourceTable.h5
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Matrix.java132
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java6
-rw-r--r--vpn/java/android/net/vpn/IVpnService.aidl43
-rw-r--r--vpn/java/android/net/vpn/L2tpIpsecProfile.java76
-rw-r--r--vpn/java/android/net/vpn/L2tpProfile.java30
-rw-r--r--vpn/java/android/net/vpn/VpnManager.java162
-rw-r--r--vpn/java/android/net/vpn/VpnProfile.aidl19
-rw-r--r--vpn/java/android/net/vpn/VpnProfile.java177
-rw-r--r--vpn/java/android/net/vpn/VpnState.java33
-rw-r--r--vpn/java/android/net/vpn/VpnType.java42
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java108
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java2
-rw-r--r--wifi/java/android/net/wifi/WifiStateTracker.java12
451 files changed, 25336 insertions, 11498 deletions
diff --git a/Android.mk b/Android.mk
index 1f4a375..e10ec80 100644
--- a/Android.mk
+++ b/Android.mk
@@ -79,6 +79,7 @@ LOCAL_SRC_FILES += \
core/java/android/app/IIntentSender.aidl \
core/java/android/app/INotificationManager.aidl \
core/java/android/app/ISearchManager.aidl \
+ core/java/android/app/ISearchManagerCallback.aidl \
core/java/android/app/IServiceConnection.aidl \
core/java/android/app/IStatusBar.aidl \
core/java/android/app/IThumbnailReceiver.aidl \
@@ -86,9 +87,9 @@ LOCAL_SRC_FILES += \
core/java/android/app/IWallpaperService.aidl \
core/java/android/app/IWallpaperServiceCallback.aidl \
core/java/android/backup/IBackupManager.aidl \
+ core/java/android/backup/IRestoreSession.aidl \
core/java/android/bluetooth/IBluetoothA2dp.aidl \
core/java/android/bluetooth/IBluetoothDevice.aidl \
- core/java/android/bluetooth/IBluetoothDeviceCallback.aidl \
core/java/android/bluetooth/IBluetoothHeadset.aidl \
core/java/android/content/IContentService.aidl \
core/java/android/content/ISyncAdapter.aidl \
@@ -121,6 +122,8 @@ LOCAL_SRC_FILES += \
core/java/android/view/IWindowSession.aidl \
core/java/android/speech/IRecognitionListener.aidl \
core/java/android/speech/IRecognitionService.aidl \
+ core/java/android/speech/tts/ITts.aidl \
+ core/java/android/speech/tts/ITtsCallback.aidl \
core/java/com/android/internal/app/IBatteryStats.aidl \
core/java/com/android/internal/app/IUsageStats.aidl \
core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
@@ -150,10 +153,9 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \
- tts/java/android/tts/ITtsCallback.aidl \
- tts/java/android/tts/ITts.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
- telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
+ telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
+ vpn/java/android/net/vpn/IVpnService.aidl \
# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS)
@@ -226,7 +228,8 @@ aidl_files := \
frameworks/base/location/java/android/location/Location.aidl \
frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
frameworks/base/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
- frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl
+ frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl \
+ frameworks/base/vpn/java/android/net/vpn/IVpnService.aidl \
gen := $(TARGET_OUT_COMMON_INTERMEDIATES)/framework.aidl
$(gen): PRIVATE_SRC_FILES := $(aidl_files)
@@ -478,5 +481,3 @@ include $(BUILD_JAVA_LIBRARY)
ifeq (,$(ONE_SHOT_MAKEFILE))
include $(call first-makefiles-under,$(LOCAL_PATH))
endif
-
-
diff --git a/api/4.xml b/api/4.xml
index 893301e..b117a87 100644
--- a/api/4.xml
+++ b/api/4.xml
@@ -122,17 +122,6 @@
visibility="public"
>
</field>
-<field name="ADD_SYSTEM_SERVICE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.ADD_SYSTEM_SERVICE&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="BATTERY_STATS"
type="java.lang.String"
transient="false"
@@ -463,17 +452,6 @@
visibility="public"
>
</field>
-<field name="FOTA_UPDATE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.FOTA_UPDATE&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="GET_ACCOUNTS"
type="java.lang.String"
transient="false"
@@ -925,17 +903,6 @@
visibility="public"
>
</field>
-<field name="SET_PROCESS_FOREGROUND"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.SET_PROCESS_FOREGROUND&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="SET_PROCESS_LIMIT"
type="java.lang.String"
transient="false"
diff --git a/api/current.xml b/api/current.xml
index 402c43d..c436b2d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -122,17 +122,6 @@
visibility="public"
>
</field>
-<field name="ADD_SYSTEM_SERVICE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.ADD_SYSTEM_SERVICE&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="BATTERY_STATS"
type="java.lang.String"
transient="false"
@@ -474,17 +463,6 @@
visibility="public"
>
</field>
-<field name="FOTA_UPDATE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.FOTA_UPDATE&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="GET_ACCOUNTS"
type="java.lang.String"
transient="false"
@@ -947,17 +925,6 @@
visibility="public"
>
</field>
-<field name="SET_PROCESS_FOREGROUND"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.SET_PROCESS_FOREGROUND&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="SET_PROCESS_LIMIT"
type="java.lang.String"
transient="false"
@@ -2147,7 +2114,7 @@
type="int"
transient="false"
volatile="false"
- value="16843393"
+ value="16843392"
static="true"
final="true"
deprecated="not deprecated"
@@ -2389,7 +2356,7 @@
type="int"
transient="false"
volatile="false"
- value="16843392"
+ value="16843391"
static="true"
final="true"
deprecated="not deprecated"
@@ -3595,17 +3562,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad30"
- type="int"
- transient="false"
- volatile="false"
- value="16843394"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad4"
type="int"
transient="false"
@@ -3973,7 +3929,7 @@
type="int"
transient="false"
volatile="false"
- value="16843390"
+ value="16843389"
static="true"
final="true"
deprecated="not deprecated"
@@ -4116,7 +4072,7 @@
type="int"
transient="false"
volatile="false"
- value="16843391"
+ value="16843390"
static="true"
final="true"
deprecated="not deprecated"
@@ -4468,7 +4424,7 @@
type="int"
transient="false"
volatile="false"
- value="16843389"
+ value="16843388"
static="true"
final="true"
deprecated="not deprecated"
@@ -4479,7 +4435,7 @@
type="int"
transient="false"
volatile="false"
- value="16843387"
+ value="16843386"
static="true"
final="true"
deprecated="not deprecated"
@@ -4490,7 +4446,7 @@
type="int"
transient="false"
volatile="false"
- value="16843388"
+ value="16843387"
static="true"
final="true"
deprecated="not deprecated"
@@ -4501,7 +4457,7 @@
type="int"
transient="false"
volatile="false"
- value="16843386"
+ value="16843385"
static="true"
final="true"
deprecated="not deprecated"
@@ -4519,11 +4475,11 @@
visibility="public"
>
</field>
-<field name="gestures"
+<field name="glEsVersion"
type="int"
transient="false"
volatile="false"
- value="16843385"
+ value="16843393"
static="true"
final="true"
deprecated="not deprecated"
@@ -6917,6 +6873,17 @@
visibility="public"
>
</field>
+<field name="queryAfterZeroResults"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843394"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="radioButtonStyle"
type="int"
transient="false"
@@ -16468,7 +16435,7 @@
</exception>
</method>
<method name="blockingGetAuthenticatorTypes"
- return="java.lang.String[]"
+ return="android.accounts.AuthenticatorDescription[]"
abstract="false"
native="false"
synchronized="false"
@@ -16808,7 +16775,7 @@
</parameter>
</method>
<method name="getAuthenticatorTypes"
- return="android.accounts.Future1&lt;java.lang.String[]&gt;"
+ return="android.accounts.Future1&lt;android.accounts.AuthenticatorDescription[]&gt;"
abstract="false"
native="false"
synchronized="false"
@@ -16817,7 +16784,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.String[]&gt;">
+<parameter name="callback" type="android.accounts.Future1Callback&lt;android.accounts.AuthenticatorDescription[]&gt;">
</parameter>
<parameter name="handler" type="android.os.Handler">
</parameter>
@@ -17011,6 +16978,122 @@
</parameter>
</method>
</class>
+<class name="AuthenticatorDescription"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<constructor name="AuthenticatorDescription"
+ type="android.accounts.AuthenticatorDescription"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="java.lang.String">
+</parameter>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+<parameter name="labelId" type="int">
+</parameter>
+<parameter name="iconId" type="int">
+</parameter>
+</constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="newKey"
+ return="android.accounts.AuthenticatorDescription"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="java.lang.String">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="iconId"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="labelId"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="packageName"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="type"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="AuthenticatorException"
extends="java.lang.Exception"
abstract="false"
@@ -31992,6 +32075,19 @@
<parameter name="mode" type="int">
</parameter>
</method>
+<method name="getSharedPrefsFile"
+ return="java.io.File"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
<method name="getSystemService"
return="java.lang.Object"
abstract="false"
@@ -38488,6 +38584,17 @@
visibility="public"
>
</method>
+<method name="getGlEsVersion"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="writeToParcel"
return="void"
abstract="false"
@@ -38513,6 +38620,17 @@
visibility="public"
>
</field>
+<field name="GL_ES_VERSION_UNDEFINED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="INPUT_FEATURE_FIVE_WAY_NAV"
type="int"
transient="false"
@@ -38535,6 +38653,16 @@
visibility="public"
>
</field>
+<field name="reqGlEsVersion"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="reqInputFeatures"
type="int"
transient="false"
@@ -49557,1785 +49685,6 @@
</method>
</class>
</package>
-<package name="android.gesture"
->
-<class name="Gesture"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="android.os.Parcelable">
-</implements>
-<constructor name="Gesture"
- type="android.gesture.Gesture"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="addStroke"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="stroke" type="android.gesture.GestureStroke">
-</parameter>
-</method>
-<method name="describeContents"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getBoundingBox"
- return="android.graphics.RectF"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getID"
- return="long"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getLength"
- return="float"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getStrokes"
- return="java.util.ArrayList&lt;android.gesture.GestureStroke&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getStrokesCount"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="toBitmap"
- return="android.graphics.Bitmap"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="width" type="int">
-</parameter>
-<parameter name="height" type="int">
-</parameter>
-<parameter name="edge" type="int">
-</parameter>
-<parameter name="numSample" type="int">
-</parameter>
-<parameter name="color" type="int">
-</parameter>
-</method>
-<method name="toBitmap"
- return="android.graphics.Bitmap"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="width" type="int">
-</parameter>
-<parameter name="height" type="int">
-</parameter>
-<parameter name="edge" type="int">
-</parameter>
-<parameter name="color" type="int">
-</parameter>
-</method>
-<method name="toPath"
- return="android.graphics.Path"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="toPath"
- return="android.graphics.Path"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="path" type="android.graphics.Path">
-</parameter>
-</method>
-<method name="toPath"
- return="android.graphics.Path"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="width" type="int">
-</parameter>
-<parameter name="height" type="int">
-</parameter>
-<parameter name="edge" type="int">
-</parameter>
-<parameter name="numSample" type="int">
-</parameter>
-</method>
-<method name="toPath"
- return="android.graphics.Path"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="path" type="android.graphics.Path">
-</parameter>
-<parameter name="width" type="int">
-</parameter>
-<parameter name="height" type="int">
-</parameter>
-<parameter name="edge" type="int">
-</parameter>
-<parameter name="numSample" type="int">
-</parameter>
-</method>
-<method name="writeToParcel"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="out" type="android.os.Parcel">
-</parameter>
-<parameter name="flags" type="int">
-</parameter>
-</method>
-<field name="CREATOR"
- type="android.os.Parcelable.Creator"
- transient="false"
- volatile="false"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="GestureLibraries"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="fromFile"
- return="android.gesture.GestureLibrary"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="path" type="java.lang.String">
-</parameter>
-</method>
-<method name="fromFile"
- return="android.gesture.GestureLibrary"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="path" type="java.io.File">
-</parameter>
-</method>
-<method name="fromPrivateFile"
- return="android.gesture.GestureLibrary"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="name" type="java.lang.String">
-</parameter>
-</method>
-<method name="fromRawResource"
- return="android.gesture.GestureLibrary"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="resourceId" type="int">
-</parameter>
-</method>
-</class>
-<class name="GestureLibrary"
- extends="java.lang.Object"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="GestureLibrary"
- type="android.gesture.GestureLibrary"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="protected"
->
-</constructor>
-<method name="addGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="getGestureEntries"
- return="java.util.Set&lt;java.lang.String&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestures"
- return="java.util.ArrayList&lt;android.gesture.Gesture&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-</method>
-<method name="getLearner"
- return="android.gesture.Learner"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getOrientationStyle"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getSequenceType"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="isReadOnly"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="load"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="recognize"
- return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="removeEntry"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-</method>
-<method name="removeGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="save"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="setOrientationStyle"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="style" type="int">
-</parameter>
-</method>
-<method name="setSequenceType"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="int">
-</parameter>
-</method>
-<field name="mStore"
- type="android.gesture.GestureStore"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="protected"
->
-</field>
-</class>
-<class name="GestureOverlayView"
- extends="android.widget.FrameLayout"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="GestureOverlayView"
- type="android.gesture.GestureOverlayView"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-</constructor>
-<constructor name="GestureOverlayView"
- type="android.gesture.GestureOverlayView"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="attrs" type="android.util.AttributeSet">
-</parameter>
-</constructor>
-<constructor name="GestureOverlayView"
- type="android.gesture.GestureOverlayView"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="attrs" type="android.util.AttributeSet">
-</parameter>
-<parameter name="defStyle" type="int">
-</parameter>
-</constructor>
-<method name="addOnGestureListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.GestureOverlayView.OnGestureListener">
-</parameter>
-</method>
-<method name="addOnGesturePerformedListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturePerformedListener">
-</parameter>
-</method>
-<method name="addOnGesturingListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturingListener">
-</parameter>
-</method>
-<method name="cancelClearAnimation"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="cancelGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="clear"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="animated" type="boolean">
-</parameter>
-</method>
-<method name="getCurrentStroke"
- return="java.util.ArrayList&lt;android.gesture.GesturePoint&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGesture"
- return="android.gesture.Gesture"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestureColor"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestureStrokeAngleThreshold"
- return="float"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestureStrokeLengthThreshold"
- return="float"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestureStrokeSquarenessTreshold"
- return="float"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestureStrokeType"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestureStrokeWidth"
- return="float"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getOrientation"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getUncertainGestureColor"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="isEventsInterceptionEnabled"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="isFadeEnabled"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="isGesturing"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="removeAllOnGestureListeners"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="removeAllOnGesturePerformedListeners"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="removeAllOnGesturingListeners"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="removeOnGestureListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.GestureOverlayView.OnGestureListener">
-</parameter>
-</method>
-<method name="removeOnGesturePerformedListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturePerformedListener">
-</parameter>
-</method>
-<method name="removeOnGesturingListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturingListener">
-</parameter>
-</method>
-<method name="setEventsInterceptionEnabled"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="enabled" type="boolean">
-</parameter>
-</method>
-<method name="setFadeEnabled"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fadeEnabled" type="boolean">
-</parameter>
-</method>
-<method name="setGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="setGestureColor"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="color" type="int">
-</parameter>
-</method>
-<method name="setGestureStrokeAngleThreshold"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gestureStrokeAngleThreshold" type="float">
-</parameter>
-</method>
-<method name="setGestureStrokeLengthThreshold"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gestureStrokeLengthThreshold" type="float">
-</parameter>
-</method>
-<method name="setGestureStrokeSquarenessTreshold"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gestureStrokeSquarenessTreshold" type="float">
-</parameter>
-</method>
-<method name="setGestureStrokeType"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gestureStrokeType" type="int">
-</parameter>
-</method>
-<method name="setGestureStrokeWidth"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gestureStrokeWidth" type="float">
-</parameter>
-</method>
-<method name="setOrientation"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="orientation" type="int">
-</parameter>
-</method>
-<method name="setUncertainGestureColor"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="color" type="int">
-</parameter>
-</method>
-<field name="GESTURE_STROKE_TYPE_MULTIPLE"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="GESTURE_STROKE_TYPE_SINGLE"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="ORIENTATION_HORIZONTAL"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="ORIENTATION_VERTICAL"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<interface name="GestureOverlayView.OnGestureListener"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="onGesture"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onGestureCancelled"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onGestureEnded"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-<method name="onGestureStarted"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="event" type="android.view.MotionEvent">
-</parameter>
-</method>
-</interface>
-<interface name="GestureOverlayView.OnGesturePerformedListener"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="onGesturePerformed"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-</interface>
-<interface name="GestureOverlayView.OnGesturingListener"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="onGesturingEnded"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-</method>
-<method name="onGesturingStarted"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="overlay" type="android.gesture.GestureOverlayView">
-</parameter>
-</method>
-</interface>
-<class name="GesturePoint"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="GesturePoint"
- type="android.gesture.GesturePoint"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="x" type="float">
-</parameter>
-<parameter name="y" type="float">
-</parameter>
-<parameter name="t" type="long">
-</parameter>
-</constructor>
-<field name="timestamp"
- type="long"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="x"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="y"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="GestureStore"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="GestureStore"
- type="android.gesture.GestureStore"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="addGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="getGestureEntries"
- return="java.util.Set&lt;java.lang.String&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getGestures"
- return="java.util.ArrayList&lt;android.gesture.Gesture&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-</method>
-<method name="getOrientationStyle"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getSequenceType"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="load"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="stream" type="java.io.InputStream">
-</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
-<method name="load"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="stream" type="java.io.InputStream">
-</parameter>
-<parameter name="closeStream" type="boolean">
-</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
-<method name="recognize"
- return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="removeEntry"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-</method>
-<method name="removeGesture"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="entryName" type="java.lang.String">
-</parameter>
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="save"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="stream" type="java.io.OutputStream">
-</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
-<method name="save"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="stream" type="java.io.OutputStream">
-</parameter>
-<parameter name="closeStream" type="boolean">
-</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
-<method name="setOrientationStyle"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="style" type="int">
-</parameter>
-</method>
-<method name="setSequenceType"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="int">
-</parameter>
-</method>
-<field name="ORIENTATION_INVARIANT"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="ORIENTATION_SENSITIVE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SEQUENCE_INVARIANT"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SEQUENCE_SENSITIVE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="GestureStroke"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="GestureStroke"
- type="android.gesture.GestureStroke"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="points" type="java.util.ArrayList&lt;android.gesture.GesturePoint&gt;">
-</parameter>
-</constructor>
-<method name="clearPath"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="computeOrientedBoundingBox"
- return="android.gesture.OrientedBoundingBox"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getPath"
- return="android.graphics.Path"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="toPath"
- return="android.graphics.Path"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="width" type="float">
-</parameter>
-<parameter name="height" type="float">
-</parameter>
-<parameter name="numSample" type="int">
-</parameter>
-</method>
-<field name="boundingBox"
- type="android.graphics.RectF"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="length"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="points"
- type="float[]"
- transient="false"
- volatile="false"
- value="null"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="Learner"
- extends="java.lang.Object"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility=""
->
-</class>
-<class name="LetterRecognizer"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="recognize"
- return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-</method>
-<method name="recognize"
- return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gesture" type="android.gesture.Gesture">
-</parameter>
-<parameter name="predictions" type="java.util.ArrayList&lt;android.gesture.Prediction&gt;">
-</parameter>
-</method>
-</class>
-<class name="LetterRecognizers"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="fromFile"
- return="android.gesture.LetterRecognizer"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="path" type="java.lang.String">
-</parameter>
-</method>
-<method name="fromFile"
- return="android.gesture.LetterRecognizer"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="file" type="java.io.File">
-</parameter>
-</method>
-<method name="fromResource"
- return="android.gesture.LetterRecognizer"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="resourceId" type="int">
-</parameter>
-</method>
-<method name="fromStream"
- return="android.gesture.LetterRecognizer"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="stream" type="java.io.InputStream">
-</parameter>
-</method>
-<method name="fromType"
- return="android.gesture.LetterRecognizer"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="context" type="android.content.Context">
-</parameter>
-<parameter name="type" type="int">
-</parameter>
-</method>
-<field name="RECOGNIZER_LATIN_LOWERCASE"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="OrientedBoundingBox"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<field name="centerX"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="centerY"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="height"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="orientation"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="squareness"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="width"
- type="float"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="Prediction"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<field name="name"
- type="java.lang.String"
- transient="false"
- volatile="false"
- static="false"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="score"
- type="double"
- transient="false"
- volatile="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-</package>
<package name="android.graphics"
>
<class name="AvoidXfermode"
@@ -110663,6 +109012,61 @@
visibility="public"
>
</field>
+<field name="TTS_DEFAULT_LANG"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;tts_default_lang&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_DEFAULT_PITCH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;tts_default_pitch&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_DEFAULT_RATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;tts_default_rate&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_DEFAULT_SYNTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;tts_default_synth&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TTS_USE_DEFAULTS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;tts_use_defaults&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USB_MASS_STORAGE_ENABLED"
type="java.lang.String"
transient="false"
@@ -115898,6 +114302,53 @@
visibility="public"
>
</constructor>
+<method name="assertActivityRequiresPermission"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+<parameter name="className" type="java.lang.String">
+</parameter>
+<parameter name="permission" type="java.lang.String">
+</parameter>
+</method>
+<method name="assertReadingContentUriRequiresPermission"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="permission" type="java.lang.String">
+</parameter>
+</method>
+<method name="assertWritingContentUriRequiresPermission"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uri" type="android.net.Uri">
+</parameter>
+<parameter name="permission" type="java.lang.String">
+</parameter>
+</method>
<method name="getContext"
return="android.content.Context"
abstract="false"
@@ -119315,6 +117766,19 @@
<parameter name="mode" type="int">
</parameter>
</method>
+<method name="getSharedPrefsFile"
+ return="java.io.File"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
<method name="getSystemService"
return="java.lang.Object"
abstract="false"
@@ -163869,17 +162333,6 @@
visibility="public"
>
</method>
-<method name="getGestures"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getListPaddingBottom"
return="int"
abstract="false"
@@ -164253,19 +162706,6 @@
<parameter name="filterText" type="java.lang.String">
</parameter>
</method>
-<method name="setGestures"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="gestures" type="int">
-</parameter>
-</method>
<method name="setOnScrollListener"
return="void"
abstract="false"
@@ -164411,39 +162851,6 @@
<parameter name="dr" type="android.graphics.drawable.Drawable">
</parameter>
</method>
-<field name="GESTURES_FILTER"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="GESTURES_JUMP"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="GESTURES_NONE"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="TRANSCRIPT_MODE_ALWAYS_SCROLL"
type="int"
transient="false"
@@ -176268,6 +174675,30 @@
<parameter name="isExpanded" type="boolean">
</parameter>
</method>
+<method name="getViewBinder"
+ return="android.widget.SimpleCursorTreeAdapter.ViewBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setViewBinder"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewBinder" type="android.widget.SimpleCursorTreeAdapter.ViewBinder">
+</parameter>
+</method>
<method name="setViewImage"
return="void"
abstract="false"
@@ -176283,7 +174714,47 @@
<parameter name="value" type="java.lang.String">
</parameter>
</method>
+<method name="setViewText"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.widget.TextView">
+</parameter>
+<parameter name="text" type="java.lang.String">
+</parameter>
+</method>
</class>
+<interface name="SimpleCursorTreeAdapter.ViewBinder"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="setViewValue"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+<parameter name="cursor" type="android.database.Cursor">
+</parameter>
+<parameter name="columnIndex" type="int">
+</parameter>
+</method>
+</interface>
<class name="SimpleExpandableListAdapter"
extends="android.widget.BaseExpandableListAdapter"
abstract="false"
@@ -177258,6 +175729,17 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="getTag"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="setContent"
return="android.widget.TabHost.TabSpec"
abstract="false"
@@ -177325,6 +175807,19 @@
<parameter name="icon" type="android.graphics.drawable.Drawable">
</parameter>
</method>
+<method name="setIndicator"
+ return="android.widget.TabHost.TabSpec"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+</method>
</class>
<class name="TabWidget"
extends="android.widget.LinearLayout"
@@ -177398,6 +175893,30 @@
<parameter name="index" type="int">
</parameter>
</method>
+<method name="getChildTabViewAt"
+ return="android.view.View"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
+<method name="getTabCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="onFocusChange"
return="void"
abstract="false"
@@ -177426,6 +175945,32 @@
<parameter name="index" type="int">
</parameter>
</method>
+<method name="setDividerDrawable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="drawable" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
+<method name="setDividerDrawable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="resId" type="int">
+</parameter>
+</method>
</class>
<class name="TableLayout"
extends="android.widget.LinearLayout"
@@ -287323,7 +285868,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="val" type="int">
+<parameter name="buf" type="byte[]">
+</parameter>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="nbytes" type="int">
</parameter>
</method>
<method name="update"
@@ -287336,11 +285885,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buf" type="byte[]">
-</parameter>
-<parameter name="off" type="int">
-</parameter>
-<parameter name="nbytes" type="int">
+<parameter name="val" type="int">
</parameter>
</method>
</interface>
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 453dc29..81639ad 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -215,7 +215,7 @@ status_t CameraService::Client::unlock()
{
Mutex::Autolock _l(mLock);
// allow anyone to use camera
- LOGV("unlock (%p)", getCameraClient()->asBinder().get());
+ LOGD("unlock (%p)", getCameraClient()->asBinder().get());
status_t result = checkPid();
if (result == NO_ERROR) {
mClientPid = 0;
@@ -230,7 +230,7 @@ status_t CameraService::Client::unlock()
status_t CameraService::Client::connect(const sp<ICameraClient>& client)
{
// connect a new process to the camera
- LOGV("connect (%p)", client->asBinder().get());
+ LOGD("connect (%p)", client->asBinder().get());
// I hate this hack, but things get really ugly when the media recorder
// service is handing back the camera to the app. The ICameraClient
@@ -245,7 +245,7 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client)
sp<ICameraClient> oldClient;
{
Mutex::Autolock _l(mLock);
- if (mClientPid != 0) {
+ if (mClientPid != 0 && checkPid() != NO_ERROR) {
LOGW("Tried to connect to locked camera");
return -EBUSY;
}
@@ -257,7 +257,7 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client)
mCameraClient = client;
mClientPid = -1;
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
- LOGV("connect new process (%d) to existing camera client", mClientPid);
+ LOGD("connect new process (%d) to existing camera client", mClientPid);
}
}
@@ -319,17 +319,17 @@ void CameraService::Client::disconnect()
IPCThreadState::self()->getCallingPid());
Mutex::Autolock lock(mLock);
if (mClientPid <= 0) {
- LOGV("camera is unlocked, don't tear down hardware");
+ LOGD("camera is unlocked, don't tear down hardware");
return;
}
if (checkPid() != NO_ERROR) {
- LOGV("Different client - don't disconnect");
+ LOGD("Different client - don't disconnect");
return;
}
mCameraService->removeClient(mCameraClient);
if (mHardware != 0) {
- LOGV("hardware teardown");
+ LOGD("hardware teardown");
// Before destroying mHardware, we must make sure it's in the
// idle state.
mHardware->stopPreview();
diff --git a/cmds/bmgr/Android.mk b/cmds/bmgr/Android.mk
new file mode 100644
index 0000000..8a1670b
--- /dev/null
+++ b/cmds/bmgr/Android.mk
@@ -0,0 +1,15 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := bmgr
+include $(BUILD_JAVA_LIBRARY)
+
+
+include $(CLEAR_VARS)
+ALL_PREBUILT += $(TARGET_OUT)/bin/bmgr
+$(TARGET_OUT)/bin/bmgr : $(LOCAL_PATH)/bmgr | $(ACP)
+ $(transform-prebuilt-to-target)
+
diff --git a/cmds/bmgr/MODULE_LICENSE_APACHE2 b/cmds/bmgr/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/bmgr/MODULE_LICENSE_APACHE2
diff --git a/cmds/bmgr/NOTICE b/cmds/bmgr/NOTICE
new file mode 100644
index 0000000..64aaa8d
--- /dev/null
+++ b/cmds/bmgr/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2009, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/cmds/bmgr/bmgr b/cmds/bmgr/bmgr
new file mode 100755
index 0000000..6b4bbe2
--- /dev/null
+++ b/cmds/bmgr/bmgr
@@ -0,0 +1,7 @@
+# Script to start "bmgr" on the device, which has a very rudimentary
+# shell.
+#
+base=/system
+export CLASSPATH=$base/framework/bmgr.jar
+exec app_process $base/bin com.android.commands.bmgr.Bmgr "$@"
+
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
new file mode 100644
index 0000000..467cac1
--- /dev/null
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.commands.bmgr;
+
+import android.backup.IBackupManager;
+import android.backup.IRestoreSession;
+import android.backup.RestoreSet;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+public final class Bmgr {
+ IBackupManager mBmgr;
+ IRestoreSession mRestore;
+
+ static final String BMGR_NOT_RUNNING_ERR =
+ "Error: Could not access the Backup Manager. Is the system running?";
+ static final String TRANSPORT_NOT_RUNNING_ERR =
+ "Error: Could not access the backup transport. Is the system running?";
+
+ private String[] mArgs;
+ private int mNextArg;
+ private String mCurArgData;
+
+ public static void main(String[] args) {
+ new Bmgr().run(args);
+ }
+
+ public void run(String[] args) {
+ boolean validCommand = false;
+ if (args.length < 1) {
+ showUsage();
+ return;
+ }
+
+ mBmgr = IBackupManager.Stub.asInterface(ServiceManager.getService("backup"));
+ if (mBmgr == null) {
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ return;
+ }
+
+ mArgs = args;
+ String op = args[0];
+ mNextArg = 1;
+
+ if ("run".equals(op)) {
+ doRun();
+ return;
+ }
+
+ if ("backup".equals(op)) {
+ doBackup();
+ return;
+ }
+
+ if ("list".equals(op)) {
+ doList();
+ return;
+ }
+ }
+
+ private void doRun() {
+ try {
+ mBmgr.backupNow();
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ }
+ }
+
+ private void doBackup() {
+ boolean isFull = false;
+ String pkg = nextArg();
+ if ("-f".equals(pkg)) {
+ isFull = true;
+ pkg = nextArg();
+ }
+
+ if (pkg == null || pkg.startsWith("-")) {
+ showUsage();
+ return;
+ }
+
+ try {
+ // !!! TODO: handle full backup
+ mBmgr.dataChanged(pkg);
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ }
+ }
+
+ private void doList() {
+ String arg = nextArg(); // sets, transports, packages set#
+ if ("transports".equals(arg)) {
+ doListTransports();
+ return;
+ }
+
+ // The rest of the 'list' options work with a restore session on the current transport
+ try {
+ int curTransport = mBmgr.getCurrentTransport();
+ mRestore = mBmgr.beginRestoreSession(curTransport);
+
+ if ("sets".equals(arg)) {
+ doListRestoreSets();
+ }
+
+ mRestore.endRestoreSession();
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ }
+ }
+
+ private void doListTransports() {
+
+ }
+
+ private void doListRestoreSets() {
+ try {
+ RestoreSet[] sets = mRestore.getAvailableRestoreSets();
+ if (sets.length == 0) {
+ System.out.println("No restore sets available");
+ } else {
+ for (RestoreSet s : sets) {
+ System.out.println(" " + s.token + " : " + s.name);
+ }
+ }
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(TRANSPORT_NOT_RUNNING_ERR);
+ }
+ }
+
+ private String nextArg() {
+ if (mNextArg >= mArgs.length) {
+ return null;
+ }
+ String arg = mArgs[mNextArg];
+ mNextArg++;
+ return arg;
+ }
+
+ private static void showUsage() {
+ System.err.println("usage: bmgr [backup|restore|list|transport|run]");
+ System.err.println(" bmgr backup [-f] package");
+ System.err.println(" bmgr list sets");
+ System.err.println(" #bmgr list transports");
+ System.err.println(" #bmgr transport which#");
+ System.err.println(" #bmgr restore set#");
+ System.err.println(" bmgr run");
+ }
+} \ No newline at end of file
diff --git a/cmds/keystore/Android.mk b/cmds/keystore/Android.mk
new file mode 100644
index 0000000..20f4adf
--- /dev/null
+++ b/cmds/keystore/Android.mk
@@ -0,0 +1,21 @@
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ keystore.c commands.c
+
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, system-core)/cutils
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils
+
+LOCAL_STATIC_LIBRARIES :=
+
+LOCAL_MODULE:= keystore
+
+include $(BUILD_EXECUTABLE)
+
+endif # !simulator))
diff --git a/cmds/keystore/commands.c b/cmds/keystore/commands.c
new file mode 100644
index 0000000..e53cece
--- /dev/null
+++ b/cmds/keystore/commands.c
@@ -0,0 +1,141 @@
+/*
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "keystore.h"
+
+static DIR *open_keystore(const char *dir)
+{
+ DIR *d;
+ if ((d = opendir(dir)) == NULL) {
+ if (mkdir(dir, 0770) < 0) {
+ LOGE("cannot create dir '%s': %s\n", dir, strerror(errno));
+ unlink(dir);
+ return NULL;
+ }
+ d = open_keystore(dir);
+ }
+ return d;
+}
+
+static int list_files(const char *dir, char reply[REPLY_MAX]) {
+ struct dirent *de;
+ DIR *d;
+
+ if ((d = open_keystore(dir)) == NULL) {
+ return -1;
+ }
+ reply[0]=0;
+ while ((de = readdir(d))) {
+ if (de->d_type != DT_REG) continue;
+ if (reply[0] != 0) strlcat(reply, " ", REPLY_MAX);
+ if (strlcat(reply, de->d_name, REPLY_MAX) >= REPLY_MAX) {
+ LOGE("reply is too long(too many files under '%s'\n", dir);
+ return -1;
+ }
+ }
+ closedir(d);
+ return 0;
+}
+
+static int copy_keyfile(const char *keystore, const char *srcfile) {
+ int srcfd, dstfd;
+ int length;
+ char buf[2048];
+ char dstfile[KEYNAME_LENGTH];
+ const char *filename = strrchr(srcfile, '/');
+
+ strlcpy(dstfile, keystore, KEYNAME_LENGTH);
+ strlcat(dstfile, "/", KEYNAME_LENGTH);
+ if (strlcat(dstfile, filename ? filename + 1 : srcfile,
+ KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
+ LOGE("keyname is too long '%s'\n", srcfile);
+ return -1;
+ }
+
+ if ((srcfd = open(srcfile, O_RDONLY)) == -1) {
+ LOGE("Cannot open the original file '%s'\n", srcfile);
+ return -1;
+ }
+ if ((dstfd = open(dstfile, O_CREAT|O_RDWR)) == -1) {
+ LOGE("Cannot open the destination file '%s'\n", dstfile);
+ return -1;
+ }
+ while((length = read(srcfd, buf, 2048)) > 0) {
+ write(dstfd, buf, length);
+ }
+ close(srcfd);
+ close(dstfd);
+ chmod(dstfile, 0440);
+ return 0;
+}
+
+static int install_key(const char *dir, const char *keyfile)
+{
+ struct dirent *de;
+ DIR *d;
+
+ if ((d = open_keystore(dir)) == NULL) {
+ return -1;
+ }
+ return copy_keyfile(dir, keyfile);
+}
+
+static int remove_key(const char *dir, const char *keyfile)
+{
+ char dstfile[KEYNAME_LENGTH];
+
+ strlcpy(dstfile, dir, KEYNAME_LENGTH);
+ strlcat(dstfile, "/", KEYNAME_LENGTH);
+ if (strlcat(dstfile, keyfile, KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
+ LOGE("keyname is too long '%s'\n", keyfile);
+ return -1;
+ }
+ if (unlink(dstfile)) {
+ LOGE("cannot delete '%s': %s\n", dstfile, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int list_certs(char reply[REPLY_MAX])
+{
+ return list_files(CERTS_DIR, reply);
+}
+
+int list_userkeys(char reply[REPLY_MAX])
+{
+ return list_files(USERKEYS_DIR, reply);
+}
+
+int install_cert(const char *certfile)
+{
+ return install_key(CERTS_DIR, certfile);
+}
+
+int install_userkey(const char *keyfile)
+{
+ return install_key(USERKEYS_DIR, keyfile);
+}
+
+int remove_cert(const char *certfile)
+{
+ return remove_key(CERTS_DIR, certfile);
+}
+
+int remove_userkey(const char *keyfile)
+{
+ return remove_key(USERKEYS_DIR, keyfile);
+}
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
new file mode 100644
index 0000000..5193b3d
--- /dev/null
+++ b/cmds/keystore/keystore.c
@@ -0,0 +1,255 @@
+/*
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "keystore.h"
+
+
+static int do_list_certs(char **arg, char reply[REPLY_MAX])
+{
+ return list_certs(reply);
+}
+
+static int do_list_userkeys(char **arg, char reply[REPLY_MAX])
+{
+ return list_userkeys(reply);
+}
+
+static int do_install_cert(char **arg, char reply[REPLY_MAX])
+{
+ return install_cert(arg[0]); /* move the certificate to keystore */
+}
+
+static int do_remove_cert(char **arg, char reply[REPLY_MAX])
+{
+ return remove_cert(arg[0]); /* certificate */
+}
+
+static int do_install_userkey(char **arg, char reply[REPLY_MAX])
+{
+ return install_userkey(arg[0]); /* move the certificate to keystore */
+}
+
+static int do_remove_userkey(char **arg, char reply[REPLY_MAX])
+{
+ return remove_userkey(arg[0]); /* userkey */
+}
+
+struct cmdinfo {
+ const char *name;
+ unsigned numargs;
+ int (*func)(char **arg, char reply[REPLY_MAX]);
+};
+
+
+struct cmdinfo cmds[] = {
+ { "listcerts", 0, do_list_certs },
+ { "listuserkeys", 0, do_list_userkeys },
+ { "installcert", 1, do_install_cert },
+ { "removecert", 1, do_remove_cert },
+ { "installuserkey", 1, do_install_userkey },
+ { "removeuserkey", 1, do_remove_userkey },
+};
+
+static int readx(int s, void *_buf, int count)
+{
+ char *buf = _buf;
+ int n = 0, r;
+ if (count < 0) return -1;
+ while (n < count) {
+ r = read(s, buf + n, count - n);
+ if (r < 0) {
+ if (errno == EINTR) continue;
+ LOGE("read error: %s\n", strerror(errno));
+ return -1;
+ }
+ if (r == 0) {
+ LOGE("eof\n");
+ return -1; /* EOF */
+ }
+ n += r;
+ }
+ return 0;
+}
+
+static int writex(int s, const void *_buf, int count)
+{
+ const char *buf = _buf;
+ int n = 0, r;
+ if (count < 0) return -1;
+ while (n < count) {
+ r = write(s, buf + n, count - n);
+ if (r < 0) {
+ if (errno == EINTR) continue;
+ LOGE("write error: %s\n", strerror(errno));
+ return -1;
+ }
+ n += r;
+ }
+ return 0;
+}
+
+
+/* Tokenize the command buffer, locate a matching command,
+ * ensure that the required number of arguments are provided,
+ * call the function(), return the result.
+ */
+static int execute(int s, char cmd[BUFFER_MAX])
+{
+ char reply[REPLY_MAX];
+ char *arg[TOKEN_MAX+1];
+ unsigned i;
+ unsigned n = 0;
+ unsigned short count;
+ short ret = -1;
+
+ /* default reply is "" */
+ reply[0] = 0;
+
+ /* n is number of args (not counting arg[0]) */
+ arg[0] = cmd;
+ while (*cmd) {
+ if (isspace(*cmd)) {
+ *cmd++ = 0;
+ n++;
+ arg[n] = cmd;
+ if (n == TOKEN_MAX) {
+ LOGE("too many arguments\n");
+ goto done;
+ }
+ }
+ cmd++;
+ }
+
+ for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) {
+ if (!strcmp(cmds[i].name,arg[0])) {
+ if (n != cmds[i].numargs) {
+ LOGE("%s requires %d arguments (%d given)\n",
+ cmds[i].name, cmds[i].numargs, n);
+ } else {
+ ret = (short) cmds[i].func(arg + 1, reply);
+ }
+ goto done;
+ }
+ }
+ LOGE("unsupported command '%s'\n", arg[0]);
+
+done:
+ if (reply[0]) {
+ strlcpy(cmd, reply, BUFFER_MAX);
+ count = strlen(cmd);
+ } else {
+ count = 0;
+ }
+ if (writex(s, &ret, sizeof(ret))) return -1;
+ if (ret == 0) {
+ if (writex(s, &count, sizeof(count))) return -1;
+ if (writex(s, cmd, count)) return -1;
+ }
+
+ return 0;
+}
+
+int shell_command(const int argc, const char **argv)
+{
+ int fd, i;
+ short ret;
+ unsigned short count;
+ char buf[BUFFER_MAX]="";
+
+ fd = socket_local_client(SOCKET_PATH,
+ ANDROID_SOCKET_NAMESPACE_RESERVED,
+ SOCK_STREAM);
+ if (fd == -1) {
+ fprintf(stderr, "Keystore service is not up and running\n");
+ exit(1);
+ }
+ for(i = 0; i < argc; i++) {
+ if (i > 0) strlcat(buf, " ", BUFFER_MAX);
+ if(strlcat(buf, argv[i], BUFFER_MAX) >= BUFFER_MAX) {
+ fprintf(stderr, "Arguments are too long\n");
+ exit(1);
+ }
+ }
+ count = strlen(buf);
+ if (writex(fd, &count, sizeof(count))) return -1;
+ if (writex(fd, buf, strlen(buf))) return -1;
+ if (readx(fd, &ret, sizeof(ret))) return -1;
+ if (ret == 0) {
+ if (readx(fd, &count, sizeof(count))) return -1;
+ if (readx(fd, buf, count)) return -1;
+ buf[count]=0;
+ fprintf(stdout, "%s\n", buf);
+ } else {
+ fprintf(stderr, "Failed, please check log!\n");
+ }
+ return 0;
+}
+
+int main(const int argc, const char *argv[])
+{
+ char buf[BUFFER_MAX];
+ struct sockaddr addr;
+ socklen_t alen;
+ int lsocket, s, count;
+
+ if (argc > 1) {
+ return shell_command(argc - 1, argv + 1);
+ }
+
+ lsocket = android_get_control_socket(SOCKET_PATH);
+ if (lsocket < 0) {
+ LOGE("Failed to get socket from environment: %s\n", strerror(errno));
+ exit(1);
+ }
+ if (listen(lsocket, 5)) {
+ LOGE("Listen on socket failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ fcntl(lsocket, F_SETFD, FD_CLOEXEC);
+
+ for (;;) {
+ alen = sizeof(addr);
+ s = accept(lsocket, &addr, &alen);
+ if (s < 0) {
+ LOGE("Accept failed: %s\n", strerror(errno));
+ continue;
+ }
+ fcntl(s, F_SETFD, FD_CLOEXEC);
+
+ LOGI("new connection\n");
+ for (;;) {
+ unsigned short count;
+ if (readx(s, &count, sizeof(count))) {
+ LOGE("failed to read size\n");
+ break;
+ }
+ if ((count < 1) || (count >= BUFFER_MAX)) {
+ LOGE("invalid size %d\n", count);
+ break;
+ }
+ if (readx(s, buf, count)) {
+ LOGE("failed to read command\n");
+ break;
+ }
+ buf[count] = 0;
+ if (execute(s, buf)) break;
+ }
+ LOGI("closing connection\n");
+ close(s);
+ }
+
+ return 0;
+}
diff --git a/cmds/keystore/keystore.h b/cmds/keystore/keystore.h
new file mode 100644
index 0000000..35acf0b9
--- /dev/null
+++ b/cmds/keystore/keystore.h
@@ -0,0 +1,57 @@
+/*
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "keystore"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <utime.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <cutils/sockets.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#define SOCKET_PATH "keystore"
+
+
+/* path of the keystore */
+
+#define KEYSTORE_DIR_PREFIX "/data/misc/keystore"
+#define CERTS_DIR KEYSTORE_DIR_PREFIX "/certs"
+#define USERKEYS_DIR KEYSTORE_DIR_PREFIX "/userkeys"
+
+#define BUFFER_MAX 1024 /* input buffer for commands */
+#define TOKEN_MAX 8 /* max number of arguments in buffer */
+#define REPLY_MAX 1024 /* largest reply allowed */
+#define KEYNAME_LENGTH 128
+
+/* commands.c */
+int list_certs(char reply[REPLY_MAX]);
+int list_userkeys(char reply[REPLY_MAX]);
+int install_cert(const char *certfile);
+int install_userkey(const char *keyfile);
+int remove_cert(const char *certfile);
+int remove_userkey(const char *keyfile);
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
index 83aae3a..c8fc12c 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -17,31 +17,10 @@
package android.accounts;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
import android.content.pm.RegisteredServicesCache;
-import android.content.res.XmlResourceParser;
import android.content.res.TypedArray;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
import android.util.AttributeSet;
-import android.util.Xml;
-
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParser;
/**
* A cache of services that export the {@link IAccountAuthenticator} interface. This cache
@@ -50,7 +29,8 @@ import org.xmlpull.v1.XmlPullParser;
* are made available via the {@link RegisteredServicesCache#getServiceInfo} method.
* @hide
*/
-/* package private */ class AccountAuthenticatorCache extends RegisteredServicesCache<String> {
+/* package private */ class AccountAuthenticatorCache
+ extends RegisteredServicesCache<AuthenticatorDescription> {
private static final String TAG = "Account";
private static final String SERVICE_INTERFACE = "android.accounts.AccountAuthenticator";
@@ -61,11 +41,17 @@ import org.xmlpull.v1.XmlPullParser;
super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME);
}
- public String parseServiceAttributes(AttributeSet attrs) {
+ public AuthenticatorDescription parseServiceAttributes(String packageName, AttributeSet attrs) {
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
com.android.internal.R.styleable.AccountAuthenticator);
try {
- return sa.getString(com.android.internal.R.styleable.AccountAuthenticator_accountType);
+ final String accountType =
+ sa.getString(com.android.internal.R.styleable.AccountAuthenticator_accountType);
+ final int labelId = sa.getResourceId(
+ com.android.internal.R.styleable.AccountAuthenticator_label, 0);
+ final int iconId = sa.getResourceId(
+ com.android.internal.R.styleable.AccountAuthenticator_icon, 0);
+ return new AuthenticatorDescription(accountType, packageName, labelId, iconId);
} finally {
sa.recycle();
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 4fcaa88..5182f2e 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -118,7 +118,7 @@ public class AccountManager {
});
}
- public String[] blockingGetAuthenticatorTypes() {
+ public AuthenticatorDescription[] blockingGetAuthenticatorTypes() {
ensureNotOnMainThread();
try {
return mService.getAuthenticatorTypes();
@@ -128,10 +128,10 @@ public class AccountManager {
}
}
- public Future1<String[]> getAuthenticatorTypes(Future1Callback<String[]> callback,
- Handler handler) {
- return startAsFuture(callback, handler, new Callable<String[]>() {
- public String[] call() throws Exception {
+ public Future1<AuthenticatorDescription[]> getAuthenticatorTypes(
+ Future1Callback<AuthenticatorDescription[]> callback, Handler handler) {
+ return startAsFuture(callback, handler, new Callable<AuthenticatorDescription[]>() {
+ public AuthenticatorDescription[] call() throws Exception {
return blockingGetAuthenticatorTypes();
}
});
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 545241f..4f617c4 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -215,14 +215,15 @@ public class AccountManagerService extends IAccountManager.Stub {
}
}
- public String[] getAuthenticatorTypes() {
+ public AuthenticatorDescription[] getAuthenticatorTypes() {
long identityToken = clearCallingIdentity();
try {
- Collection<AccountAuthenticatorCache.ServiceInfo<String>> authenticatorCollection =
- mAuthenticatorCache.getAllServices();
- String[] types = new String[authenticatorCollection.size()];
+ Collection<AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription>>
+ authenticatorCollection = mAuthenticatorCache.getAllServices();
+ AuthenticatorDescription[] types =
+ new AuthenticatorDescription[authenticatorCollection.size()];
int i = 0;
- for (AccountAuthenticatorCache.ServiceInfo<String> authenticator
+ for (AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticator
: authenticatorCollection) {
types[i] = authenticator.type;
i++;
diff --git a/core/java/android/accounts/AuthenticatorBindHelper.java b/core/java/android/accounts/AuthenticatorBindHelper.java
index 9d2ccf6..91e23ab 100644
--- a/core/java/android/accounts/AuthenticatorBindHelper.java
+++ b/core/java/android/accounts/AuthenticatorBindHelper.java
@@ -95,8 +95,9 @@ public class AuthenticatorBindHelper {
// otherwise find the component name for the authenticator and initiate a bind
// if no authenticator or the bind fails then return false, otherwise return true
- AccountAuthenticatorCache.ServiceInfo authenticatorInfo =
- mAuthenticatorCache.getServiceInfo(authenticatorType);
+ AccountAuthenticatorCache.ServiceInfo<AuthenticatorDescription> authenticatorInfo =
+ mAuthenticatorCache.getServiceInfo(
+ AuthenticatorDescription.newKey(authenticatorType));
if (authenticatorInfo == null) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "there is no authenticator for " + authenticatorType
diff --git a/core/java/android/accounts/AuthenticatorDescription.aidl b/core/java/android/accounts/AuthenticatorDescription.aidl
new file mode 100644
index 0000000..136361c
--- /dev/null
+++ b/core/java/android/accounts/AuthenticatorDescription.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accounts;
+
+parcelable AuthenticatorDescription;
diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java
new file mode 100644
index 0000000..f896bf8
--- /dev/null
+++ b/core/java/android/accounts/AuthenticatorDescription.java
@@ -0,0 +1,69 @@
+package android.accounts;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+public class AuthenticatorDescription implements Parcelable {
+ final public String type;
+ final public int labelId;
+ final public int iconId;
+ final public String packageName;
+
+ public AuthenticatorDescription(String type, String packageName, int labelId, int iconId) {
+ this.type = type;
+ this.packageName = packageName;
+ this.labelId = labelId;
+ this.iconId = iconId;
+ }
+
+ public static AuthenticatorDescription newKey(String type) {
+ return new AuthenticatorDescription(type);
+ }
+
+ private AuthenticatorDescription(String type) {
+ this.type = type;
+ this.packageName = null;
+ this.labelId = 0;
+ this.iconId = 0;
+ }
+
+ private AuthenticatorDescription(Parcel source) {
+ this.type = source.readString();
+ this.packageName = source.readString();
+ this.labelId = source.readInt();
+ this.iconId = source.readInt();
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public int hashCode() {
+ return type.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof AuthenticatorDescription)) return false;
+ final AuthenticatorDescription other = (AuthenticatorDescription) o;
+ return type.equals(other.type);
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(type);
+ dest.writeString(packageName);
+ dest.writeInt(labelId);
+ dest.writeInt(iconId);
+ }
+
+ public static final Creator<AuthenticatorDescription> CREATOR =
+ new Creator<AuthenticatorDescription>() {
+ public AuthenticatorDescription createFromParcel(Parcel source) {
+ return new AuthenticatorDescription(source);
+ }
+
+ public AuthenticatorDescription[] newArray(int size) {
+ return new AuthenticatorDescription[size];
+ }
+ };
+}
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 5e37a1f..15ab4e8 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -18,6 +18,7 @@ package android.accounts;
import android.accounts.IAccountManagerResponse;
import android.accounts.Account;
+import android.accounts.AuthenticatorDescription;
import android.os.Bundle;
/**
@@ -27,7 +28,7 @@ import android.os.Bundle;
interface IAccountManager {
String getPassword(in Account account);
String getUserData(in Account account, String key);
- String[] getAuthenticatorTypes();
+ AuthenticatorDescription[] getAuthenticatorTypes();
Account[] getAccounts();
Account[] getAccountsByType(String accountType);
boolean addAccount(in Account account, String password, in Bundle extras);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f9b3d05..7fb3449 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -628,6 +628,8 @@ public class Activity extends ContextThemeWrapper
boolean mStartedActivity;
/*package*/ int mConfigChangeFlags;
/*package*/ Configuration mCurrentConfig;
+ private SearchManager mSearchManager;
+ private Bundle mSearchDialogState = null;
private Window mWindow;
@@ -788,6 +790,9 @@ public class Activity extends ContextThemeWrapper
protected void onCreate(Bundle savedInstanceState) {
mVisibleFromClient = mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, true);
+ // uses super.getSystemService() since this.getSystemService() looks at the
+ // mSearchManager field.
+ mSearchManager = (SearchManager) super.getSystemService(Context.SEARCH_SERVICE);
mCalled = true;
}
@@ -805,9 +810,10 @@ public class Activity extends ContextThemeWrapper
// Also restore the state of a search dialog (if any)
// TODO more generic than just this manager
- SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- searchManager.restoreSearchDialog(savedInstanceState, SAVED_SEARCH_DIALOG_KEY);
+ Bundle searchState = savedInstanceState.getBundle(SAVED_SEARCH_DIALOG_KEY);
+ if (searchState != null) {
+ mSearchManager.restoreSearchDialog(searchState);
+ }
}
/**
@@ -1013,9 +1019,11 @@ public class Activity extends ContextThemeWrapper
// Also save the state of a search dialog (if any)
// TODO more generic than just this manager
- SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- searchManager.saveSearchDialog(outState, SAVED_SEARCH_DIALOG_KEY);
+ // onPause() should always be called before this method, so mSearchManagerState
+ // should be up to date.
+ if (mSearchDialogState != null) {
+ outState.putBundle(SAVED_SEARCH_DIALOG_KEY, mSearchDialogState);
+ }
}
/**
@@ -1286,12 +1294,6 @@ public class Activity extends ContextThemeWrapper
}
}
}
-
- // also dismiss search dialog if showing
- // TODO more generic than just this manager
- SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- searchManager.stopSearch();
// close any cursors we are managing.
int numCursors = mManagedCursors.size();
@@ -1301,6 +1303,10 @@ public class Activity extends ContextThemeWrapper
c.mCursor.close();
}
}
+
+ // Clear any search state saved in performPause(). If the state may be needed in the
+ // future, it will have been saved by performSaveInstanceState()
+ mSearchDialogState = null;
}
/**
@@ -1324,9 +1330,7 @@ public class Activity extends ContextThemeWrapper
// also update search dialog if showing
// TODO more generic than just this manager
- SearchManager searchManager =
- (SearchManager) getSystemService(Context.SEARCH_SERVICE);
- searchManager.onConfigurationChanged(newConfig);
+ mSearchManager.onConfigurationChanged(newConfig);
if (mWindow != null) {
// Pass the configuration changed event to the window
@@ -2543,10 +2547,7 @@ public class Activity extends ContextThemeWrapper
*/
public void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
- // activate the search manager and start it up!
- SearchManager searchManager = (SearchManager)
- getSystemService(Context.SEARCH_SERVICE);
- searchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
+ mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
appSearchData, globalSearch);
}
@@ -3265,6 +3266,8 @@ public class Activity extends ContextThemeWrapper
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
+ } else if (SEARCH_SERVICE.equals(name)) {
+ return mSearchManager;
}
return super.getSystemService(name);
}
@@ -3563,10 +3566,21 @@ public class Activity extends ContextThemeWrapper
"Activity " + mComponent.toShortString() +
" did not call through to super.onPostResume()");
}
+
+ // restore search dialog, if any
+ if (mSearchDialogState != null) {
+ mSearchManager.restoreSearchDialog(mSearchDialogState);
+ }
+ mSearchDialogState = null;
}
final void performPause() {
onPause();
+
+ // save search dialog state if the search dialog is open,
+ // and then dismiss the search dialog
+ mSearchDialogState = mSearchManager.saveSearchDialog();
+ mSearchManager.stopSearch();
}
final void performUserLeaving() {
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 34aeca1..c261acb 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -303,10 +303,14 @@ class ApplicationContext extends Context {
return new File(prefsFile.getPath() + ".bak");
}
+ public File getSharedPrefsFile(String name) {
+ return makeFilename(getPreferencesDir(), name + ".xml");
+ }
+
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
SharedPreferencesImpl sp;
- File f = makeFilename(getPreferencesDir(), name + ".xml");
+ File f = getSharedPrefsFile(name);
synchronized (sSharedPrefs) {
sp = sSharedPrefs.get(f);
if (sp != null && !sp.hasFileChanged()) {
diff --git a/core/java/android/app/FullBackupAgent.java b/core/java/android/app/FullBackupAgent.java
index 18d62e3..bf5cb5d 100644
--- a/core/java/android/app/FullBackupAgent.java
+++ b/core/java/android/app/FullBackupAgent.java
@@ -47,12 +47,11 @@ public class FullBackupAgent extends BackupAgent {
}
// That's the file set; now back it all up
- FileBackupHelper.performBackup(this, oldState, data, newState,
- (String[]) allFiles.toArray());
+ FileBackupHelper helper = new FileBackupHelper(this);
+ helper.performBackup(oldState, data, newState, (String[])allFiles.toArray());
}
@Override
public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) {
}
-
}
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 374423e..e8bd60a 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -16,7 +16,10 @@
package android.app;
+import android.app.ISearchManagerCallback;
import android.content.ComponentName;
+import android.content.res.Configuration;
+import android.os.Bundle;
import android.server.search.SearchableInfo;
/** @hide */
@@ -26,4 +29,15 @@ interface ISearchManager {
List<SearchableInfo> getSearchablesForWebSearch();
SearchableInfo getDefaultSearchableForWebSearch();
void setDefaultWebSearch(in ComponentName component);
+ void startSearch(in String initialQuery,
+ boolean selectInitialQuery,
+ in ComponentName launchActivity,
+ in Bundle appSearchData,
+ boolean globalSearch,
+ ISearchManagerCallback searchManagerCallback);
+ void stopSearch();
+ boolean isVisible();
+ Bundle onSaveInstanceState();
+ void onRestoreInstanceState(in Bundle savedInstanceState);
+ void onConfigurationChanged(in Configuration newConfig);
}
diff --git a/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl b/core/java/android/app/ISearchManagerCallback.aidl
index d057093..bdfb2ba 100644
--- a/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
+++ b/core/java/android/app/ISearchManagerCallback.aidl
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2008, The Android Open Source Project
+/**
+ * Copyright (c) 2009, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,12 +14,10 @@
* limitations under the License.
*/
-package android.bluetooth;
+package android.app;
-/**
- * {@hide}
- */
-oneway interface IBluetoothDeviceCallback
-{
- void onGetRemoteServiceChannelResult(in String address, int channel);
+/** @hide */
+oneway interface ISearchManagerCallback {
+ void onDismiss();
+ void onCancel();
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 0bb483b..9141c4c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -24,6 +24,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -74,8 +76,8 @@ import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
- * In-application-process implementation of Search Bar. This is still controlled by the
- * SearchManager, but it runs in the current activity's process to keep things lighter weight.
+ * System search dialog. This is controlled by the
+ * SearchManagerService and runs in the system process.
*
* @hide
*/
@@ -177,17 +179,17 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Window theWindow = getWindow();
- theWindow.setGravity(Gravity.TOP|Gravity.FILL_HORIZONTAL);
-
setContentView(com.android.internal.R.layout.search_bar);
- theWindow.setLayout(ViewGroup.LayoutParams.FILL_PARENT,
- // taking up the whole window (even when transparent) is less than ideal,
- // but necessary to show the popup window until the window manager supports
- // having windows anchored by their parent but not clipped by them.
- ViewGroup.LayoutParams.FILL_PARENT);
+ Window theWindow = getWindow();
WindowManager.LayoutParams lp = theWindow.getAttributes();
+ lp.type = WindowManager.LayoutParams.TYPE_SEARCH_BAR;
+ lp.width = ViewGroup.LayoutParams.FILL_PARENT;
+ // taking up the whole window (even when transparent) is less than ideal,
+ // but necessary to show the popup window until the window manager supports
+ // having windows anchored by their parent but not clipped by them.
+ lp.height = ViewGroup.LayoutParams.FILL_PARENT;
+ lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
theWindow.setAttributes(lp);
@@ -232,10 +234,12 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// Save voice intent for later queries/launching
mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+ mVoiceWebSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mVoiceWebSearchIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+ mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mLocationManager =
(LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
@@ -276,12 +280,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
*/
public boolean show(String initialQuery, boolean selectInitialQuery,
ComponentName componentName, Bundle appSearchData, boolean globalSearch) {
- if (isShowing()) {
- // race condition - already showing but not handling events yet.
- // in this case, just discard the "show" request
- return true;
- }
-
+
// Reset any stored values from last time dialog was shown.
mStoredComponentName = null;
mStoredAppSearchData = null;
@@ -440,11 +439,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
stopLocationUpdates();
- // TODO: Removing the listeners means that they never get called, since
- // Dialog.dismissDialog() calls onStop() before sendDismissMessage().
- setOnCancelListener(null);
- setOnDismissListener(null);
-
// stop receiving broadcasts (throws exception if none registered)
try {
getContext().unregisterReceiver(mBroadcastReceiver);
@@ -652,15 +646,15 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
mSearchAutoComplete.setDropDownAnimationStyle(0); // no animation
mSearchAutoComplete.setThreshold(mSearchable.getSuggestThreshold());
+ // we dismiss the entire dialog instead
+ mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
if (mGlobalSearchMode) {
mSearchAutoComplete.setDropDownAlwaysVisible(true); // fill space until results come in
- mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
mSearchAutoComplete.setDropDownBackgroundResource(
com.android.internal.R.drawable.search_dropdown_background);
} else {
mSearchAutoComplete.setDropDownAlwaysVisible(false);
- mSearchAutoComplete.setDropDownDismissedOnCompletion(true);
mSearchAutoComplete.setDropDownBackgroundResource(
com.android.internal.R.drawable.search_dropdown_background_apps);
}
@@ -1202,10 +1196,23 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
protected boolean launchSuggestion(int position, int actionKey, String actionMsg) {
Cursor c = mSuggestionsAdapter.getCursor();
if ((c != null) && c.moveToPosition(position)) {
- mSuggestionsAdapter.callCursorOnClick(c, position);
- // launch the intent
Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);
+
+ // report back about the click
+ if (mGlobalSearchMode) {
+ // in global search mode, do it via cursor
+ mSuggestionsAdapter.callCursorOnClick(c, position);
+ } else if (intent != null
+ && mPreviousComponents != null
+ && !mPreviousComponents.isEmpty()) {
+ // in-app search (and we have pivoted in as told by mPreviousComponents,
+ // which is used for keeping track of what we pop back to when we are pivoting into
+ // in app search.)
+ reportInAppClickToGlobalSearch(c, intent);
+ }
+
+ // launch the intent
launchIntent(intent);
return true;
@@ -1214,7 +1221,96 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
/**
- * Launches an intent. Also dismisses the search dialog if not in global search mode.
+ * Report a click from an in app search result back to global search for shortcutting porpoises.
+ *
+ * @param c The cursor that is pointing to the clicked position.
+ * @param intent The intent that will be launched for the click.
+ */
+ private void reportInAppClickToGlobalSearch(Cursor c, Intent intent) {
+ // for in app search, still tell global search via content provider
+ Uri uri = getClickReportingUri();
+ final ContentValues cv = new ContentValues();
+ cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_QUERY, mUserQuery);
+ final ComponentName source = mSearchable.getSearchActivity();
+ cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_COMPONENT, source.flattenToShortString());
+
+ // grab the intent columns from the intent we created since it has additional
+ // logic for falling back on the searchable default
+ cv.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION, intent.getAction());
+ cv.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, intent.getDataString());
+ cv.put(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA,
+ intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
+
+ // ensure the icons will work for global search
+ cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
+ wrapIconForPackage(
+ source,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_1)));
+ cv.put(SearchManager.SUGGEST_COLUMN_ICON_2,
+ wrapIconForPackage(
+ source,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_2)));
+
+ // the rest can be passed through directly
+ cv.put(SearchManager.SUGGEST_COLUMN_FORMAT,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_FORMAT));
+ cv.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_1));
+ cv.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_2));
+ cv.put(SearchManager.SUGGEST_COLUMN_QUERY,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY));
+ cv.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
+ getColumnString(c, SearchManager.SUGGEST_COLUMN_SHORTCUT_ID));
+ // note: deliberately omitting background color since it is only for global search
+ // "more results" entries
+ mContext.getContentResolver().insert(uri, cv);
+ }
+
+ /**
+ * @return A URI appropriate for reporting a click.
+ */
+ private Uri getClickReportingUri() {
+ Uri.Builder uriBuilder = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SearchManager.SEARCH_CLICK_REPORT_AUTHORITY);
+
+ uriBuilder.appendPath(SearchManager.SEARCH_CLICK_REPORT_URI_PATH);
+
+ return uriBuilder
+ .query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
+ .fragment("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
+ .build();
+ }
+
+ /**
+ * Wraps an icon for a particular package. If the icon is a resource id, it is converted into
+ * an android.resource:// URI.
+ *
+ * @param source The source of the icon
+ * @param icon The icon retrieved from a suggestion column
+ * @return An icon string appropriate for the package.
+ */
+ private String wrapIconForPackage(ComponentName source, String icon) {
+ if (icon == null || icon.length() == 0 || "0".equals(icon)) {
+ // SearchManager specifies that null or zero can be returned to indicate
+ // no icon. We also allow empty string.
+ return null;
+ } else if (!Character.isDigit(icon.charAt(0))){
+ return icon;
+ } else {
+ String packageName = source.getPackageName();
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(packageName)
+ .encodedPath(icon)
+ .toString();
+ }
+ }
+
+ /**
+ * Launches an intent and dismisses the search dialog (unless the intent
+ * is one of the special intents that modifies the state of the search dialog).
*/
private void launchIntent(Intent intent) {
if (intent == null) {
@@ -1223,9 +1319,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
if (handleSpecialIntent(intent)){
return;
}
- if (!mGlobalSearchMode) {
- dismiss();
- }
+ dismiss();
getContext().startActivity(intent);
}
@@ -1244,7 +1338,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
/**
- * Handles SearchManager#INTENT_ACTION_CHANGE_SOURCE.
+ * Handles {@link SearchManager#INTENT_ACTION_CHANGE_SEARCH_SOURCE}.
*/
private void handleChangeSourceIntent(Intent intent) {
Uri dataUri = intent.getData();
@@ -1408,6 +1502,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
int actionKey, String actionMsg) {
// Now build the Intent
Intent intent = new Intent(action);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (data != null) {
intent.setData(data);
}
@@ -1492,14 +1587,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
private boolean isEmpty() {
return TextUtils.getTrimmedLength(getText()) == 0;
}
-
- /**
- * Clears the entered text.
- */
- private void clear() {
- setText("");
- }
-
+
/**
* We override this method to avoid replacing the query box text
* when a suggestion is clicked.
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index f1cc24a..1ddd20a 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -28,6 +28,7 @@ import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.server.search.SearchableInfo;
+import android.util.Log;
import android.view.KeyEvent;
import java.util.List;
@@ -1108,6 +1109,10 @@ import java.util.List;
public class SearchManager
implements DialogInterface.OnDismissListener, DialogInterface.OnCancelListener
{
+
+ private static final boolean DBG = false;
+ private static final String TAG = "SearchManager";
+
/**
* This is a shortcut definition for the default menu key to use for invoking search.
*
@@ -1256,6 +1261,41 @@ public class SearchManager
*/
public final static String SHORTCUT_MIME_TYPE =
"vnd.android.cursor.item/vnd.android.search.suggest";
+
+
+ /**
+ * The authority of the provider to report clicks to when a click is detected after pivoting
+ * into a specific app's search from global search.
+ *
+ * In addition to the columns below, the suggestion columns are used to pass along the full
+ * suggestion so it can be shortcutted.
+ *
+ * @hide
+ */
+ public final static String SEARCH_CLICK_REPORT_AUTHORITY =
+ "com.android.globalsearch.stats";
+
+ /**
+ * The path the write goes to.
+ *
+ * @hide
+ */
+ public final static String SEARCH_CLICK_REPORT_URI_PATH = "click";
+
+ /**
+ * The column storing the query for the click.
+ *
+ * @hide
+ */
+ public final static String SEARCH_CLICK_REPORT_COLUMN_QUERY = "query";
+
+ /**
+ * The column storing the component name of the application that was pivoted into.
+ *
+ * @hide
+ */
+ public final static String SEARCH_CLICK_REPORT_COLUMN_COMPONENT = "component";
+
/**
* Column name for suggestions cursor. <i>Unused - can be null or column can be omitted.</i>
*/
@@ -1360,6 +1400,25 @@ public class SearchManager
public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
/**
+ * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify the
+ * cursor item's background color if it needs a non-default background color. A non-zero value
+ * indicates a valid background color to override the default.
+ *
+ * @hide For internal use, not part of the public API.
+ */
+ public final static String SUGGEST_COLUMN_BACKGROUND_COLOR = "suggest_background_color";
+
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
+ * that a spinner should be shown in lieu of an icon2 while the shortcut of this suggestion
+ * is being refreshed.
+ *
+ * @hide Pending API council approval.
+ */
+ public final static String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING =
+ "suggest_spinner_while_refreshing";
+
+ /**
* Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion
* should not be stored as a shortcut in global search.
*
@@ -1440,12 +1499,14 @@ public class SearchManager
private static ISearchManager sService = getSearchManagerService();
private final Context mContext;
- private final Handler mHandler;
-
- private SearchDialog mSearchDialog;
-
- private OnDismissListener mDismissListener = null;
- private OnCancelListener mCancelListener = null;
+
+ // package private since they are used by the inner class SearchManagerCallback
+ /* package */ boolean mIsShowing = false;
+ /* package */ final Handler mHandler;
+ /* package */ OnDismissListener mDismissListener = null;
+ /* package */ OnCancelListener mCancelListener = null;
+
+ private final SearchManagerCallback mSearchManagerCallback = new SearchManagerCallback();
/*package*/ SearchManager(Context context, Handler handler) {
mContext = context;
@@ -1497,17 +1558,16 @@ public class SearchManager
ComponentName launchActivity,
Bundle appSearchData,
boolean globalSearch) {
-
- if (mSearchDialog == null) {
- mSearchDialog = new SearchDialog(mContext);
+ if (DBG) debug("startSearch(), mIsShowing=" + mIsShowing);
+ if (mIsShowing) return;
+ try {
+ mIsShowing = true;
+ // activate the search manager and start it up!
+ sService.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData,
+ globalSearch, mSearchManagerCallback);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "startSearch() failed: " + ex);
}
-
- // activate the search manager and start it up!
- mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
- globalSearch);
-
- mSearchDialog.setOnCancelListener(this);
- mSearchDialog.setOnDismissListener(this);
}
/**
@@ -1521,9 +1581,16 @@ public class SearchManager
*
* @see #startSearch
*/
- public void stopSearch() {
- if (mSearchDialog != null) {
- mSearchDialog.cancel();
+ public void stopSearch() {
+ if (DBG) debug("stopSearch(), mIsShowing=" + mIsShowing);
+ if (!mIsShowing) return;
+ try {
+ sService.stopSearch();
+ // onDismiss will also clear this, but we do it here too since onDismiss() is
+ // called asynchronously.
+ mIsShowing = false;
+ } catch (RemoteException ex) {
+ Log.e(TAG, "stopSearch() failed: " + ex);
}
}
@@ -1536,13 +1603,11 @@ public class SearchManager
*
* @hide
*/
- public boolean isVisible() {
- if (mSearchDialog != null) {
- return mSearchDialog.isShowing();
- }
- return false;
+ public boolean isVisible() {
+ if (DBG) debug("isVisible(), mIsShowing=" + mIsShowing);
+ return mIsShowing;
}
-
+
/**
* See {@link SearchManager#setOnDismissListener} for configuring your activity to monitor
* search UI state.
@@ -1577,79 +1642,112 @@ public class SearchManager
public void setOnDismissListener(final OnDismissListener listener) {
mDismissListener = listener;
}
-
- /**
- * The callback from the search dialog when dismissed
- * @hide
- */
- public void onDismiss(DialogInterface dialog) {
- if (dialog == mSearchDialog) {
- if (mDismissListener != null) {
- mDismissListener.onDismiss();
- }
- }
- }
/**
* Set or clear the callback that will be invoked whenever the search UI is canceled.
*
* @param listener The {@link OnCancelListener} to use, or null.
*/
- public void setOnCancelListener(final OnCancelListener listener) {
+ public void setOnCancelListener(OnCancelListener listener) {
mCancelListener = listener;
}
-
-
- /**
- * The callback from the search dialog when canceled
- * @hide
- */
- public void onCancel(DialogInterface dialog) {
- if (dialog == mSearchDialog) {
- if (mCancelListener != null) {
- mCancelListener.onCancel();
+
+ private class SearchManagerCallback extends ISearchManagerCallback.Stub {
+
+ private final Runnable mFireOnDismiss = new Runnable() {
+ public void run() {
+ if (DBG) debug("mFireOnDismiss");
+ mIsShowing = false;
+ if (mDismissListener != null) {
+ mDismissListener.onDismiss();
+ }
+ }
+ };
+
+ private final Runnable mFireOnCancel = new Runnable() {
+ public void run() {
+ if (DBG) debug("mFireOnCancel");
+ // doesn't need to clear mIsShowing since onDismiss() always gets called too
+ if (mCancelListener != null) {
+ mCancelListener.onCancel();
+ }
}
+ };
+
+ public void onDismiss() {
+ if (DBG) debug("onDismiss()");
+ mHandler.post(mFireOnDismiss);
}
+
+ public void onCancel() {
+ if (DBG) debug("onCancel()");
+ mHandler.post(mFireOnCancel);
+ }
+
+ }
+
+ // TODO: remove the DialogInterface interfaces from SearchManager.
+ // This changes the public API, so I'll do it in a separate change.
+ public void onCancel(DialogInterface dialog) {
+ throw new UnsupportedOperationException();
+ }
+ public void onDismiss(DialogInterface dialog) {
+ throw new UnsupportedOperationException();
}
/**
- * Save instance state so we can recreate after a rotation.
- *
+ * Saves the state of the search UI.
+ *
+ * @return A Bundle containing the state of the search dialog, or {@code null}
+ * if the search UI is not visible.
+ *
* @hide
*/
- void saveSearchDialog(Bundle outState, String key) {
- if (mSearchDialog != null && mSearchDialog.isShowing()) {
- Bundle searchDialogState = mSearchDialog.onSaveInstanceState();
- outState.putBundle(key, searchDialogState);
+ public Bundle saveSearchDialog() {
+ if (DBG) debug("saveSearchDialog(), mIsShowing=" + mIsShowing);
+ if (!mIsShowing) return null;
+ try {
+ return sService.onSaveInstanceState();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "onSaveInstanceState() failed: " + ex);
+ return null;
}
}
/**
- * Restore instance state after a rotation.
- *
+ * Restores the state of the search dialog.
+ *
+ * @param searchDialogState Bundle to read the state from.
+ *
* @hide
*/
- void restoreSearchDialog(Bundle inState, String key) {
- Bundle searchDialogState = inState.getBundle(key);
- if (searchDialogState != null) {
- if (mSearchDialog == null) {
- mSearchDialog = new SearchDialog(mContext);
- }
- mSearchDialog.onRestoreInstanceState(searchDialogState);
+ public void restoreSearchDialog(Bundle searchDialogState) {
+ if (DBG) debug("restoreSearchDialog(" + searchDialogState + ")");
+ if (searchDialogState == null) return;
+ try {
+ sService.onRestoreInstanceState(searchDialogState);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "onRestoreInstanceState() failed: " + ex);
}
}
-
+
/**
- * Hook for updating layout on a rotation
- *
+ * Update the search dialog after a configuration change.
+ *
+ * @param newConfig The new configuration.
+ *
* @hide
*/
- void onConfigurationChanged(Configuration newConfig) {
- if (mSearchDialog != null && mSearchDialog.isShowing()) {
- mSearchDialog.onConfigurationChanged(newConfig);
+ public void onConfigurationChanged(Configuration newConfig) {
+ if (DBG) debug("onConfigurationChanged(" + newConfig + "), mIsShowing=" + mIsShowing);
+ if (!mIsShowing) return;
+ try {
+ sService.onConfigurationChanged(newConfig);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "onConfigurationChanged() failed:" + ex);
}
}
-
+
private static ISearchManager getSearchManagerService() {
return ISearchManager.Stub.asInterface(
ServiceManager.getService(Context.SEARCH_SERVICE));
@@ -1670,7 +1768,8 @@ public class SearchManager
boolean globalSearch) {
try {
return sService.getSearchableInfo(componentName, globalSearch);
- } catch (RemoteException e) {
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getSearchableInfo() failed: " + ex);
return null;
}
}
@@ -1751,6 +1850,7 @@ public class SearchManager
try {
return sService.getSearchablesInGlobalSearch();
} catch (RemoteException e) {
+ Log.e(TAG, "getSearchablesInGlobalSearch() failed: " + e);
return null;
}
}
@@ -1758,7 +1858,8 @@ public class SearchManager
/**
* Returns a list of the searchable activities that handle web searches.
*
- * @return a a list of all searchable activities that handle {@link SearchManager#ACTION_WEB_SEARCH}.
+ * @return a list of all searchable activities that handle
+ * {@link android.content.Intent#ACTION_WEB_SEARCH}.
*
* @hide because SearchableInfo is not part of the API.
*/
@@ -1766,6 +1867,7 @@ public class SearchManager
try {
return sService.getSearchablesForWebSearch();
} catch (RemoteException e) {
+ Log.e(TAG, "getSearchablesForWebSearch() failed: " + e);
return null;
}
}
@@ -1781,6 +1883,7 @@ public class SearchManager
try {
return sService.getDefaultSearchableForWebSearch();
} catch (RemoteException e) {
+ Log.e(TAG, "getDefaultSearchableForWebSearch() failed: " + e);
return null;
}
}
@@ -1796,6 +1899,12 @@ public class SearchManager
try {
sService.setDefaultWebSearch(component);
} catch (RemoteException e) {
+ Log.e(TAG, "setDefaultWebSearch() failed: " + e);
}
}
+
+ private static void debug(String msg) {
+ Thread thread = Thread.currentThread();
+ Log.d(TAG, msg + " (" + thread.getName() + "-" + thread.getId() + ")");
+ }
}
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index e515594..ed76f4e 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -20,15 +20,19 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
+import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.server.search.SearchableInfo;
import android.text.Html;
import android.text.TextUtils;
+import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
@@ -42,26 +46,27 @@ import java.util.WeakHashMap;
/**
* Provides the contents for the suggestion drop-down list.in {@link SearchDialog}.
- *
+ *
* @hide
*/
class SuggestionsAdapter extends ResourceCursorAdapter {
private static final boolean DBG = false;
private static final String LOG_TAG = "SuggestionsAdapter";
-
+
private SearchDialog mSearchDialog;
private SearchableInfo mSearchable;
private Context mProviderContext;
private WeakHashMap<String, Drawable> mOutsideDrawablesCache;
private boolean mGlobalSearchMode;
- // Cached column indexes, updated when the cursor changes.
+ // Cached column indexes, updated when the cursor changes.
private int mFormatCol;
private int mText1Col;
private int mText2Col;
private int mIconName1Col;
private int mIconName2Col;
+ private int mBackgroundColorCol;
// This value is stored in SuggestionsAdapter by the SearchDialog to indicate whether
// a particular list item should be selected upon the next call to notifyDataSetChanged.
@@ -78,6 +83,9 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
// holds the position that, when displayed, should result in notifying the cursor
int mDisplayNotifyPos = NONE;
+ private final Runnable mStartSpinnerRunnable;
+ private final Runnable mStopSpinnerRunnable;
+
public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable,
WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) {
super(context,
@@ -86,15 +94,27 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
true); // auto-requery
mSearchDialog = searchDialog;
mSearchable = searchable;
-
+
// set up provider resources (gives us icons, etc.)
Context activityContext = mSearchable.getActivityContext(mContext);
mProviderContext = mSearchable.getProviderContext(mContext, activityContext);
-
+
mOutsideDrawablesCache = outsideDrawablesCache;
mGlobalSearchMode = globalSearchMode;
+
+ mStartSpinnerRunnable = new Runnable() {
+ public void run() {
+ mSearchDialog.setWorking(true);
+ }
+ };
+
+ mStopSpinnerRunnable = new Runnable() {
+ public void run() {
+ mSearchDialog.setWorking(false);
+ }
+ };
}
-
+
/**
* Overridden to always return <code>false</code>, since we cannot be sure that
* suggestion sources return stable IDs.
@@ -113,14 +133,30 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (DBG) Log.d(LOG_TAG, "runQueryOnBackgroundThread(" + constraint + ")");
String query = (constraint == null) ? "" : constraint.toString();
+ if (!mGlobalSearchMode) {
+ /**
+ * for in app search we show the progress spinner until the cursor is returned with
+ * the results. for global search we manage the progress bar using
+ * {@link DialogCursorProtocol#POST_REFRESH_RECEIVE_ISPENDING}.
+ */
+ mSearchDialog.getWindow().getDecorView().post(mStartSpinnerRunnable);
+ }
try {
- return SearchManager.getSuggestions(mContext, mSearchable, query);
+ final Cursor cursor = SearchManager.getSuggestions(mContext, mSearchable, query);
+ // trigger fill window so the spinner stays up until the results are copied over and
+ // closer to being ready
+ if (!mGlobalSearchMode) cursor.getCount();
+ return cursor;
} catch (RuntimeException e) {
Log.w(LOG_TAG, "Search suggestions query threw an exception.", e);
return null;
+ } finally {
+ if (!mGlobalSearchMode) {
+ mSearchDialog.getWindow().getDecorView().post(mStopSpinnerRunnable);
+ }
}
}
-
+
/**
* Cache columns.
*/
@@ -139,6 +175,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
mText2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2);
mIconName1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
mIconName2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2);
+ mBackgroundColorCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_BACKGROUND_COLOR);
}
}
@@ -175,7 +212,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
/**
* Handle sending and receiving information associated with
* {@link DialogCursorProtocol#POST_REFRESH}.
- *
+ *
* @param cursor The cursor to call.
*/
private void callCursorPostRefresh(Cursor cursor) {
@@ -213,7 +250,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View v = super.newView(context, cursor, parent);
+ View v = new SuggestionItemView(context, cursor);
v.setTag(new ChildViewCache(v));
return v;
}
@@ -227,7 +264,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
public final TextView mText2;
public final ImageView mIcon1;
public final ImageView mIcon2;
-
+
public ChildViewCache(View v) {
mText1 = (TextView) v.findViewById(com.android.internal.R.id.text1);
mText2 = (TextView) v.findViewById(com.android.internal.R.id.text2);
@@ -235,7 +272,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
mIcon2 = (ImageView) v.findViewById(com.android.internal.R.id.icon2);
}
}
-
+
@Override
public void bindView(View view, Context context, Cursor cursor) {
ChildViewCache views = (ChildViewCache) view.getTag();
@@ -254,13 +291,19 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
mDisplayNotifyPos = NONE; // only notify the first time
}
+ int backgroundColor = 0;
+ if (mBackgroundColorCol != -1) {
+ backgroundColor = cursor.getInt(mBackgroundColorCol);
+ }
+ ((SuggestionItemView)view).setColor(backgroundColor);
+
final boolean isHtml = mFormatCol > 0 && "html".equals(cursor.getString(mFormatCol));
setViewText(cursor, views.mText1, mText1Col, isHtml);
setViewText(cursor, views.mText2, mText2Col, isHtml);
setViewIcon(cursor, views.mIcon1, mIconName1Col);
setViewIcon(cursor, views.mIcon2, mIconName2Col);
}
-
+
private void setViewText(Cursor cursor, TextView v, int textCol, boolean isHtml) {
if (v == null) {
return;
@@ -272,14 +315,14 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
}
// Set the text even if it's null, since we need to clear any previous text.
v.setText(text);
-
+
if (TextUtils.isEmpty(text)) {
v.setVisibility(View.GONE);
} else {
v.setVisibility(View.VISIBLE);
}
}
-
+
private void setViewIcon(Cursor cursor, ImageView v, int iconNameCol) {
if (v == null) {
return;
@@ -292,12 +335,12 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
// Set the icon even if the drawable is null, since we need to clear any
// previous icon.
v.setImageDrawable(drawable);
-
+
if (drawable == null) {
v.setVisibility(View.GONE);
} else {
v.setVisibility(View.VISIBLE);
-
+
// This is a hack to get any animated drawables (like a 'working' spinner)
// to animate. You have to setVisible true on an AnimationDrawable to get
// it to start animating, but it must first have been false or else the
@@ -307,11 +350,11 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
drawable.setVisible(true, false);
}
}
-
+
/**
* Gets the text to show in the query field when a suggestion is selected.
- *
- * @param cursor The Cursor to read the suggestion data from. The Cursor should already
+ *
+ * @param cursor The Cursor to read the suggestion data from. The Cursor should already
* be moved to the suggestion that is to be read from.
* @return The text to show, or <code>null</code> if the query should not be
* changed when selecting this suggestion.
@@ -321,36 +364,36 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
if (cursor == null) {
return null;
}
-
+
String query = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_QUERY);
if (query != null) {
return query;
}
-
+
if (mSearchable.shouldRewriteQueryFromData()) {
String data = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_INTENT_DATA);
if (data != null) {
return data;
}
}
-
+
if (mSearchable.shouldRewriteQueryFromText()) {
String text1 = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_TEXT_1);
if (text1 != null) {
return text1;
}
}
-
+
return null;
}
-
+
/**
* This method is overridden purely to provide a bit of protection against
* flaky content providers.
- *
+ *
* @see android.widget.ListAdapter#getView(int, View, ViewGroup)
*/
- @Override
+ @Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
return super.getView(position, convertView, parent);
@@ -359,28 +402,28 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
// Put exception string in item title
View v = newView(mContext, mCursor, parent);
if (v != null) {
- ChildViewCache views = (ChildViewCache) v.getTag();
+ ChildViewCache views = (ChildViewCache) v.getTag();
TextView tv = views.mText1;
tv.setText(e.toString());
}
return v;
}
}
-
+
/**
* Gets a drawable given a value provided by a suggestion provider.
- *
+ *
* This value could be just the string value of a resource id
* (e.g., "2130837524"), in which case we will try to retrieve a drawable from
* the provider's resources. If the value is not an integer, it is
- * treated as a Uri and opened with
+ * treated as a Uri and opened with
* {@link ContentResolver#openOutputStream(android.net.Uri, String)}.
*
* All resources and URIs are read using the suggestion provider's context.
*
* If the string is not formatted as expected, or no drawable can be found for
* the provided value, this method returns null.
- *
+ *
* @param drawableId a string like "2130837524",
* "android.resource://com.android.alarmclock/2130837524",
* or "content://contacts/photos/253".
@@ -390,7 +433,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
if (drawableId == null || drawableId.length() == 0 || "0".equals(drawableId)) {
return null;
}
-
+
// First, check the cache.
Drawable drawable = mOutsideDrawablesCache.get(drawableId);
if (drawable != null) {
@@ -425,7 +468,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
if (DBG) Log.d(LOG_TAG, "Icon stream not found: " + drawableId);
// drawable = null;
}
-
+
// If we got a drawable for this resource id, then stick it in the
// map so we don't do this lookup again.
if (drawable != null) {
@@ -435,13 +478,13 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
if (DBG) Log.d(LOG_TAG, "Icon resource not found: " + drawableId);
// drawable = null;
}
-
+
return drawable;
}
-
+
/**
* Gets the value of a string column by name.
- *
+ *
* @param cursor Cursor to read the value from.
* @param columnName The name of the column to read.
* @return The value of the given column, or <code>null</null>
@@ -455,4 +498,69 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
return cursor.getString(col);
}
+ /**
+ * A parent viewgroup class which holds the actual suggestion item as a child.
+ *
+ * The sole purpose of this class is to draw the given background color when the item is in
+ * normal state and not draw the background color when it is pressed, so that when pressed the
+ * list view's selection highlight will be displayed properly (if we draw our background it
+ * draws on top of the list view selection highlight).
+ */
+ private class SuggestionItemView extends ViewGroup {
+ private int mBackgroundColor; // the background color to draw in normal state.
+ private View mView; // the suggestion item's view.
+
+ protected SuggestionItemView(Context context, Cursor cursor) {
+ // Initialize ourselves
+ super(context);
+ mBackgroundColor = 0; // transparent by default.
+
+ // For our layout use the default list item height from the current theme.
+ TypedValue lineHeight = new TypedValue();
+ context.getTheme().resolveAttribute(
+ com.android.internal.R.attr.searchResultListItemHeight, lineHeight, true);
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setToDefaults();
+ AbsListView.LayoutParams layout = new AbsListView.LayoutParams(
+ AbsListView.LayoutParams.FILL_PARENT,
+ (int)lineHeight.getDimension(metrics));
+
+ setLayoutParams(layout);
+
+ // Initialize the child view
+ mView = SuggestionsAdapter.super.newView(context, cursor, this);
+ if (mView != null) {
+ addView(mView, layout.width, layout.height);
+ mView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void setColor(int backgroundColor) {
+ mBackgroundColor = backgroundColor;
+ }
+
+ @Override
+ public void dispatchDraw(Canvas canvas) {
+ if (mBackgroundColor != 0 && !isPressed() && !isSelected()) {
+ canvas.drawColor(mBackgroundColor);
+ }
+ super.dispatchDraw(canvas);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (mView != null) {
+ mView.measure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (mView != null) {
+ mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
+ }
+ }
+ }
+
}
diff --git a/core/java/android/backup/BackupDataInput.java b/core/java/android/backup/BackupDataInput.java
new file mode 100644
index 0000000..609dd90
--- /dev/null
+++ b/core/java/android/backup/BackupDataInput.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+import android.content.Context;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/** @hide */
+public class BackupDataInput {
+ int mBackupReader;
+
+ private EntityHeader mHeader = new EntityHeader();
+ private boolean mHeaderReady;
+
+ private static class EntityHeader {
+ String key;
+ int dataSize;
+ }
+
+ public BackupDataInput(FileDescriptor fd) {
+ if (fd == null) throw new NullPointerException();
+ mBackupReader = ctor(fd);
+ if (mBackupReader == 0) {
+ throw new RuntimeException("Native initialization failed with fd=" + fd);
+ }
+ }
+
+ protected void finalize() throws Throwable {
+ try {
+ dtor(mBackupReader);
+ } finally {
+ super.finalize();
+ }
+ }
+
+ public boolean readNextHeader() throws IOException {
+ int result = readNextHeader_native(mBackupReader, mHeader);
+ if (result == 0) {
+ // read successfully
+ mHeaderReady = true;
+ return true;
+ } else if (result > 0) {
+ // done
+ mHeaderReady = false;
+ return false;
+ } else {
+ // error
+ mHeaderReady = false;
+ throw new IOException("result=0x" + Integer.toHexString(result));
+ }
+ }
+
+ public String getKey() {
+ if (mHeaderReady) {
+ return mHeader.key;
+ } else {
+ throw new IllegalStateException("mHeaderReady=false");
+ }
+ }
+
+ public int getDataSize() {
+ if (mHeaderReady) {
+ return mHeader.dataSize;
+ } else {
+ throw new IllegalStateException("mHeaderReady=false");
+ }
+ }
+
+ public int readEntityData(byte[] data, int size) throws IOException {
+ if (mHeaderReady) {
+ int result = readEntityData_native(mBackupReader, data, size);
+ if (result >= 0) {
+ return result;
+ } else {
+ throw new IOException("result=0x" + Integer.toHexString(result));
+ }
+ } else {
+ throw new IllegalStateException("mHeaderReady=false");
+ }
+ }
+
+ private native static int ctor(FileDescriptor fd);
+ private native static void dtor(int mBackupReader);
+
+ private native int readNextHeader_native(int mBackupReader, EntityHeader entity);
+ private native int readEntityData_native(int mBackupReader, byte[] data, int size);
+}
diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java
index 25ae15b..1348d81 100644
--- a/core/java/android/backup/BackupDataOutput.java
+++ b/core/java/android/backup/BackupDataOutput.java
@@ -19,6 +19,7 @@ package android.backup;
import android.content.Context;
import java.io.FileDescriptor;
+import java.io.IOException;
/** @hide */
public class BackupDataOutput {
@@ -37,6 +38,24 @@ public class BackupDataOutput {
}
}
+ public int writeEntityHeader(String key, int dataSize) throws IOException {
+ int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
+ if (result >= 0) {
+ return result;
+ } else {
+ throw new IOException("result=0x" + Integer.toHexString(result));
+ }
+ }
+
+ public int writeEntityData(byte[] data, int size) throws IOException {
+ int result = writeEntityData_native(mBackupWriter, data, size);
+ if (result >= 0) {
+ return result;
+ } else {
+ throw new IOException("result=0x" + Integer.toHexString(result));
+ }
+ }
+
protected void finalize() throws Throwable {
try {
dtor(mBackupWriter);
@@ -47,5 +66,8 @@ public class BackupDataOutput {
private native static int ctor(FileDescriptor fd);
private native static void dtor(int mBackupWriter);
+
+ private native static int writeEntityHeader_native(int mBackupWriter, String key, int dataSize);
+ private native static int writeEntityData_native(int mBackupWriter, byte[] data, int size);
}
diff --git a/core/java/android/backup/BackupManager.java b/core/java/android/backup/BackupManager.java
index 30f781e..8df7eae 100644
--- a/core/java/android/backup/BackupManager.java
+++ b/core/java/android/backup/BackupManager.java
@@ -32,8 +32,9 @@ import android.os.ServiceManager;
* until the backup operation actually occurs.
*
* <p>The backup operation itself begins with the system launching the
- * {@link BackupService} subclass declared in your manifest. See the documentation
- * for {@link BackupService} for a detailed description of how the backup then proceeds.
+ * {@link android.app.BackupAgent} subclass declared in your manifest. See the
+ * documentation for {@link android.app.BackupAgent} for a detailed description
+ * of how the backup then proceeds.
*
* @hide pending API solidification
*/
@@ -44,7 +45,7 @@ public class BackupManager {
/**
* Defined backup transports understood by {@link IBackupManager.selectBackupTransport}.
*/
- public static final int TRANSPORT_ADB = 1;
+ public static final int TRANSPORT_LOCAL = 1;
public static final int TRANSPORT_GOOGLE = 2;
/**
@@ -64,7 +65,7 @@ public class BackupManager {
/**
* Notifies the Android backup system that your application wishes to back up
* new changes to its data. A backup operation using your application's
- * {@link BackupService} subclass will be scheduled when you call this method.
+ * {@link android.app.BackupAgent} subclass will be scheduled when you call this method.
*/
public void dataChanged() {
try {
@@ -72,4 +73,20 @@ public class BackupManager {
} catch (RemoteException e) {
}
}
+
+ /**
+ * Begin the process of restoring system data from backup. This method requires
+ * that the application hold the "android.permission.BACKUP" permission, and is
+ * not public.
+ *
+ * {@hide}
+ */
+ public IRestoreSession beginRestoreSession(int transportID) {
+ IRestoreSession binder = null;
+ try {
+ binder = mService.beginRestoreSession(transportID);
+ } catch (RemoteException e) {
+ }
+ return binder;
+ }
}
diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java
index ec16eb1..ed840bb 100644
--- a/core/java/android/backup/FileBackupHelper.java
+++ b/core/java/android/backup/FileBackupHelper.java
@@ -20,36 +20,84 @@ import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
+import java.io.File;
import java.io.FileDescriptor;
/** @hide */
public class FileBackupHelper {
private static final String TAG = "FileBackupHelper";
+ Context mContext;
+ String mKeyPrefix;
+
+ public FileBackupHelper(Context context) {
+ mContext = context;
+ }
+
+ public FileBackupHelper(Context context, String keyPrefix) {
+ mContext = context;
+ mKeyPrefix = keyPrefix;
+ }
+
/**
* Based on oldState, determine which of the files from the application's data directory
* need to be backed up, write them to the data stream, and fill in newState with the
* state as it exists now.
*/
- public static void performBackup(Context context,
- ParcelFileDescriptor oldState, BackupDataOutput data,
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState, String[] files) {
- String basePath = context.getFilesDir().getAbsolutePath();
- performBackup_checked(basePath, oldState, data, newState, files);
+ // file names
+ File base = mContext.getFilesDir();
+ final int N = files.length;
+ String[] fullPaths = new String[N];
+ for (int i=0; i<N; i++) {
+ fullPaths[i] = (new File(base, files[i])).getAbsolutePath();
+ }
+
+ // keys
+ String[] keys = makeKeys(mKeyPrefix, files);
+
+ // go
+ performBackup_checked(oldState, data, newState, fullPaths, keys);
+ }
+
+ /**
+ * If keyPrefix is not null, prepend it to each of the strings in <code>original</code>;
+ * otherwise, return original.
+ */
+ static String[] makeKeys(String keyPrefix, String[] original) {
+ if (keyPrefix != null) {
+ String[] keys;
+ final int N = original.length;
+ keys = new String[N];
+ for (int i=0; i<N; i++) {
+ keys[i] = keyPrefix + ':' + original[i];
+ }
+ return keys;
+ } else {
+ return original;
+ }
}
/**
* Check the parameters so the native code doens't have to throw all the exceptions
* since it's easier to do that from java.
*/
- static void performBackup_checked(String basePath,
- ParcelFileDescriptor oldState, BackupDataOutput data,
- ParcelFileDescriptor newState, String[] files) {
+ static void performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState, String[] files, String[] keys) {
if (files.length == 0) {
return;
}
- if (basePath == null) {
- throw new NullPointerException();
+ // files must be all absolute paths
+ for (String f: files) {
+ if (f.charAt(0) != '/') {
+ throw new RuntimeException("files must have all absolute paths: " + f);
+ }
+ }
+ // the length of files and keys must be the same
+ if (files.length != keys.length) {
+ throw new RuntimeException("files.length=" + files.length
+ + " keys.length=" + keys.length);
}
// oldStateFd can be null
FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null;
@@ -58,13 +106,14 @@ public class FileBackupHelper {
throw new NullPointerException();
}
- int err = performBackup_native(basePath, oldStateFd, data.mBackupWriter, newStateFd, files);
+ int err = performBackup_native(oldStateFd, data.mBackupWriter, newStateFd, files, keys);
if (err != 0) {
- throw new RuntimeException("Backup failed"); // TODO: more here
+ // TODO: more here
+ throw new RuntimeException("Backup failed 0x" + Integer.toHexString(err));
}
}
- native private static int performBackup_native(String basePath, FileDescriptor oldState,
- int data, FileDescriptor newState, String[] files);
+ native private static int performBackup_native(FileDescriptor oldState,
+ int data, FileDescriptor newState, String[] files, String[] keys);
}
diff --git a/core/java/android/backup/IBackupManager.aidl b/core/java/android/backup/IBackupManager.aidl
index f5b82fe..efc664c 100644
--- a/core/java/android/backup/IBackupManager.aidl
+++ b/core/java/android/backup/IBackupManager.aidl
@@ -16,6 +16,8 @@
package android.backup;
+import android.backup.IRestoreSession;
+
/**
* Direct interface to the Backup Manager Service that applications invoke on. The only
* operation currently needed is a simple notification that the app has made changes to
@@ -46,10 +48,22 @@ interface IBackupManager {
oneway void agentDisconnected(String packageName);
/**
- * Schedule a full backup of the given package. Callers must hold the
+ * Schedule an immediate backup attempt for all pending updates. This is
+ * primarily intended for transports to use when they detect a suitable
+ * opportunity for doing a backup pass. If there are no pending updates to
+ * be sent, no action will be taken. Even if some updates are pending, the
+ * transport will still be asked to confirm via the usual requestBackupTime()
+ * method.
+ *
+ * <p>Callers must hold the android.permission.BACKUP permission to use this method.
+ */
+ oneway void backupNow();
+
+ /**
+ * Identify the currently selected transport. Callers must hold the
* android.permission.BACKUP permission to use this method.
*/
- oneway void scheduleFullBackup(String packageName);
+ int getCurrentTransport();
/**
* Specify a default backup transport. Callers must hold the
@@ -60,4 +74,12 @@ interface IBackupManager {
* @return The ID of the previously selected transport.
*/
int selectBackupTransport(int transportID);
+
+ /**
+ * Begin a restore session with the given transport (which may differ from the
+ * currently-active backup transport).
+ *
+ * @return An interface to the restore session, or null on error.
+ */
+ IRestoreSession beginRestoreSession(int transportID);
}
diff --git a/core/java/android/backup/IRestoreSession.aidl b/core/java/android/backup/IRestoreSession.aidl
new file mode 100644
index 0000000..6bca865
--- /dev/null
+++ b/core/java/android/backup/IRestoreSession.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+import android.backup.RestoreSet;
+
+/**
+ * Binder interface used by clients who wish to manage a restore operation. Every
+ * method in this interface requires the android.permission.BACKUP permission.
+ *
+ * {@hide}
+ */
+interface IRestoreSession {
+ /**
+ * Ask the current transport what the available restore sets are.
+ *
+ * @return A bundle containing two elements: an int array under the key
+ * "tokens" whose entries are a transport-private identifier for each backup set;
+ * and a String array under the key "names" whose entries are the user-meaningful
+ * text corresponding to the backup sets at each index in the tokens array.
+ */
+ RestoreSet[] getAvailableRestoreSets();
+
+ /**
+ * Restore the given set onto the device, replacing the current data of any app
+ * contained in the restore set with the data previously backed up.
+ *
+ * @param token The token from {@link getAvailableRestoreSets()} corresponding to
+ * the restore set that should be used.
+ */
+ int performRestore(int token);
+
+ /**
+ * End this restore session. After this method is called, the IRestoreSession binder
+ * is no longer valid.
+ */
+ void endRestoreSession();
+}
diff --git a/core/java/android/backup/RestoreHelper.java b/core/java/android/backup/RestoreHelper.java
new file mode 100644
index 0000000..ebd9906
--- /dev/null
+++ b/core/java/android/backup/RestoreHelper.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+/** @hide */
+public interface RestoreHelper {
+ public void performRestore();
+}
+
diff --git a/core/java/android/backup/RestoreHelperDistributor.java b/core/java/android/backup/RestoreHelperDistributor.java
new file mode 100644
index 0000000..555ca79
--- /dev/null
+++ b/core/java/android/backup/RestoreHelperDistributor.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+import java.util.HashMap;
+
+/** @hide */
+public class RestoreHelperDistributor {
+ HashMap<String,RestoreHelper> mHelpers;
+
+ public void addHelper(String keyPrefix, RestoreHelper helper) {
+ mHelpers.put(keyPrefix, helper);
+ }
+}
diff --git a/core/java/android/backup/RestoreSet.aidl b/core/java/android/backup/RestoreSet.aidl
new file mode 100644
index 0000000..42e77bf
--- /dev/null
+++ b/core/java/android/backup/RestoreSet.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+parcelable RestoreSet; \ No newline at end of file
diff --git a/core/java/android/backup/RestoreSet.java b/core/java/android/backup/RestoreSet.java
new file mode 100644
index 0000000..7f09af3
--- /dev/null
+++ b/core/java/android/backup/RestoreSet.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Descriptive information about a set of backed-up app data available for restore.
+ * Used by IRestoreSession clients.
+ *
+ * @hide
+ */
+public class RestoreSet implements Parcelable {
+ /**
+ * Name of this restore set. May be user generated, may simply be the name
+ * of the handset model, e.g. "T-Mobile G1".
+ */
+ public String name;
+
+ /**
+ * Identifier of the device whose data this is. This will be as unique as
+ * is practically possible; for example, it might be an IMEI.
+ */
+ public String device;
+
+ /**
+ * Token that identifies this backup set unambiguously to the backup/restore
+ * transport. This is guaranteed to be valid for the duration of a restore
+ * session, but is meaningless once the session has ended.
+ */
+ public int token;
+
+
+ RestoreSet() {
+ // Leave everything zero / null
+ }
+
+ RestoreSet(String _name, String _dev, int _token) {
+ name = _name;
+ device = _dev;
+ token = _token;
+ }
+
+
+ // Parcelable implementation
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(name);
+ out.writeString(device);
+ out.writeInt(token);
+ }
+
+ public static final Parcelable.Creator<RestoreSet> CREATOR
+ = new Parcelable.Creator<RestoreSet>() {
+ public RestoreSet createFromParcel(Parcel in) {
+ return new RestoreSet(in);
+ }
+
+ public RestoreSet[] newArray(int size) {
+ return new RestoreSet[size];
+ }
+ };
+
+ private RestoreSet(Parcel in) {
+ name = in.readString();
+ device = in.readString();
+ token = in.readInt();
+ }
+} \ No newline at end of file
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index 8627f08..cad79df 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -23,19 +23,34 @@ import java.io.FileDescriptor;
/** @hide */
public class SharedPreferencesBackupHelper {
- public static void performBackup(Context context,
- ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
- BackupDataOutput data, String[] prefGroups) {
- String basePath = "/xxx"; //context.getPreferencesDir();
+ private Context mContext;
+ private String mKeyPrefix;
+
+ public SharedPreferencesBackupHelper(Context context) {
+ mContext = context;
+ }
+ public SharedPreferencesBackupHelper(Context context, String keyPrefix) {
+ mContext = context;
+ mKeyPrefix = keyPrefix;
+ }
+
+ public void performBackup(ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
+ BackupDataOutput data, String[] prefGroups) {
+ Context context = mContext;
+
// make filenames for the prefGroups
final int N = prefGroups.length;
String[] files = new String[N];
for (int i=0; i<N; i++) {
- files[i] = prefGroups[i] + ".xml";
+ files[i] = context.getSharedPrefsFile(prefGroups[i]).getAbsolutePath();
}
- FileBackupHelper.performBackup_checked(basePath, oldSnapshot, data, newSnapshot, files);
+ // make keys if necessary
+ String[] keys = FileBackupHelper.makeKeys(mKeyPrefix, prefGroups);
+
+ // go
+ FileBackupHelper.performBackup_checked(oldSnapshot, data, newSnapshot, files, prefGroups);
}
}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 951b4b0..c942a27 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -75,7 +75,7 @@ public class BluetoothDevice {
public static final int UNBOND_REASON_REMOVED = 6;
private static final String TAG = "BluetoothDevice";
-
+
private final IBluetoothDevice mService;
/**
* @hide - hide this because it takes a parameter of type
@@ -180,31 +180,6 @@ public class BluetoothDevice {
return false;
}
- public String getVersion() {
- try {
- return mService.getVersion();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String getRevision() {
- try {
- return mService.getRevision();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String getManufacturer() {
- try {
- return mService.getManufacturer();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String getCompany() {
- try {
- return mService.getCompany();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
-
/**
* Get the current scan mode.
* Used to determine if the local device is connectable and/or discoverable
@@ -241,11 +216,8 @@ public class BluetoothDevice {
}
public boolean startDiscovery() {
- return startDiscovery(true);
- }
- public boolean startDiscovery(boolean resolveNames) {
try {
- return mService.startDiscovery(resolveNames);
+ return mService.startDiscovery();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
@@ -263,88 +235,17 @@ public class BluetoothDevice {
return false;
}
- public boolean startPeriodicDiscovery() {
- try {
- return mService.startPeriodicDiscovery();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
- public boolean stopPeriodicDiscovery() {
- try {
- return mService.stopPeriodicDiscovery();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
- public boolean isPeriodicDiscovery() {
- try {
- return mService.isPeriodicDiscovery();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
-
- public String[] listRemoteDevices() {
- try {
- return mService.listRemoteDevices();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
-
- /**
- * List remote devices that have a low level (ACL) connection.
- *
- * RFCOMM, SDP and L2CAP are all built on ACL connections. Devices can have
- * an ACL connection even when not paired - this is common for SDP queries
- * or for in-progress pairing requests.
- *
- * In most cases you probably want to test if a higher level protocol is
- * connected, rather than testing ACL connections.
- *
- * @return bluetooth hardware addresses of remote devices with a current
- * ACL connection. Array size is 0 if no devices have a
- * connection. Null on error.
- */
- public String[] listAclConnections() {
- try {
- return mService.listAclConnections();
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
-
- /**
- * Check if a specified remote device has a low level (ACL) connection.
- *
- * RFCOMM, SDP and L2CAP are all built on ACL connections. Devices can have
- * an ACL connection even when not paired - this is common for SDP queries
- * or for in-progress pairing requests.
- *
- * In most cases you probably want to test if a higher level protocol is
- * connected, rather than testing ACL connections.
- *
- * @param address the Bluetooth hardware address you want to check.
- * @return true if there is an ACL connection, false otherwise and on
- * error.
- */
- public boolean isAclConnected(String address) {
- try {
- return mService.isAclConnected(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
-
/**
- * Perform a low level (ACL) disconnection of a remote device.
- *
- * This forcably disconnects the ACL layer connection to a remote device,
- * which will cause all RFCOMM, SDP and L2CAP connections to this remote
- * device to close.
+ * Removes the remote device and the pairing information associated
+ * with it.
*
* @param address the Bluetooth hardware address you want to disconnect.
* @return true if the device was disconnected, false otherwise and on
* error.
*/
- public boolean disconnectRemoteDeviceAcl(String address) {
+ public boolean removeBond(String address) {
try {
- return mService.disconnectRemoteDeviceAcl(address);
+ return mService.removeBond(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
@@ -377,16 +278,6 @@ public class BluetoothDevice {
}
/**
- * Remove an already exisiting bonding (delete the link key).
- */
- public boolean removeBond(String address) {
- try {
- return mService.removeBond(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
-
- /**
* List remote devices that are bonded (paired) to the local device.
*
* Bonding (pairing) is the process by which the user enters a pin code for
@@ -440,78 +331,25 @@ public class BluetoothDevice {
return null;
}
- public String getRemoteVersion(String address) {
- try {
- return mService.getRemoteVersion(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String getRemoteRevision(String address) {
- try {
- return mService.getRemoteRevision(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String getRemoteManufacturer(String address) {
- try {
- return mService.getRemoteManufacturer(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String getRemoteCompany(String address) {
- try {
- return mService.getRemoteCompany(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
-
- /**
- * Returns the RFCOMM channel associated with the 16-byte UUID on
- * the remote Bluetooth address.
- *
- * Performs a SDP ServiceSearchAttributeRequest transaction. The provided
- * uuid is verified in the returned record. If there was a problem, or the
- * specified uuid does not exist, -1 is returned.
- */
- public boolean getRemoteServiceChannel(String address, short uuid16,
- IBluetoothDeviceCallback callback) {
- try {
- return mService.getRemoteServiceChannel(address, uuid16, callback);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
-
- /**
- * Get the major, minor and servics classes of a remote device.
- * These classes are encoded as a 32-bit integer. See BluetoothClass.
- * @param address remote device
- * @return 32-bit class suitable for use with BluetoothClass, or
- * BluetoothClass.ERROR on error
- */
public int getRemoteClass(String address) {
try {
return mService.getRemoteClass(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
- return BluetoothClass.ERROR;
+ return BluetoothError.ERROR_IPC;
}
- public byte[] getRemoteFeatures(String address) {
+ public String[] getRemoteUuids(String address) {
try {
- return mService.getRemoteFeatures(address);
+ return mService.getRemoteUuids(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return null;
}
- public String lastSeen(String address) {
- try {
- return mService.lastSeen(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
- }
- public String lastUsed(String address) {
- try {
- return mService.lastUsed(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return null;
+
+ public int getRemoteServiceChannel(String address, String uuid) {
+ try {
+ return mService.getRemoteServiceChannel(address, uuid);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return BluetoothError.ERROR_IPC;
}
public boolean setPin(String address, byte[] pin) {
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
new file mode 100644
index 0000000..96b93f9
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import java.util.UUID;
+
+/**
+* Static helper methods and constants to decode the UUID of remote devices.
+* @hide
+*/
+public final class BluetoothUuid {
+
+ /* See Bluetooth Assigned Numbers document - SDP section, to get the values of UUIDs
+ * for the various services.
+ *
+ * The following 128 bit values are calculated as:
+ * uuid * 2^96 + BASE_UUID
+ */
+ public static final UUID AudioSink = UUID.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+ public static final UUID AudioSource = UUID.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+ public static final UUID AdvAudioDist = UUID.fromString("0000110D-0000-1000-8000-00805F9B34FB");
+ public static final UUID HSP = UUID.fromString("00001108-0000-1000-8000-00805F9B34FB");
+ public static final UUID HeadsetHS = UUID.fromString("00001131-0000-1000-8000-00805F9B34FB");
+ public static final UUID Handsfree = UUID.fromString("0000111e-0000-1000-8000-00805F9B34FB");
+ public static final UUID HandsfreeAudioGateway
+ = UUID.fromString("0000111f-0000-1000-8000-00805F9B34FB");
+
+ public static boolean isAudioSource(UUID uuid) {
+ return uuid.equals(AudioSource);
+ }
+
+ public static boolean isAudioSink(UUID uuid) {
+ return uuid.equals(AudioSink);
+ }
+
+ public static boolean isAdvAudioDist(UUID uuid) {
+ return uuid.equals(AdvAudioDist);
+ }
+
+ public static boolean isHandsfree(UUID uuid) {
+ return uuid.equals(Handsfree) || uuid.equals(HandsfreeAudioGateway);
+ }
+
+ public static boolean isHeadset(UUID uuid) {
+ return uuid.equals(HSP) || uuid.equals(HeadsetHS);
+ }
+}
+
diff --git a/core/java/android/bluetooth/IBluetoothDevice.aidl b/core/java/android/bluetooth/IBluetoothDevice.aidl
index 6cd792e..c249c81 100644
--- a/core/java/android/bluetooth/IBluetoothDevice.aidl
+++ b/core/java/android/bluetooth/IBluetoothDevice.aidl
@@ -16,8 +16,6 @@
package android.bluetooth;
-import android.bluetooth.IBluetoothDeviceCallback;
-
/**
* System private API for talking with the Bluetooth service.
*
@@ -33,10 +31,6 @@ interface IBluetoothDevice
String getAddress();
String getName();
boolean setName(in String name);
- String getVersion();
- String getRevision();
- String getManufacturer();
- String getCompany();
int getScanMode();
boolean setScanMode(int mode);
@@ -44,17 +38,9 @@ interface IBluetoothDevice
int getDiscoverableTimeout();
boolean setDiscoverableTimeout(int timeout);
- boolean startDiscovery(boolean resolveNames);
+ boolean startDiscovery();
boolean cancelDiscovery();
boolean isDiscovering();
- boolean startPeriodicDiscovery();
- boolean stopPeriodicDiscovery();
- boolean isPeriodicDiscovery();
- String[] listRemoteDevices();
-
- String[] listAclConnections();
- boolean isAclConnected(in String address);
- boolean disconnectRemoteDeviceAcl(in String address);
boolean createBond(in String address);
boolean cancelBondProcess(in String address);
@@ -63,15 +49,9 @@ interface IBluetoothDevice
int getBondState(in String address);
String getRemoteName(in String address);
- String getRemoteVersion(in String address);
- String getRemoteRevision(in String address);
int getRemoteClass(in String address);
- String getRemoteManufacturer(in String address);
- String getRemoteCompany(in String address);
- boolean getRemoteServiceChannel(in String address, int uuid16, in IBluetoothDeviceCallback callback);
- byte[] getRemoteFeatures(in String adddress);
- String lastSeen(in String address);
- String lastUsed(in String address);
+ String[] getRemoteUuids(in String address);
+ int getRemoteServiceChannel(in String address, String uuid);
boolean setPin(in String address, in byte[] pin);
boolean cancelPin(in String address);
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
index 8c9955a..3266c07 100644
--- a/core/java/android/content/AbstractTableMerger.java
+++ b/core/java/android/content/AbstractTableMerger.java
@@ -63,9 +63,11 @@ public abstract class AbstractTableMerger
_SYNC_ID +"=? and " + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?";
private static final String SELECT_BY_ID = BaseColumns._ID +"=?";
- private static final String SELECT_UNSYNCED = ""
- + _SYNC_DIRTY + " > 0 and ((" + _SYNC_ACCOUNT + "=? AND " + _SYNC_ACCOUNT_TYPE + "=?) "
- + "or " + _SYNC_ACCOUNT + " is null)";
+ private static final String SELECT_UNSYNCED =
+ "(" + _SYNC_ACCOUNT + " IS NULL OR ("
+ + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?)) and "
+ + "(" + _SYNC_ID + " IS NULL OR (" + _SYNC_DIRTY + " > 0 and "
+ + _SYNC_VERSION + " IS NOT NULL))";
public AbstractTableMerger(SQLiteDatabase database,
String table, Uri tableURL, String deletedTable,
@@ -365,26 +367,32 @@ public abstract class AbstractTableMerger
if (!TextUtils.isEmpty(localSyncID)) {
// An existing server item has changed
- boolean recordChanged = (localSyncVersion == null) ||
- !serverSyncVersion.equals(localSyncVersion);
- if (recordChanged) {
- if (localSyncDirty) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "remote record " + serverSyncId
- + " conflicts with local _sync_id " + localSyncID
- + ", local _id " + localRowId);
+ // If serverSyncVersion is null, there is no edit URL;
+ // server won't let this change be written.
+ // Just hold onto it, I guess, in case the server permissions
+ // change later.
+ if (serverSyncVersion != null) {
+ boolean recordChanged = (localSyncVersion == null) ||
+ !serverSyncVersion.equals(localSyncVersion);
+ if (recordChanged) {
+ if (localSyncDirty) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "remote record " + serverSyncId
+ + " conflicts with local _sync_id " + localSyncID
+ + ", local _id " + localRowId);
+ }
+ conflict = true;
+ } else {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG,
+ "remote record " +
+ serverSyncId +
+ " updates local _sync_id " +
+ localSyncID + ", local _id " +
+ localRowId);
+ }
+ update = true;
}
- conflict = true;
- } else {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG,
- "remote record " +
- serverSyncId +
- " updates local _sync_id " +
- localSyncID + ", local _id " +
- localRowId);
- }
- update = true;
}
}
} else {
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 001af16..8b0b6ab 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -369,6 +369,12 @@ public class ContentProviderOperation implements Parcelable {
/** Create a ContentProviderOperation from this {@link Builder}. */
public ContentProviderOperation build() {
+ if (mType == TYPE_UPDATE) {
+ if ((mValues == null || mValues.size() == 0)
+ && (mValuesBackReferences == null || mValuesBackReferences.size() == 0)) {
+ throw new IllegalArgumentException("Empty values");
+ }
+ }
return new ContentProviderOperation(this);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 64d8c63..4ccbf18 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -254,12 +254,20 @@ public abstract class Context {
* <p>Note: this is not generally useful for applications, since they should
* not be directly accessing the file system.
*
- *
* @return String Path to the code and assets.
*/
public abstract String getPackageCodePath();
/**
+ * {@hide}
+ * Return the full path to the shared prefs file for the given prefs group name.
+ *
+ * <p>Note: this is not generally useful for applications, since they should
+ * not be directly accessing the file system.
+ */
+ public abstract File getSharedPrefsFile(String name);
+
+ /**
* Retrieve and hold the contents of the preferences file 'name', returning
* a SharedPreferences through which you can retrieve and modify its
* values. Only one instance of the SharedPreferences object is returned
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 36e1c34..262204e 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -130,6 +130,11 @@ public class ContextWrapper extends Context {
}
@Override
+ public File getSharedPrefsFile(String name) {
+ return mBase.getSharedPrefsFile(name);
+ }
+
+ @Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return mBase.getSharedPreferences(name, mode);
}
diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java
index 56e3e75..ce47d76 100644
--- a/core/java/android/content/SyncAdaptersCache.java
+++ b/core/java/android/content/SyncAdaptersCache.java
@@ -16,32 +16,10 @@
package android.content;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
import android.content.pm.RegisteredServicesCache;
-import android.content.res.XmlResourceParser;
import android.content.res.TypedArray;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
import android.util.AttributeSet;
-import android.util.Xml;
-
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import com.google.android.collect.Maps;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParser;
/**
* A cache of services that export the {@link android.content.ISyncAdapter} interface.
@@ -58,7 +36,7 @@ import org.xmlpull.v1.XmlPullParser;
super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME);
}
- public SyncAdapterType parseServiceAttributes(AttributeSet attrs) {
+ public SyncAdapterType parseServiceAttributes(String packageName, AttributeSet attrs) {
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
com.android.internal.R.styleable.SyncAdapter);
try {
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 03cfbea..cba02aa 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1642,7 +1642,7 @@ class SyncManager implements OnAccountsUpdatedListener {
// connect to the sync adapter
SyncAdapterType syncAdapterType = new SyncAdapterType(syncOperation.authority,
syncOperation.account.mType);
- RegisteredServicesCache.ServiceInfo syncAdapterInfo =
+ RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
mSyncAdapters.getServiceInfo(syncAdapterType);
if (syncAdapterInfo == null) {
if (Config.LOGD) {
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index f3dfc5a..f10dd53 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -145,6 +145,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_ALLOW_BACKUP = 1<<10;
/**
+ * Indicates that the application supports any densities;
+ * {@hide}
+ */
+ public static final int ANY_DENSITY = -1;
+ private static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY };
+
+ /**
* Flags associated with the application. Any combination of
* {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
* {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
@@ -369,4 +376,14 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
}
return null;
}
+
+ /**
+ * Disable compatibility mode
+ *
+ * @hide
+ */
+ public void disableCompatibilityMode() {
+ expandable = true;
+ supportsDensities = ANY_DENSITIES_ARRAY;
+ }
}
diff --git a/core/java/android/content/pm/ConfigurationInfo.java b/core/java/android/content/pm/ConfigurationInfo.java
index dcc7463..fb7a47f 100755
--- a/core/java/android/content/pm/ConfigurationInfo.java
+++ b/core/java/android/content/pm/ConfigurationInfo.java
@@ -22,7 +22,7 @@ import android.os.Parcelable;
/**
* Information you can retrieve about hardware configuration preferences
* declared by an application. This corresponds to information collected from the
- * AndroidManifest.xml's &lt;uses-configuration&gt; tags.
+ * AndroidManifest.xml's &lt;uses-configuration&gt; and the &lt;uses-feature&gt;tags.
*/
public class ConfigurationInfo implements Parcelable {
/**
@@ -70,6 +70,16 @@ public class ConfigurationInfo implements Parcelable {
*/
public int reqInputFeatures = 0;
+ /**
+ * Default value for {@link #reqGlEsVersion};
+ */
+ public static final int GL_ES_VERSION_UNDEFINED = 0;
+ /**
+ * The GLES version used by an application. The upper order 16 bits represent the
+ * major version and the lower order 16 bits the minor version.
+ */
+ public int reqGlEsVersion;
+
public ConfigurationInfo() {
}
@@ -78,6 +88,7 @@ public class ConfigurationInfo implements Parcelable {
reqKeyboardType = orig.reqKeyboardType;
reqNavigation = orig.reqNavigation;
reqInputFeatures = orig.reqInputFeatures;
+ reqGlEsVersion = orig.reqGlEsVersion;
}
public String toString() {
@@ -86,7 +97,8 @@ public class ConfigurationInfo implements Parcelable {
+ ", touchscreen = " + reqTouchScreen + "}"
+ ", inputMethod = " + reqKeyboardType + "}"
+ ", navigation = " + reqNavigation + "}"
- + ", reqInputFeatures = " + reqInputFeatures + "}";
+ + ", reqInputFeatures = " + reqInputFeatures + "}"
+ + ", reqGlEsVersion = " + reqGlEsVersion + "}";
}
public int describeContents() {
@@ -98,6 +110,7 @@ public class ConfigurationInfo implements Parcelable {
dest.writeInt(reqKeyboardType);
dest.writeInt(reqNavigation);
dest.writeInt(reqInputFeatures);
+ dest.writeInt(reqGlEsVersion);
}
public static final Creator<ConfigurationInfo> CREATOR =
@@ -115,5 +128,18 @@ public class ConfigurationInfo implements Parcelable {
reqKeyboardType = source.readInt();
reqNavigation = source.readInt();
reqInputFeatures = source.readInt();
+ reqGlEsVersion = source.readInt();
+ }
+
+ /**
+ * This method extracts the major and minor version of reqGLEsVersion attribute
+ * and returns it as a string. Say reqGlEsVersion value of 0x00010002 is returned
+ * as 1.2
+ * @return String representation of the reqGlEsVersion attribute
+ */
+ public String getGlEsVersion() {
+ int major = ((reqGlEsVersion & 0xffff0000) >> 16);
+ int minor = reqGlEsVersion & 0x0000ffff;
+ return String.valueOf(major)+"."+String.valueOf(minor);
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e2c0fe6..ab8559c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -748,6 +748,18 @@ public class PackageParser {
XmlUtils.skipCurrentTag(parser);
+ } else if (tagName.equals("uses-feature")) {
+ ConfigurationInfo cPref = new ConfigurationInfo();
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestUsesFeature);
+ cPref.reqGlEsVersion = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestUsesFeature_glEsVersion,
+ ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
+ sa.recycle();
+ pkg.configPreferences.add(cPref);
+
+ XmlUtils.skipCurrentTag(parser);
+
} else if (tagName.equals("uses-sdk")) {
if (mSdkVersion > 0) {
sa = res.obtainAttributes(attrs,
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index d8f8478..bb94372 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -130,7 +130,7 @@ public abstract class RegisteredServicesCache<V> {
* @param type the account type of the authenticator
* @return the AuthenticatorInfo that matches the account type or null if none is present
*/
- public ServiceInfo getServiceInfo(V type) {
+ public ServiceInfo<V> getServiceInfo(V type) {
if (mServices == null) {
maybeRegisterForPackageChanges();
mServices = generateServicesMap();
@@ -219,7 +219,7 @@ public abstract class RegisteredServicesCache<V> {
"Meta-data does not start with " + mAttributesName + " tag");
}
- V v = parseServiceAttributes(attrs);
+ V v = parseServiceAttributes(si.packageName, attrs);
if (v == null) {
return null;
}
@@ -229,5 +229,5 @@ public abstract class RegisteredServicesCache<V> {
}
}
- public abstract V parseServiceAttributes(AttributeSet attrs);
+ public abstract V parseServiceAttributes(String packageName, AttributeSet attrs);
}
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 19379fb..836de39 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -51,10 +51,17 @@ public class CompatibilityInfo {
public final float mApplicationInvertedScale;
/**
- *
* A boolean flag to indicates that the application can expand over the original size.
+ * The flag is set to true if
+ * 1) Application declares its expandable in manifest file using <expandable /> or
+ * 2) The screen size is same as (320 x 480) * density.
*/
- public final boolean mExpandable;
+ public boolean mExpandable;
+
+ /**
+ * A expandable flag in the configuration.
+ */
+ public final boolean mConfiguredExpandable;
/**
* A boolean flag to tell if the application needs scaling (when mApplicationScale != 1.0f)
@@ -62,13 +69,16 @@ public class CompatibilityInfo {
public final boolean mScalingRequired;
public CompatibilityInfo(ApplicationInfo appInfo) {
- // A temp workaround to fix rotation issue.
- // mExpandable = appInfo.expandable;
- mExpandable = true;
+ mExpandable = mConfiguredExpandable = appInfo.expandable;
+
float packageDensityScale = -1.0f;
if (appInfo.supportsDensities != null) {
int minDiff = Integer.MAX_VALUE;
for (int density : appInfo.supportsDensities) {
+ if (density == ApplicationInfo.ANY_DENSITY) {
+ packageDensityScale = 1.0f;
+ break;
+ }
int tmpDiff = Math.abs(DisplayMetrics.DEVICE_DENSITY - density);
if (tmpDiff == 0) {
packageDensityScale = 1.0f;
@@ -92,7 +102,7 @@ public class CompatibilityInfo {
private CompatibilityInfo() {
mApplicationScale = mApplicationInvertedScale = 1.0f;
- mExpandable = true;
+ mExpandable = mConfiguredExpandable = true;
mScalingRequired = false;
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 976b618..2f63820 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -88,7 +88,7 @@ public class Resources {
PluralRules mPluralRule;
private final CompatibilityInfo mCompatibilityInfo;
-
+
private static final SparseArray<Object> EMPTY_ARRAY = new SparseArray<Object>() {
@Override
public void put(int k, Object o) {
@@ -1255,7 +1255,7 @@ public class Resources {
return array;
}
-
+
/**
* Store the newly updated configuration.
*/
@@ -1268,7 +1268,7 @@ public class Resources {
}
if (metrics != null) {
mMetrics.setTo(metrics);
- mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration);
+ mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration.orientation);
}
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
diff --git a/core/java/android/gesture/Gesture.java b/core/java/android/gesture/Gesture.java
index 8e71c57..2262477 100755
--- a/core/java/android/gesture/Gesture.java
+++ b/core/java/android/gesture/Gesture.java
@@ -216,16 +216,15 @@ public class Gesture implements Parcelable {
*
* @param width
* @param height
- * @param edge
+ * @param inset
* @param color
* @return the bitmap
*/
- public Bitmap toBitmap(int width, int height, int edge, int color) {
- final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ public Bitmap toBitmap(int width, int height, int inset, int color) {
+ final Bitmap bitmap = Bitmap.createBitmap(width, height,
+ Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
- canvas.translate(edge, edge);
-
final Paint paint = new Paint();
paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS);
paint.setDither(BITMAP_RENDERING_DITHER);
@@ -235,12 +234,22 @@ public class Gesture implements Parcelable {
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(BITMAP_RENDERING_WIDTH);
- final ArrayList<GestureStroke> strokes = mStrokes;
- final int count = strokes.size();
+ final Path path = toPath();
+ final RectF bounds = new RectF();
+ path.computeBounds(bounds, true);
- for (int i = 0; i < count; i++) {
- strokes.get(i).draw(canvas, paint);
- }
+ final float sx = (width - 2 * inset) / bounds.width();
+ final float sy = (height - 2 * inset) / bounds.height();
+ final float scale = sx > sy ? sy : sx;
+ paint.setStrokeWidth(2.0f / scale);
+
+ path.offset(-bounds.left + (width - bounds.width() * scale) / 2.0f,
+ -bounds.top + (height - bounds.height() * scale) / 2.0f);
+
+ canvas.translate(inset, inset);
+ canvas.scale(scale, scale);
+
+ canvas.drawPath(path, paint);
return bitmap;
}
diff --git a/core/java/android/gesture/GestureLibraries.java b/core/java/android/gesture/GestureLibraries.java
index 2ce7a8e..6d6c156 100644
--- a/core/java/android/gesture/GestureLibraries.java
+++ b/core/java/android/gesture/GestureLibraries.java
@@ -61,17 +61,21 @@ public final class GestureLibraries {
}
public boolean save() {
+ if (!mStore.hasChanged()) return true;
+
final File file = mPath;
- if (!file.canWrite()) return false;
- if (!file.getParentFile().exists()) {
- if (!file.getParentFile().mkdirs()) {
+ final File parentFile = file.getParentFile();
+ if (!parentFile.exists()) {
+ if (!parentFile.mkdirs()) {
return false;
}
}
boolean result = false;
try {
+ //noinspection ResultOfMethodCallIgnored
+ file.createNewFile();
mStore.save(new FileOutputStream(file), true);
result = true;
} catch (FileNotFoundException e) {
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index 6f2c2a7..fd6d850 100755
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -93,8 +93,10 @@ public class GestureOverlayView extends FrameLayout {
private float mTotalLength;
private boolean mIsGesturing = false;
+ private boolean mPreviousWasGesturing = false;
private boolean mInterceptEvents = true;
private boolean mIsListeningForGestures;
+ private boolean mResetGesture;
// current gesture
private Gesture mCurrentGesture;
@@ -272,6 +274,14 @@ public class GestureOverlayView extends FrameLayout {
return mCurrentGesture;
}
+ public long getFadeOffset() {
+ return mFadeOffset;
+ }
+
+ public void setFadeOffset(long fadeOffset) {
+ mFadeOffset = fadeOffset;
+ }
+
public void setGesture(Gesture gesture) {
if (mCurrentGesture != null) {
clear(false);
@@ -284,9 +294,12 @@ public class GestureOverlayView extends FrameLayout {
final RectF bounds = new RectF();
path.computeBounds(bounds, true);
+ // TODO: The path should also be scaled to fit inside this view
mPath.rewind();
- mPath.addPath(path, (getWidth() - bounds.width()) / 2.0f,
- (getHeight() - bounds.height()) / 2.0f);
+ mPath.addPath(path, -bounds.left + (getWidth() - bounds.width()) / 2.0f,
+ -bounds.top + (getHeight() - bounds.height()) / 2.0f);
+
+ mResetGesture = true;
invalidate();
}
@@ -348,6 +361,13 @@ public class GestureOverlayView extends FrameLayout {
invalidate();
}
+ /**
+ * @hide
+ */
+ public Paint getGesturePaint() {
+ return mGesturePaint;
+ }
+
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -365,13 +385,15 @@ public class GestureOverlayView extends FrameLayout {
}
public void clear(boolean animated) {
- clear(animated, false);
+ clear(animated, false, true);
}
- private void clear(boolean animated, boolean fireActionPerformed) {
+ private void clear(boolean animated, boolean fireActionPerformed, boolean immediate) {
setPaintAlpha(255);
removeCallbacks(mFadingOut);
+ mResetGesture = false;
mFadingOut.fireActionPerformed = fireActionPerformed;
+ mFadingOut.resetMultipleStrokes = false;
if (animated && mCurrentGesture != null) {
mFadingAlpha = 1.0f;
@@ -385,8 +407,15 @@ public class GestureOverlayView extends FrameLayout {
mIsFadingOut = false;
mFadingHasStarted = false;
- if (fireActionPerformed) {
- post(mFadingOut);
+ if (immediate) {
+ mCurrentGesture = null;
+ mPath.rewind();
+ invalidate();
+ } else if (fireActionPerformed) {
+ postDelayed(mFadingOut, mFadeOffset);
+ } else if (mGestureStrokeType == GESTURE_STROKE_TYPE_MULTIPLE) {
+ mFadingOut.resetMultipleStrokes = true;
+ postDelayed(mFadingOut, mFadeOffset);
} else {
mCurrentGesture = null;
mPath.rewind();
@@ -425,6 +454,7 @@ public class GestureOverlayView extends FrameLayout {
clear(false);
mIsGesturing = false;
+ mPreviousWasGesturing = false;
mStrokeBuffer.clear();
final ArrayList<OnGesturingListener> otherListeners = mOnGesturingListeners;
@@ -442,8 +472,10 @@ public class GestureOverlayView extends FrameLayout {
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (isEnabled()) {
- boolean cancelDispatch = (mIsGesturing || (mCurrentGesture != null &&
- mCurrentGesture.getStrokesCount() > 0)) && mInterceptEvents;
+ final boolean cancelDispatch = (mIsGesturing || (mCurrentGesture != null &&
+ mCurrentGesture.getStrokesCount() > 0 && mPreviousWasGesturing)) &&
+ mInterceptEvents;
+
processEvent(event);
if (cancelDispatch) {
@@ -451,6 +483,7 @@ public class GestureOverlayView extends FrameLayout {
}
super.dispatchTouchEvent(event);
+
return true;
}
@@ -502,8 +535,9 @@ public class GestureOverlayView extends FrameLayout {
mTotalLength = 0;
mIsGesturing = false;
- if (mGestureStrokeType == GESTURE_STROKE_TYPE_SINGLE) {
+ if (mGestureStrokeType == GESTURE_STROKE_TYPE_SINGLE || mResetGesture) {
if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor);
+ mResetGesture = false;
mCurrentGesture = null;
mPath.rewind();
} else if (mCurrentGesture == null || mCurrentGesture.getStrokesCount() == 0) {
@@ -635,9 +669,8 @@ public class GestureOverlayView extends FrameLayout {
listeners.get(i).onGestureEnded(this, event);
}
- if (mHandleGestureActions) {
- clear(mFadeEnabled, mIsGesturing);
- }
+ clear(mHandleGestureActions && mFadeEnabled, mHandleGestureActions && mIsGesturing,
+ false);
} else {
cancelGesture(event);
@@ -647,6 +680,7 @@ public class GestureOverlayView extends FrameLayout {
}
mStrokeBuffer.clear();
+ mPreviousWasGesturing = mIsGesturing;
mIsGesturing = false;
final ArrayList<OnGesturingListener> listeners = mOnGesturingListeners;
@@ -677,6 +711,7 @@ public class GestureOverlayView extends FrameLayout {
private class FadeOutRunnable implements Runnable {
boolean fireActionPerformed;
+ boolean resetMultipleStrokes;
public void run() {
if (mIsFadingOut) {
@@ -688,6 +723,7 @@ public class GestureOverlayView extends FrameLayout {
fireOnGesturePerformed();
}
+ mPreviousWasGesturing = false;
mIsFadingOut = false;
mFadingHasStarted = false;
mPath.rewind();
@@ -701,12 +737,15 @@ public class GestureOverlayView extends FrameLayout {
setPaintAlpha((int) (255 * mFadingAlpha));
postDelayed(this, FADE_ANIMATION_RATE);
}
+ } else if (resetMultipleStrokes) {
+ mResetGesture = true;
} else {
fireOnGesturePerformed();
mFadingHasStarted = false;
mPath.rewind();
mCurrentGesture = null;
+ mPreviousWasGesturing = false;
setPaintAlpha(255);
}
diff --git a/core/java/android/gesture/GestureStore.java b/core/java/android/gesture/GestureStore.java
index ddf1c83..5f1a445 100644
--- a/core/java/android/gesture/GestureStore.java
+++ b/core/java/android/gesture/GestureStore.java
@@ -206,6 +206,10 @@ public class GestureStore {
}
}
+ public boolean hasChanged() {
+ return mChanged;
+ }
+
/**
* Save the gesture library
*/
@@ -214,10 +218,6 @@ public class GestureStore {
}
public void save(OutputStream stream, boolean closeStream) throws IOException {
- if (!mChanged) {
- return;
- }
-
DataOutputStream out = null;
try {
@@ -228,8 +228,8 @@ public class GestureStore {
final HashMap<String, ArrayList<Gesture>> maps = mNamedGestures;
- out = new DataOutputStream((stream instanceof BufferedOutputStream) ? out :
- new BufferedOutputStream(out, GestureConstants.IO_BUFFER_SIZE));
+ out = new DataOutputStream((stream instanceof BufferedOutputStream) ? stream :
+ new BufferedOutputStream(stream, GestureConstants.IO_BUFFER_SIZE));
// Write version number
out.writeShort(FILE_FORMAT_VERSION);
// Write number of entries
diff --git a/core/java/android/gesture/InstanceLearner.java b/core/java/android/gesture/InstanceLearner.java
index 00cdadc..b93b76f 100644
--- a/core/java/android/gesture/InstanceLearner.java
+++ b/core/java/android/gesture/InstanceLearner.java
@@ -26,6 +26,20 @@ import java.util.TreeMap;
*/
class InstanceLearner extends Learner {
+ private static final Comparator<Prediction> sComparator = new Comparator<Prediction>() {
+ public int compare(Prediction object1, Prediction object2) {
+ double score1 = object1.score;
+ double score2 = object2.score;
+ if (score1 > score2) {
+ return -1;
+ } else if (score1 < score2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
@Override
ArrayList<Prediction> classify(int sequenceType, float[] vector) {
ArrayList<Prediction> predictions = new ArrayList<Prediction>();
@@ -55,31 +69,19 @@ class InstanceLearner extends Learner {
}
}
- double sum = 0;
+// double sum = 0;
for (String name : label2score.keySet()) {
double score = label2score.get(name);
- sum += score;
+// sum += score;
predictions.add(new Prediction(name, score));
}
// normalize
- for (Prediction prediction : predictions) {
- prediction.score /= sum;
- }
+// for (Prediction prediction : predictions) {
+// prediction.score /= sum;
+// }
- Collections.sort(predictions, new Comparator<Prediction>() {
- public int compare(Prediction object1, Prediction object2) {
- double score1 = object1.score;
- double score2 = object2.score;
- if (score1 > score2) {
- return -1;
- } else if (score1 < score2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
+ Collections.sort(predictions, sComparator);
return predictions;
}
diff --git a/core/java/android/gesture/LetterRecognizer.java b/core/java/android/gesture/LetterRecognizer.java
deleted file mode 100644
index 580fc26..0000000
--- a/core/java/android/gesture/LetterRecognizer.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.gesture;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-
-import static android.gesture.GestureConstants.LOG_TAG;
-
-public class LetterRecognizer {
- static final String GESTURE_FILE_NAME = "letters.gestures";
-
- private final static int ADJUST_RANGE = 3;
-
- private SigmoidUnit[] mHiddenLayer;
- private SigmoidUnit[] mOutputLayer;
-
- private final String[] mClasses;
-
- private final int mPatchSize;
-
- private GestureLibrary mGestureStore;
-
- private final Comparator<Prediction> mComparator = new PredictionComparator();
-
- private static class SigmoidUnit {
- final float[] mWeights;
-
- SigmoidUnit(float[] weights) {
- mWeights = weights;
- }
-
- private float compute(float[] inputs) {
- float sum = 0;
-
- final int count = inputs.length;
- final float[] weights = mWeights;
-
- for (int i = 0; i < count; i++) {
- sum += inputs[i] * weights[i];
- }
- sum += weights[weights.length - 1];
-
- return 1.0f / (float) (1 + Math.exp(-sum));
- }
- }
-
- private LetterRecognizer(int numOfInput, int numOfHidden, String[] classes) {
- mPatchSize = (int) Math.sqrt(numOfInput);
- mHiddenLayer = new SigmoidUnit[numOfHidden];
- mClasses = classes;
- mOutputLayer = new SigmoidUnit[classes.length];
- }
-
- public ArrayList<Prediction> recognize(Gesture gesture) {
- return recognize(gesture, null);
- }
-
- public ArrayList<Prediction> recognize(Gesture gesture, ArrayList<Prediction> predictions) {
- float[] query = GestureUtilities.spatialSampling(gesture, mPatchSize);
- predictions = classify(query, predictions);
- adjustPrediction(gesture, predictions);
- return predictions;
- }
-
- private ArrayList<Prediction> classify(float[] vector, ArrayList<Prediction> predictions) {
- if (predictions == null) {
- predictions = new ArrayList<Prediction>();
- } else {
- predictions.clear();
- }
-
- final float[] intermediateOutput = compute(mHiddenLayer, vector);
- final float[] output = compute(mOutputLayer, intermediateOutput);
-
- double sum = 0;
-
- final String[] classes = mClasses;
- final int count = classes.length;
-
- for (int i = 0; i < count; i++) {
- double score = output[i];
- sum += score;
- predictions.add(new Prediction(classes[i], score));
- }
-
- for (int i = 0; i < count; i++) {
- predictions.get(i).score /= sum;
- }
-
- Collections.sort(predictions, mComparator);
-
- return predictions;
- }
-
- private float[] compute(SigmoidUnit[] layer, float[] input) {
- final float[] output = new float[layer.length];
- final int count = layer.length;
-
- for (int i = 0; i < count; i++) {
- output[i] = layer[i].compute(input);
- }
-
- return output;
- }
-
- static LetterRecognizer createFromResource(Context context, int resourceID) {
- final Resources resources = context.getResources();
- final InputStream stream = resources.openRawResource(resourceID);
- return createFromStream(stream);
- }
-
- static LetterRecognizer createFromStream(InputStream stream) {
- DataInputStream in = null;
- LetterRecognizer classifier = null;
-
- try {
- in = new DataInputStream(new BufferedInputStream(stream,
- GestureConstants.IO_BUFFER_SIZE));
-
- final int version = in.readShort();
-
- switch (version) {
- case 1:
- classifier = readV1(in);
- break;
- default:
- Log.d(LOG_TAG, "Couldn't load handwriting data: version " + version +
- " not supported");
- break;
- }
-
- } catch (IOException e) {
- Log.d(LOG_TAG, "Failed to load handwriting data:", e);
- } finally {
- GestureUtilities.closeStream(in);
- }
-
- return classifier;
- }
-
- private static LetterRecognizer readV1(DataInputStream in) throws IOException {
-
- final int iCount = in.readInt();
- final int hCount = in.readInt();
- final int oCount = in.readInt();
-
- final String[] classes = new String[oCount];
- for (int i = 0; i < classes.length; i++) {
- classes[i] = in.readUTF();
- }
-
- final LetterRecognizer classifier = new LetterRecognizer(iCount, hCount, classes);
- final SigmoidUnit[] hiddenLayer = new SigmoidUnit[hCount];
- final SigmoidUnit[] outputLayer = new SigmoidUnit[oCount];
-
- for (int i = 0; i < hCount; i++) {
- final float[] weights = new float[iCount + 1];
- for (int j = 0; j <= iCount; j++) {
- weights[j] = in.readFloat();
- }
- hiddenLayer[i] = new SigmoidUnit(weights);
- }
-
- for (int i = 0; i < oCount; i++) {
- final float[] weights = new float[hCount + 1];
- for (int j = 0; j <= hCount; j++) {
- weights[j] = in.readFloat();
- }
- outputLayer[i] = new SigmoidUnit(weights);
- }
-
- classifier.mHiddenLayer = hiddenLayer;
- classifier.mOutputLayer = outputLayer;
-
- return classifier;
- }
-
- /**
- * TODO: Publish this API once we figure out where we should save the personalized
- * gestures, and how to do so across all apps
- *
- * @hide
- */
- public boolean save() {
- if (mGestureStore != null) {
- return mGestureStore.save();
- }
- return false;
- }
-
- /**
- * TODO: Publish this API once we figure out where we should save the personalized
- * gestures, and how to do so across all apps
- *
- * @hide
- */
- public void setPersonalizationEnabled(boolean enabled) {
- if (enabled) {
- mGestureStore = GestureLibraries.fromFile(GESTURE_FILE_NAME);
- mGestureStore.setSequenceType(GestureStore.SEQUENCE_INVARIANT);
- mGestureStore.load();
- } else {
- mGestureStore = null;
- }
- }
-
- /**
- * TODO: Publish this API once we figure out where we should save the personalized
- * gestures, and how to do so across all apps
- *
- * @hide
- */
- public void addExample(String letter, Gesture example) {
- if (mGestureStore != null) {
- mGestureStore.addGesture(letter, example);
- }
- }
-
- private void adjustPrediction(Gesture query, ArrayList<Prediction> predictions) {
- if (mGestureStore != null) {
- final ArrayList<Prediction> results = mGestureStore.recognize(query);
- final HashMap<String, Prediction> topNList = new HashMap<String, Prediction>();
-
- for (int j = 0; j < ADJUST_RANGE; j++) {
- Prediction prediction = predictions.remove(0);
- topNList.put(prediction.name, prediction);
- }
-
- final int count = results.size();
- for (int j = count - 1; j >= 0 && !topNList.isEmpty(); j--) {
- final Prediction item = results.get(j);
- final Prediction original = topNList.get(item.name);
- if (original != null) {
- predictions.add(0, original);
- topNList.remove(item.name);
- }
- }
- }
- }
-
- private static class PredictionComparator implements Comparator<Prediction> {
- public int compare(Prediction object1, Prediction object2) {
- double score1 = object1.score;
- double score2 = object2.score;
- if (score1 > score2) {
- return -1;
- } else if (score1 < score2) {
- return 1;
- } else {
- return 0;
- }
- }
- }
-}
diff --git a/core/java/android/gesture/LetterRecognizers.java b/core/java/android/gesture/LetterRecognizers.java
deleted file mode 100644
index e3f45a0..0000000
--- a/core/java/android/gesture/LetterRecognizers.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-package android.gesture;
-
-import android.content.Context;
-import android.util.Log;
-import static android.gesture.GestureConstants.LOG_TAG;
-import static android.gesture.LetterRecognizer.*;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-
-public final class LetterRecognizers {
- public final static int RECOGNIZER_LATIN_LOWERCASE = 0;
-
- private LetterRecognizers() {
- }
-
- public static LetterRecognizer fromType(Context context, int type) {
- switch (type) {
- case RECOGNIZER_LATIN_LOWERCASE: {
- return createFromResource(context, com.android.internal.R.raw.latin_lowercase);
- }
- }
- return null;
- }
-
- public static LetterRecognizer fromResource(Context context, int resourceId) {
- return createFromResource(context, resourceId);
- }
-
- public static LetterRecognizer fromFile(String path) {
- return fromFile(new File(path));
- }
-
- public static LetterRecognizer fromFile(File file) {
- try {
- return createFromStream(new FileInputStream(file));
- } catch (FileNotFoundException e) {
- Log.d(LOG_TAG, "Failed to load handwriting data from file " + file, e);
- }
- return null;
- }
-
- public static LetterRecognizer fromStream(InputStream stream) {
- return createFromStream(stream);
- }
-}
diff --git a/core/java/android/gesture/package.html b/core/java/android/gesture/package.html
new file mode 100644
index 0000000..a54a017
--- /dev/null
+++ b/core/java/android/gesture/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+@hide
+</BODY>
+</HTML>
diff --git a/core/java/android/net/http/Request.java b/core/java/android/net/http/Request.java
index aeb85a2..3fb3d3f 100644
--- a/core/java/android/net/http/Request.java
+++ b/core/java/android/net/http/Request.java
@@ -260,6 +260,8 @@ class Request {
// process gzip content encoding
Header contentEncoding = entity.getContentEncoding();
InputStream nis = null;
+ byte[] buf = null;
+ int count = 0;
try {
if (contentEncoding != null &&
contentEncoding.getValue().equals("gzip")) {
@@ -270,9 +272,8 @@ class Request {
/* accumulate enough data to make it worth pushing it
* up the stack */
- byte[] buf = mConnection.getBuf();
+ buf = mConnection.getBuf();
int len = 0;
- int count = 0;
int lowWater = buf.length / 2;
while (len != -1) {
len = nis.read(buf, count, buf.length - count);
@@ -289,6 +290,10 @@ class Request {
/* InflaterInputStream throws an EOFException when the
server truncates gzipped content. Handle this case
as we do truncated non-gzipped content: no error */
+ if (count > 0) {
+ // if there is uncommited content, we should commit them
+ mEventHandler.data(buf, count);
+ }
if (HttpLog.LOGV) HttpLog.v( "readResponse() handling " + e);
} catch(IOException e) {
// don't throw if we have a non-OK status code
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index c597b3c..9c8c537 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -34,6 +34,12 @@ public class Browser {
Uri.parse("content://browser/bookmarks");
/**
+ * The inline scheme to show embedded content in a browser.
+ * @hide
+ */
+ public static final Uri INLINE_URI = Uri.parse("inline:");
+
+ /**
* The name of extra data when starting Browser with ACTION_VIEW or
* ACTION_SEARCH intent.
* <p>
@@ -53,7 +59,37 @@ public class Browser {
* identifier.
*/
public static final String EXTRA_APPLICATION_ID =
- "com.android.browser.application_id";
+ "com.android.browser.application_id";
+
+ /**
+ * The content to be rendered when url's scheme is inline.
+ * @hide
+ */
+ public static final String EXTRA_INLINE_CONTENT ="com.android.browser.inline.content";
+
+ /**
+ * The encoding of the inlined content for inline scheme.
+ * @hide
+ */
+ public static final String EXTRA_INLINE_ENCODING ="com.android.browser.inline.encoding";
+
+ /**
+ * The url used when the inline content is falied to render.
+ * @hide
+ */
+ public static final String EXTRA_INLINE_FAILURL ="com.android.browser.inline.failurl";
+
+ /**
+ * The name of the extra data in the VIEW intent. The data is in boolean.
+ * <p>
+ * If the Browser is handling the intent and the setting for
+ * USE_LOCATION_FOR_SERVICES is allow, the Browser will send the location in
+ * the POST data if this extra data is presented and it is true.
+ * <p>
+ * pending api approval
+ * @hide
+ */
+ public static final String EXTRA_APPEND_LOCATION = "com.android.browser.append_location";
/* if you change column order you must also change indices
below */
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 3a221e4..3145166 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -172,9 +172,6 @@ public final class Calendar {
public static final Uri CONTENT_URI =
Uri.parse("content://calendar/calendars");
- public static final Uri LIVE_CONTENT_URI =
- Uri.parse("content://calendar/calendars?update=1");
-
/**
* The default sort order for this table
*/
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index f32ab00..b9c9236 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -166,6 +166,21 @@ public final class ContactsContract {
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "aggregates");
/**
+ * The content:// style URI for this table joined with useful data from
+ * {@link Data} and {@link Presence}.
+ */
+ public static final Uri CONTENT_SUMMARY_URI = Uri.withAppendedPath(AUTHORITY_URI,
+ "aggregates_summary");
+ /**
+ * The content:// style URI used for "type-to-filter" functionality on the
+ * {@link CONTENT_SUMMARY_URI} URI. The filter string will be used to match
+ * various parts of the aggregate name. The filter argument should be passed
+ * as an additional path segment after this URI.
+ */
+ public static final Uri CONTENT_SUMMARY_FILTER_URI = Uri.withAppendedPath(
+ CONTENT_SUMMARY_URI, "filter");
+
+ /**
* The MIME type of {@link #CONTENT_URI} providing a directory of
* people.
*/
@@ -192,6 +207,31 @@ public final class ContactsContract {
*/
public static final String CONTENT_DIRECTORY = "data";
}
+
+ /**
+ * A sub-directory of a single contact aggregate that contains all aggregation suggestions
+ * (other aggregates). The aggregation suggestions are computed based on approximate
+ * data matches with this aggregate.
+ */
+ public static final class AggregationSuggestions implements BaseColumns, AggregatesColumns {
+ /**
+ * No public constructor since this is a utility class
+ */
+ private AggregationSuggestions() {}
+
+ /**
+ * The directory twig for this sub-table
+ */
+ public static final String CONTENT_DIRECTORY = "suggestions";
+
+ /**
+ * An optional query parameter that can be supplied to limit the number of returned
+ * suggestions.
+ * <p>
+ * Type: INTEGER
+ */
+ public static final String MAX_SUGGESTIONS = "max_suggestions";
+ }
}
@@ -303,6 +343,20 @@ public final class ContactsContract {
*/
public static final String IS_SUPER_PRIMARY = "is_super_primary";
+ /**
+ * Flag indicating that this data entry has been restricted by the owner
+ * {@link #PACKAGE}.
+ */
+ public static final String IS_RESTRICTED = "is_restricted";
+
+ /**
+ * The version of this data record. This is a read-only value. The data column is
+ * guaranteed to not change without the version going up. This value is monotonically
+ * increasing.
+ * <P>Type: INTEGER</P>
+ */
+ public static final String DATA_VERSION = "data_version";
+
/** Generic data column, the meaning is {@link #MIMETYPE} specific */
public static final String DATA1 = "data1";
/** Generic data column, the meaning is {@link #MIMETYPE} specific */
@@ -367,7 +421,97 @@ public final class ContactsContract {
* Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_URI, phoneNumber);
* }
*/
- public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "phone_lookup");
+ public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(AUTHORITY_URI,
+ "phone_lookup");
+ }
+
+ /**
+ * Additional data mixed in with {@link Im.CommonPresenceColumns} to link
+ * back to specific {@link ContactsContract.Aggregates#_ID} entries.
+ */
+ private interface PresenceColumns {
+ /**
+ * Reference to the {@link Aggregates#_ID} this presence references.
+ */
+ public static final String AGGREGATE_ID = "aggregate_id";
+
+ /**
+ * Reference to the {@link Data#_ID} entry that owns this presence.
+ */
+ public static final String DATA_ID = "data_id";
+
+ /**
+ * The IM service the presence is coming from. Formatted using either
+ * {@link Contacts.ContactMethods#encodePredefinedImProtocol} or
+ * {@link Contacts.ContactMethods#encodeCustomImProtocol}.
+ * <p>
+ * Type: STRING
+ */
+ public static final String IM_PROTOCOL = "im_protocol";
+
+ /**
+ * The IM handle the presence item is for. The handle is scoped to the
+ * {@link #IM_PROTOCOL}.
+ * <p>
+ * Type: STRING
+ */
+ public static final String IM_HANDLE = "im_handle";
+
+ /**
+ * The IM account for the local user that the presence data came from.
+ * <p>
+ * Type: STRING
+ */
+ public static final String IM_ACCOUNT = "im_account";
+ }
+
+ public static final class Presence implements BaseColumns, PresenceColumns,
+ Im.CommonPresenceColumns {
+ /**
+ * This utility class cannot be instantiated
+ */
+ private Presence() {
+ }
+
+ /**
+ * The content:// style URI for this table
+ */
+ public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "presence");
+
+ /**
+ * Gets the resource ID for the proper presence icon.
+ *
+ * @param status the status to get the icon for
+ * @return the resource ID for the proper presence icon
+ */
+ public static final int getPresenceIconResourceId(int status) {
+ switch (status) {
+ case AVAILABLE:
+ return android.R.drawable.presence_online;
+ case IDLE:
+ case AWAY:
+ return android.R.drawable.presence_away;
+ case DO_NOT_DISTURB:
+ return android.R.drawable.presence_busy;
+ case INVISIBLE:
+ return android.R.drawable.presence_invisible;
+ case OFFLINE:
+ default:
+ return android.R.drawable.presence_offline;
+ }
+ }
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * presence details.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/im-presence";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * presence detail.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im-presence";
}
/**
@@ -425,6 +569,17 @@ public final class ContactsContract {
}
/**
+ * The base types that all "Typed" data kinds support.
+ */
+ public interface BaseTypes {
+
+ /**
+ * A custom type. The custom label should be supplied by user.
+ */
+ public static int TYPE_CUSTOM = 0;
+ }
+
+ /**
* Parts of the name.
*/
public static final class StructuredName {
@@ -490,7 +645,7 @@ public final class ContactsContract {
/**
* A nickname.
*/
- public static final class Nickname {
+ public static final class Nickname implements BaseTypes {
private Nickname() {}
/** Mime-type used when storing this in data table. */
@@ -502,12 +657,11 @@ public final class ContactsContract {
*/
public static final String TYPE = "data1";
- public static final int TYPE_CUSTOM = 1;
- public static final int TYPE_DEFAULT = 2;
- public static final int TYPE_OTHER_NAME = 3;
- public static final int TYPE_MAINDEN_NAME = 4;
- public static final int TYPE_SHORT_NAME = 5;
- public static final int TYPE_INITIALS = 6;
+ public static final int TYPE_DEFAULT = 1;
+ public static final int TYPE_OTHER_NAME = 2;
+ public static final int TYPE_MAINDEN_NAME = 3;
+ public static final int TYPE_SHORT_NAME = 4;
+ public static final int TYPE_INITIALS = 5;
/**
* The name itself
@@ -524,13 +678,35 @@ public final class ContactsContract {
/**
* Common data definition for telephone numbers.
*/
- public static final class Phone implements BaseCommonColumns, CommonColumns {
+ public static final class Phone implements BaseCommonColumns, CommonColumns, BaseTypes {
private Phone() {}
/** Mime-type used when storing this in data table. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone";
- public static final int TYPE_CUSTOM = 0;
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * phones.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone";
+
+ /**
+ * The content:// style URI for all data records of the
+ * {@link Phone.CONTENT_ITEM_TYPE} mimetype, combined with the associated contact
+ * and aggregate data.
+ */
+ public static final Uri CONTENT_URI = Uri.withAppendedPath(Data.CONTENT_URI,
+ "phones");
+
+ /**
+ * The content:// style URI for filtering data records of the
+ * {@link Phone.CONTENT_ITEM_TYPE} mimetype, combined with the associated contact
+ * and aggregate data. The filter argument should be passed
+ * as an additional path segment after this URI.
+ */
+ public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI,
+ "filter");
+
public static final int TYPE_HOME = 1;
public static final int TYPE_MOBILE = 2;
public static final int TYPE_WORK = 3;
@@ -549,13 +725,12 @@ public final class ContactsContract {
/**
* Common data definition for email addresses.
*/
- public static final class Email implements BaseCommonColumns, CommonColumns {
+ public static final class Email implements BaseCommonColumns, CommonColumns, BaseTypes {
private Email() {}
/** Mime-type used when storing this in data table. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email";
- public static final int TYPE_CUSTOM = 0;
public static final int TYPE_HOME = 1;
public static final int TYPE_WORK = 2;
public static final int TYPE_OTHER = 3;
@@ -564,13 +739,26 @@ public final class ContactsContract {
/**
* Common data definition for postal addresses.
*/
- public static final class Postal implements BaseCommonColumns, CommonColumns {
+ public static final class Postal implements BaseCommonColumns, CommonColumns, BaseTypes {
private Postal() {}
/** Mime-type used when storing this in data table. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/postal-address";
- public static final int TYPE_CUSTOM = 0;
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * postal addresses.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address";
+
+ /**
+ * The content:// style URI for all data records of the
+ * {@link Postal.CONTENT_ITEM_TYPE} mimetype, combined with the associated contact
+ * and aggregate data.
+ */
+ public static final Uri CONTENT_URI = Uri.withAppendedPath(Data.CONTENT_URI,
+ "postals");
+
public static final int TYPE_HOME = 1;
public static final int TYPE_WORK = 2;
public static final int TYPE_OTHER = 3;
@@ -579,13 +767,12 @@ public final class ContactsContract {
/**
* Common data definition for IM addresses.
*/
- public static final class Im implements BaseCommonColumns, CommonColumns {
+ public static final class Im implements BaseCommonColumns, CommonColumns, BaseTypes {
private Im() {}
/** Mime-type used when storing this in data table. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im";
- public static final int TYPE_CUSTOM = 0;
public static final int TYPE_HOME = 1;
public static final int TYPE_WORK = 2;
public static final int TYPE_OTHER = 3;
@@ -640,7 +827,7 @@ public final class ContactsContract {
/**
* Common data definition for organizations.
*/
- public static final class Organization implements BaseCommonColumns {
+ public static final class Organization implements BaseCommonColumns, BaseTypes {
private Organization() {}
/** Mime-type used when storing this in data table. */
@@ -652,7 +839,6 @@ public final class ContactsContract {
*/
public static final String TYPE = "data1";
- public static final int TYPE_CUSTOM = 0;
public static final int TYPE_HOME = 1;
public static final int TYPE_WORK = 2;
public static final int TYPE_OTHER = 3;
@@ -716,7 +902,8 @@ public final class ContactsContract {
public static final class CustomRingtone implements BaseCommonColumns {
private CustomRingtone() {}
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/custom_ringtone";
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/custom_ringtone";
/**
* Whether to send the number to voicemail.
@@ -763,7 +950,7 @@ public final class ContactsContract {
* Constants for the contact aggregation exceptions table, which contains
* aggregation rules overriding those used by automatic aggregation.
*/
- public static final class AggregationExceptions {
+ public static final class AggregationExceptions implements BaseColumns {
/**
* This utility class cannot be instantiated
*/
@@ -781,6 +968,12 @@ public final class ContactsContract {
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/aggregation_exception";
/**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of an aggregation exception
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/aggregation_exception";
+
+ /**
* The type of exception: {@link #TYPE_NEVER_MATCH} or {@link #TYPE_ALWAYS_MATCH}.
*
* <P>Type: INTEGER</P>
@@ -802,4 +995,51 @@ public final class ContactsContract {
*/
public static final String CONTACT_ID2 = "contact_id2";
}
+
+ private interface RestrictionExceptionsColumns {
+ /**
+ * Package name of a specific data provider, which will be matched
+ * against {@link Data#PACKAGE}.
+ * <p>
+ * Type: STRING
+ */
+ public static final String PACKAGE_PROVIDER = "package_provider";
+
+ /**
+ * Package name of a specific data client, which will be matched against
+ * the incoming {@link android.os.Binder#getCallingUid()} to decide if
+ * the caller can access values with {@link Data#IS_RESTRICTED} flags.
+ * <p>
+ * Type: STRING
+ */
+ public static final String PACKAGE_CLIENT = "package_client";
+
+ /**
+ * Flag indicating if {@link #PACKAGE_PROVIDER} allows
+ * {@link #PACKAGE_CLIENT} to access restricted {@link Data} rows.
+ * <p>
+ * Type: INTEGER
+ */
+ public static final String ALLOW_ACCESS = "allow_access";
+ }
+
+ /**
+ * Constants for {@link Data} restriction exceptions. Sync adapters who
+ * insert restricted data can use this table to specify exceptions about
+ * which additional packages can access that restricted data.You can only
+ * modify rules for a {@link RestrictionExceptionsColumns#PACKAGE_PROVIDER}
+ * that your {@link android.os.Binder#getCallingUid()} owns.
+ */
+ public static final class RestrictionExceptions implements RestrictionExceptionsColumns {
+ /**
+ * This utility class cannot be instantiated
+ */
+ private RestrictionExceptions() {}
+
+ /**
+ * The content:// style URI for this table
+ */
+ public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
+ "restriction_exceptions");
+ }
}
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index c36f508..ef4ff51 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -1611,6 +1611,9 @@ public class Im {
/** specifies whether or not to show mobile indicator to friends */
public static final String SETTING_SHOW_MOBILE_INDICATOR = "mobile_indicator";
+ /** specifies whether or not to show as away when device is idle */
+ public static final String SETTING_SHOW_AWAY_ON_IDLE = "show_away_on_idle";
+
/**
* Used for reliable message queue (RMQ). This is for storing the last rmq id received
* from the GTalk server
@@ -1819,6 +1822,17 @@ public class Im {
showMobileIndicator);
}
+ /**
+ * A convenience method to set whether or not to show as away when device is idle.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param showAway Whether or not to show as away when device is idle.
+ */
+ public static void setShowAwayOnIdle(ContentResolver contentResolver,
+ long providerId, boolean showAway) {
+ putBooleanValue(contentResolver, providerId, SETTING_SHOW_AWAY_ON_IDLE, showAway);
+ }
+
public static class QueryMap extends ContentQueryMap {
private ContentResolver mContentResolver;
private long mProviderId;
@@ -1949,6 +1963,25 @@ public class Im {
}
/**
+ * Set whether or not to show as away when device is idle.
+ *
+ * @param showAway whether or not to show as away when device is idle.
+ */
+ public void setShowAwayOnIdle(boolean showAway) {
+ ProviderSettings.setShowAwayOnIdle(mContentResolver, mProviderId, showAway);
+ }
+
+ /**
+ * Get whether or not to show as away when device is idle.
+ *
+ * @return Whether or not to show as away when device is idle.
+ */
+ public boolean getShowAwayOnIdle() {
+ return getBoolean(SETTING_SHOW_AWAY_ON_IDLE,
+ true /* by default show as away on idle*/);
+ }
+
+ /**
* Convenience function for retrieving a single settings value
* as a boolean.
*
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a632bf0..03c7f28 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1025,6 +1025,14 @@ public final class Settings {
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
/**
+ * If 0, the compatibility mode is off for all applications.
+ * If 1, older applications run under compatibility mode.
+ * TODO: remove this settings before code freeze (bug/1907571)
+ * @hide
+ */
+ public static final String COMPATIBILITY_MODE = "compatibility_mode";
+
+ /**
* The screen backlight brightness between 0 and 255.
*/
public static final String SCREEN_BRIGHTNESS = "screen_brightness";
@@ -1940,6 +1948,34 @@ public final class Settings {
"enabled_accessibility_services";
/**
+ * Setting to always use the default text-to-speech settings regardless
+ * of the application settings.
+ * 1 = override application settings,
+ * 0 = use application settings (if specified).
+ */
+ public static final String TTS_USE_DEFAULTS = "tts_use_defaults";
+
+ /**
+ * Default text-to-speech engine speech rate. 100 = 1x
+ */
+ public static final String TTS_DEFAULT_RATE = "tts_default_rate";
+
+ /**
+ * Default text-to-speech engine pitch. 100 = 1x
+ */
+ public static final String TTS_DEFAULT_PITCH = "tts_default_pitch";
+
+ /**
+ * Default text-to-speech engine.
+ */
+ public static final String TTS_DEFAULT_SYNTH = "tts_default_synth";
+
+ /**
+ * Default text-to-speech language.
+ */
+ public static final String TTS_DEFAULT_LANG = "tts_default_lang";
+
+ /**
* Whether to notify the user of open networks.
* <p>
* If not connected and the scan results have an open network, we will
@@ -2479,6 +2515,12 @@ public final class Settings {
public static final String GMAIL_BUFFER_SERVER_RESPONSE = "gmail_buffer_server_response";
/**
+ * The maximum size in bytes allowed for the provider to gzip a protocol buffer uploaded to
+ * the server.
+ */
+ public static final String GMAIL_MAX_GZIP_SIZE = "gmail_max_gzip_size_bytes";
+
+ /**
* Controls whether Gmail will discard uphill operations that repeatedly fail. Value must be
* an integer where non-zero means true. Defaults to 1.
*/
@@ -3049,6 +3091,13 @@ public final class Settings {
public static final String ANR_BUGREPORT_RECIPIENT = "anr_bugreport_recipient";
/**
+ * Flag for allowing service provider to use location information to improve products and
+ * services.
+ * Type: int ( 0 = disallow, 1 = allow )
+ */
+ public static final String USE_LOCATION_FOR_SERVICES = "use_location";
+
+ /**
* @deprecated
* @hide
*/
diff --git a/core/java/android/provider/SocialContract.java b/core/java/android/provider/SocialContract.java
index d4a9c48..28bf8db 100644
--- a/core/java/android/provider/SocialContract.java
+++ b/core/java/android/provider/SocialContract.java
@@ -18,6 +18,8 @@ package android.provider;
import android.graphics.BitmapFactory;
import android.net.Uri;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.Data;
/**
* The contract between the social provider and applications. Contains
@@ -152,13 +154,21 @@ public class SocialContract {
public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "activities");
/**
- * The content:// style URI for this table filtered to the set of social activities
+ * The content:// URI for this table filtered to the set of social activities
* authored by a specific {@link android.provider.ContactsContract.Contacts#_ID}.
*/
public static final Uri CONTENT_AUTHORED_BY_URI =
Uri.withAppendedPath(CONTENT_URI, "authored_by");
/**
+ * The {@link Uri} for the latest social activity performed by any
+ * contact aggregated under the specified {@link Aggregates#_ID}. Will
+ * also join with most-present {@link Presence} for this aggregate.
+ */
+ public static final Uri CONTENT_AGGREGATE_STATUS_URI =
+ Uri.withAppendedPath(AUTHORITY_URI, "aggregate_status");
+
+ /**
* The MIME type of {@link #CONTENT_URI} providing a directory of social
* activities.
*/
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index a2c253a..0d96ec3 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -1498,6 +1498,14 @@ public final class Telephony {
public static final Uri CONTENT_DRAFT_URI = Uri.parse(
"content://mms-sms/draft");
+
+ /***
+ * Pass in a query parameter called "pattern" which is the text
+ * to search for.
+ * The sort order is fixed to be thread_id ASC,date DESC.
+ */
+ public static final Uri SEARCH_URI = Uri.parse(
+ "content://mms-sms/search");
// Constants for message protocol types.
public static final int SMS_PROTO = 0;
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 5c4e56d..1cf7be9 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -26,14 +26,13 @@ import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
+import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothA2dp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.PackageManager;
import android.media.AudioManager;
-import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
@@ -44,6 +43,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.UUID;
public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String TAG = "BluetoothA2dpService";
@@ -58,57 +58,22 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String BLUETOOTH_ENABLED = "bluetooth_enabled";
private static final int MESSAGE_CONNECT_TO = 1;
- private static final int MESSAGE_DISCONNECT = 2;
- private final Context mContext;
- private final IntentFilter mIntentFilter;
- private HashMap<String, SinkState> mAudioDevices;
- private final AudioManager mAudioManager;
- private final BluetoothDevice mBluetooth;
+ private static final String PROPERTY_STATE = "State";
- // list of disconnected sinks to process after a delay
- private final ArrayList<String> mPendingDisconnects = new ArrayList<String>();
- // number of active sinks
- private int mSinkCount = 0;
+ private static final String SINK_STATE_DISCONNECTED = "disconnected";
+ private static final String SINK_STATE_CONNECTING = "connecting";
+ private static final String SINK_STATE_CONNECTED = "connected";
+ private static final String SINK_STATE_PLAYING = "playing";
- private class SinkState {
- public String address;
- public int state;
- public SinkState(String a, int s) {address = a; state = s;}
- }
+ private static int mSinkCount;
- public BluetoothA2dpService(Context context) {
- mContext = context;
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-
- mBluetooth = (BluetoothDevice) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
- if (mBluetooth == null) {
- throw new RuntimeException("Platform does not support Bluetooth");
- }
-
- if (!initNative()) {
- throw new RuntimeException("Could not init BluetoothA2dpService");
- }
-
- mIntentFilter = new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
- mContext.registerReceiver(mReceiver, mIntentFilter);
-
- if (mBluetooth.isEnabled()) {
- onBluetoothEnable();
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- cleanupNative();
- } finally {
- super.finalize();
- }
- }
+ private final Context mContext;
+ private final IntentFilter mIntentFilter;
+ private HashMap<String, Integer> mAudioDevices;
+ private final AudioManager mAudioManager;
+ private final BluetoothDeviceService mBluetoothService;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -151,6 +116,40 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
}
};
+ public BluetoothA2dpService(Context context, BluetoothDeviceService bluetoothService) {
+ mContext = context;
+
+ mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+
+ mBluetoothService = bluetoothService;
+ if (mBluetoothService == null) {
+ throw new RuntimeException("Platform does not support Bluetooth");
+ }
+
+ if (!initNative()) {
+ throw new RuntimeException("Could not init BluetoothA2dpService");
+ }
+
+ mIntentFilter = new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
+ mContext.registerReceiver(mReceiver, mIntentFilter);
+
+ mAudioDevices = new HashMap<String, Integer>();
+
+ if (mBluetoothService.isEnabled())
+ onBluetoothEnable();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ cleanupNative();
+ } finally {
+ super.finalize();
+ }
+ }
+
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -159,7 +158,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
String address = (String)msg.obj;
// check bluetooth is still on, device is still preferred, and
// nothing is currently connected
- if (mBluetooth.isEnabled() &&
+ if (mBluetoothService.isEnabled() &&
getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF &&
lookupSinksMatchingStates(new int[] {
BluetoothA2dp.STATE_CONNECTING,
@@ -170,45 +169,85 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
connectSink(address);
}
break;
- case MESSAGE_DISCONNECT:
- handleDeferredDisconnect((String)msg.obj);
- break;
}
}
};
+ private int convertBluezSinkStringtoState(String value) {
+ if (value.equalsIgnoreCase("disconnected"))
+ return BluetoothA2dp.STATE_DISCONNECTED;
+ if (value.equalsIgnoreCase("connecting"))
+ return BluetoothA2dp.STATE_CONNECTING;
+ if (value.equalsIgnoreCase("connected"))
+ return BluetoothA2dp.STATE_CONNECTED;
+ if (value.equalsIgnoreCase("playing"))
+ return BluetoothA2dp.STATE_PLAYING;
+ return -1;
+ }
+
+ private synchronized boolean addAudioSink (String address) {
+ String path = mBluetoothService.getObjectPathFromAddress(address);
+ String propValues[] = (String []) getSinkPropertiesNative(path);
+ if (propValues == null) {
+ Log.e(TAG, "Error while getting AudioSink properties for device: " + address);
+ return false;
+ }
+ Integer state = null;
+ // Properties are name-value pairs
+ for (int i = 0; i < propValues.length; i+=2) {
+ if (propValues[i].equals(PROPERTY_STATE)) {
+ state = new Integer(convertBluezSinkStringtoState(propValues[i+1]));
+ break;
+ }
+ }
+ mAudioDevices.put(address, state);
+ handleSinkStateChange(address, BluetoothA2dp.STATE_DISCONNECTED, state);
+ return true;
+ }
+
private synchronized void onBluetoothEnable() {
- mAudioDevices = new HashMap<String, SinkState>();
- String[] paths = (String[])listHeadsetsNative();
- if (paths != null) {
- for (String path : paths) {
- mAudioDevices.put(path, new SinkState(getAddressNative(path),
- isSinkConnectedNative(path) ? BluetoothA2dp.STATE_CONNECTED :
- BluetoothA2dp.STATE_DISCONNECTED));
+ String devices = mBluetoothService.getProperty("Devices");
+ mSinkCount = 0;
+ if (devices != null) {
+ String [] paths = devices.split(",");
+ for (String path: paths) {
+ String address = mBluetoothService.getAddressFromObjectPath(path);
+ String []uuids = mBluetoothService.getRemoteUuids(address);
+ if (uuids != null)
+ for (String uuid: uuids) {
+ UUID remoteUuid = UUID.fromString(uuid);
+ if (BluetoothUuid.isAudioSink(remoteUuid) ||
+ BluetoothUuid.isAudioSource(remoteUuid) ||
+ BluetoothUuid.isAdvAudioDist(remoteUuid)) {
+ addAudioSink(address);
+ break;
+ }
+ }
}
}
mAudioManager.setParameter(BLUETOOTH_ENABLED, "true");
}
private synchronized void onBluetoothDisable() {
- if (mAudioDevices != null) {
- // copy to allow modification during iteration
- String[] paths = new String[mAudioDevices.size()];
- paths = mAudioDevices.keySet().toArray(paths);
- for (String path : paths) {
- switch (mAudioDevices.get(path).state) {
+ if (!mAudioDevices.isEmpty()) {
+ String [] addresses = new String[mAudioDevices.size()];
+ addresses = mAudioDevices.keySet().toArray(addresses);
+ for (String address : addresses) {
+ int state = getSinkState(address);
+ switch (state) {
case BluetoothA2dp.STATE_CONNECTING:
case BluetoothA2dp.STATE_CONNECTED:
case BluetoothA2dp.STATE_PLAYING:
- disconnectSinkNative(path);
- updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
+ disconnectSinkNative(mBluetoothService.getObjectPathFromAddress(address));
+ handleSinkStateChange(address,state, BluetoothA2dp.STATE_DISCONNECTED);
break;
case BluetoothA2dp.STATE_DISCONNECTING:
- updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
+ handleSinkStateChange(address, BluetoothA2dp.STATE_DISCONNECTING,
+ BluetoothA2dp.STATE_DISCONNECTED);
break;
}
}
- mAudioDevices = null;
+ mAudioDevices.clear();
}
mAudioManager.setBluetoothA2dpOn(false);
mAudioManager.setParameter(BLUETOOTH_ENABLED, "false");
@@ -221,9 +260,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return BluetoothError.ERROR;
}
- if (mAudioDevices == null) {
- return BluetoothError.ERROR;
- }
+
// ignore if there are any active sinks
if (lookupSinksMatchingStates(new int[] {
BluetoothA2dp.STATE_CONNECTING,
@@ -233,20 +270,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return BluetoothError.ERROR;
}
- String path = lookupPath(address);
- if (path == null) {
- path = createHeadsetNative(address);
- if (DBG) log("new bluez sink: " + address + " (" + path + ")");
- }
- if (path == null) {
+ if (mAudioDevices.get(address) == null && !addAudioSink(address))
return BluetoothError.ERROR;
- }
- SinkState sink = mAudioDevices.get(path);
- int state = BluetoothA2dp.STATE_DISCONNECTED;
- if (sink != null) {
- state = sink.state;
- }
+ int state = mAudioDevices.get(address);
+
switch (state) {
case BluetoothA2dp.STATE_CONNECTED:
case BluetoothA2dp.STATE_PLAYING:
@@ -256,11 +284,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return BluetoothError.SUCCESS;
}
+ String path = mBluetoothService.getObjectPathFromAddress(address);
+ if (path == null)
+ return BluetoothError.ERROR;
+
// State is DISCONNECTED
if (!connectSinkNative(path)) {
return BluetoothError.ERROR;
}
- updateState(path, BluetoothA2dp.STATE_CONNECTING);
return BluetoothError.SUCCESS;
}
@@ -271,14 +302,12 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return BluetoothError.ERROR;
}
- if (mAudioDevices == null) {
- return BluetoothError.ERROR;
- }
- String path = lookupPath(address);
+ String path = mBluetoothService.getObjectPathFromAddress(address);
if (path == null) {
return BluetoothError.ERROR;
}
- switch (mAudioDevices.get(path).state) {
+
+ switch (getSinkState(address)) {
case BluetoothA2dp.STATE_DISCONNECTED:
return BluetoothError.ERROR;
case BluetoothA2dp.STATE_DISCONNECTING:
@@ -289,7 +318,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (!disconnectSinkNative(path)) {
return BluetoothError.ERROR;
} else {
- updateState(path, BluetoothA2dp.STATE_DISCONNECTING);
return BluetoothError.SUCCESS;
}
}
@@ -305,15 +333,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return BluetoothError.ERROR;
}
- if (mAudioDevices == null) {
+ Integer state = mAudioDevices.get(address);
+ if (state == null)
return BluetoothA2dp.STATE_DISCONNECTED;
- }
- for (SinkState sink : mAudioDevices.values()) {
- if (address.equals(sink.address)) {
- return sink.state;
- }
- }
- return BluetoothA2dp.STATE_DISCONNECTED;
+ return state;
}
public synchronized int getSinkPriority(String address) {
@@ -337,103 +360,68 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
BluetoothError.SUCCESS : BluetoothError.ERROR;
}
- private synchronized void onHeadsetCreated(String path) {
- updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
- }
-
- private synchronized void onHeadsetRemoved(String path) {
- if (mAudioDevices == null) return;
- mAudioDevices.remove(path);
- }
-
- private synchronized void onSinkConnected(String path) {
- // if we are reconnected, do not process previous disconnect event.
- mPendingDisconnects.remove(path);
-
- if (mAudioDevices == null) return;
- // bluez 3.36 quietly disconnects the previous sink when a new sink
- // is connected, so we need to mark all previously connected sinks as
- // disconnected
-
- // copy to allow modification during iteration
- String[] paths = new String[mAudioDevices.size()];
- paths = mAudioDevices.keySet().toArray(paths);
- for (String oldPath : paths) {
- if (path.equals(oldPath)) {
- continue;
- }
- int state = mAudioDevices.get(oldPath).state;
- if (state == BluetoothA2dp.STATE_CONNECTED || state == BluetoothA2dp.STATE_PLAYING) {
- updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
- }
+ private synchronized void onSinkPropertyChanged(String path, String []propValues) {
+ String name = propValues[0];
+ String address = mBluetoothService.getAddressFromObjectPath(path);
+ if (address == null) {
+ Log.e(TAG, "onSinkPropertyChanged: Address of the remote device in null");
+ return;
}
- updateState(path, BluetoothA2dp.STATE_CONNECTING);
- mAudioManager.setParameter(A2DP_SINK_ADDRESS, lookupAddress(path));
- mAudioManager.setBluetoothA2dpOn(true);
- updateState(path, BluetoothA2dp.STATE_CONNECTED);
- }
-
- private synchronized void onSinkDisconnected(String path) {
- // This is to work around a problem in bluez that results
- // sink disconnect events being sent, immediately followed by a reconnect.
- // To avoid unnecessary audio routing changes, we defer handling
- // sink disconnects until after a short delay.
- mPendingDisconnects.add(path);
- Message msg = Message.obtain(mHandler, MESSAGE_DISCONNECT, path);
- mHandler.sendMessageDelayed(msg, 2000);
- }
-
- private synchronized void handleDeferredDisconnect(String path) {
- if (mPendingDisconnects.contains(path)) {
- mPendingDisconnects.remove(path);
- if (mSinkCount == 1) {
- mAudioManager.setBluetoothA2dpOn(false);
- }
- updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
+ if (mAudioDevices.get(address) == null) {
+ // Ignore this state change, since it means we have got it after
+ // bluetooth has been disabled.
+ return;
+ }
+ if (name.equals(PROPERTY_STATE)) {
+ int state = convertBluezSinkStringtoState(propValues[1]);
+ int prevState = mAudioDevices.get(address);
+ handleSinkStateChange(address, prevState, state);
}
}
- private synchronized void onSinkPlaying(String path) {
- updateState(path, BluetoothA2dp.STATE_PLAYING);
- }
-
- private synchronized void onSinkStopped(String path) {
- updateState(path, BluetoothA2dp.STATE_CONNECTED);
- }
+ private void handleSinkStateChange(String address, int prevState, int state) {
+ if (state != prevState) {
+ if (state == BluetoothA2dp.STATE_DISCONNECTED ||
+ state == BluetoothA2dp.STATE_DISCONNECTING) {
+ if (prevState == BluetoothA2dp.STATE_CONNECTED ||
+ prevState == BluetoothA2dp.STATE_PLAYING) {
+ // disconnecting or disconnected
+ Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+ mContext.sendBroadcast(intent);
+ }
+ if (--mSinkCount == 0)
+ mAudioManager.setBluetoothA2dpOn(false);
+ } else if (state == BluetoothA2dp.STATE_CONNECTED) {
+ mSinkCount ++;
+ }
+ mAudioDevices.put(address, state);
- private synchronized final String lookupAddress(String path) {
- if (mAudioDevices == null) return null;
- SinkState sink = mAudioDevices.get(path);
- if (sink == null) {
- Log.w(TAG, "lookupAddress() called for unknown device " + path);
- updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
- }
- String address = mAudioDevices.get(path).address;
- if (address == null) Log.e(TAG, "Can't find address for " + path);
- return address;
- }
+ Intent intent = new Intent(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ intent.putExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothA2dp.SINK_STATE, state);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- private synchronized final String lookupPath(String address) {
- if (mAudioDevices == null) return null;
+ if (DBG) log("A2DP state : address: " + address + " State:" + prevState + "->" + state);
- for (String path : mAudioDevices.keySet()) {
- if (address.equals(mAudioDevices.get(path).address)) {
- return path;
+ if (state == BluetoothA2dp.STATE_CONNECTED) {
+ mAudioManager.setParameter(A2DP_SINK_ADDRESS, address);
+ mAudioManager.setBluetoothA2dpOn(true);
}
}
- return null;
}
private synchronized List<String> lookupSinksMatchingStates(int[] states) {
List<String> sinks = new ArrayList<String>();
- if (mAudioDevices == null) {
+ if (mAudioDevices.isEmpty()) {
return sinks;
}
- for (SinkState sink : mAudioDevices.values()) {
+ for (String path: mAudioDevices.keySet()) {
+ int sinkState = getSinkState(path);
for (int state : states) {
- if (sink.state == state) {
- sinks.add(sink.address);
+ if (state == sinkState) {
+ sinks.add(path);
break;
}
}
@@ -441,57 +429,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return sinks;
}
- private synchronized void updateState(String path, int state) {
- if (mAudioDevices == null) return;
-
- SinkState s = mAudioDevices.get(path);
- int prevState;
- String address;
- if (s == null) {
- address = getAddressNative(path);
- mAudioDevices.put(path, new SinkState(address, state));
- prevState = BluetoothA2dp.STATE_DISCONNECTED;
- } else {
- address = lookupAddress(path);
- prevState = s.state;
- s.state = state;
- }
-
- if (state != prevState) {
- if (DBG) log("state " + address + " (" + path + ") " + prevState + "->" + state);
-
- // keep track of the number of active sinks
- if (prevState == BluetoothA2dp.STATE_DISCONNECTED) {
- mSinkCount++;
- } else if (state == BluetoothA2dp.STATE_DISCONNECTED) {
- mSinkCount--;
- }
-
- Intent intent = new Intent(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- intent.putExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, prevState);
- intent.putExtra(BluetoothA2dp.SINK_STATE, state);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-
- if ((prevState == BluetoothA2dp.STATE_CONNECTED ||
- prevState == BluetoothA2dp.STATE_PLAYING) &&
- (state != BluetoothA2dp.STATE_CONNECTING &&
- state != BluetoothA2dp.STATE_CONNECTED &&
- state != BluetoothA2dp.STATE_PLAYING)) {
- // disconnected
- intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
- mContext.sendBroadcast(intent);
- }
- }
- }
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mAudioDevices == null) return;
+ if (mAudioDevices.isEmpty()) return;
pw.println("Cached audio devices:");
- for (String path : mAudioDevices.keySet()) {
- SinkState sink = mAudioDevices.get(path);
- pw.println(path + " " + sink.address + " " + BluetoothA2dp.stateToString(sink.state));
+ for (String address : mAudioDevices.keySet()) {
+ int state = mAudioDevices.get(address);
+ pw.println(address + " " + BluetoothA2dp.stateToString(state));
}
}
@@ -501,11 +446,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private native boolean initNative();
private native void cleanupNative();
- private synchronized native String[] listHeadsetsNative();
- private synchronized native String createHeadsetNative(String address);
- private synchronized native boolean removeHeadsetNative(String path);
- private synchronized native String getAddressNative(String path);
private synchronized native boolean connectSinkNative(String path);
private synchronized native boolean disconnectSinkNative(String path);
- private synchronized native boolean isSinkConnectedNative(String path);
+ private synchronized native Object []getSinkPropertiesNative(String path);
}
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 8e5cee9..36c432b 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -30,7 +30,6 @@ import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDevice;
-import android.bluetooth.IBluetoothDeviceCallback;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -38,7 +37,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -46,6 +44,8 @@ import android.os.SystemService;
import android.provider.Settings;
import android.util.Log;
+import com.android.internal.app.IBatteryStats;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
@@ -55,8 +55,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import com.android.internal.app.IBatteryStats;
-
public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private static final String TAG = "BluetoothDeviceService";
private static final boolean DBG = true;
@@ -80,10 +78,12 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
private static final int MESSAGE_FINISH_DISABLE = 2;
+ private Map<String, String> mProperties;
+ private HashMap <String, Map<String, String>> mRemoteDeviceProperties;
+
static {
classInitNative();
}
- private native static void classInitNative();
public BluetoothDeviceService(Context context) {
mContext = context;
@@ -109,8 +109,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
mIsDiscovering = false;
mEventLoop = new BluetoothEventLoop(mContext, this);
registerForAirplaneMode();
+ mProperties = new HashMap<String, String>();
+ mRemoteDeviceProperties = new HashMap<String, Map<String,String>>();
}
- private native void initializeNativeDataNative();
@Override
protected void finalize() throws Throwable {
@@ -123,13 +124,11 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
super.finalize();
}
}
- private native void cleanupNativeDataNative();
public boolean isEnabled() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return mBluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON;
}
- private native int isEnabledNative();
public int getBluetoothState() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
@@ -150,8 +149,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
* @param saveSetting If true, disable BT in settings
*/
public synchronized boolean disable(boolean saveSetting) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH_ADMIN permission");
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
switch (mBluetoothState) {
case BluetoothDevice.BLUETOOTH_STATE_OFF:
@@ -180,6 +178,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
return;
}
mEventLoop.stop();
+ tearDownNativeDataNative();
disableNative();
// mark in progress bondings as cancelled
@@ -188,25 +187,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
}
- // Remove remoteServiceChannelCallbacks
- HashMap<String, IBluetoothDeviceCallback> callbacksMap =
- mEventLoop.getRemoteServiceChannelCallbacks();
-
- for (Iterator<String> i = callbacksMap.keySet().iterator(); i.hasNext();) {
- String address = i.next();
- IBluetoothDeviceCallback callback = callbacksMap.get(address);
- try {
- callback.onGetRemoteServiceChannelResult(address, BluetoothError.ERROR_DISABLED);
- } catch (RemoteException e) {}
- i.remove();
- }
-
// update mode
Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothDevice.SCAN_MODE_NONE);
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
mIsDiscovering = false;
+ mProperties.clear();
if (saveSetting) {
persistBluetoothOnSetting(false);
@@ -270,7 +257,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (!disable(false)) {
mRestart = false;
}
- }
+ }
private synchronized void setBluetoothState(int state) {
if (state == mBluetoothState) {
@@ -343,6 +330,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (res) {
+ if (!setupNativeDataNative()) {
+ return;
+ }
if (mSaveSetting) {
persistBluetoothOnSetting(true);
}
@@ -369,7 +359,12 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (res) {
// Update mode
- mEventLoop.onModeChanged(getModeNative());
+ String[] propVal = {"Pairable", getProperty("Pairable")};
+ mEventLoop.onPropertyChanged(propVal);
+ }
+
+ if (mIsAirplaneSensitive && isAirplaneModeOn()) {
+ disable(false);
}
}
@@ -382,9 +377,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
Binder.restoreCallingIdentity(origCallerIdentityToken);
}
- private native int enableNative();
- private native int disableNative();
-
/* package */ BondState getBondState() {
return mBondState;
}
@@ -419,14 +411,19 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (mBluetoothState != BluetoothDevice.BLUETOOTH_STATE_TURNING_ON) {
return;
}
- String[] bonds = listBondingsNative();
+ String []bonds = null;
+ String val = getProperty("Devices");
+ if (val != null) {
+ bonds = val.split(",");
+ }
if (bonds == null) {
return;
}
mState.clear();
if (DBG) log("found " + bonds.length + " bonded devices");
- for (String address : bonds) {
- mState.put(address.toUpperCase(), BluetoothDevice.BOND_BONDED);
+ for (String device : bonds) {
+ mState.put(getAddressFromObjectPath(device).toUpperCase(),
+ BluetoothDevice.BOND_BONDED);
}
}
@@ -524,7 +521,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
}
- private native String[] listBondingsNative();
private static String toBondStateString(int bondState) {
switch (bondState) {
@@ -539,17 +535,36 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
}
- public synchronized String getAddress() {
+ /*package*/synchronized void getAllProperties() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getAddressNative();
+ mProperties.clear();
+
+ String properties[] = (String [])getAdapterPropertiesNative();
+ // The String Array consists of key-value pairs.
+ if (properties == null) {
+ Log.e(TAG, "*Error*: GetAdapterProperties returned NULL");
+ return;
+ }
+ for (int i = 0; i < properties.length; i+=2) {
+ String value = null;
+ if (mProperties.containsKey(properties[i])) {
+ value = mProperties.get(properties[i]);
+ value = value + ',' + properties[i+1];
+ } else
+ value = properties[i+1];
+
+ mProperties.put(properties[i], value);
+ }
+
+ // Add adapter object path property.
+ String adapterPath = getAdapterPathNative();
+ if (adapterPath != null)
+ mProperties.put("ObjectPath", adapterPath + "/dev_");
}
- private native String getAddressNative();
- public synchronized String getName() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getNameNative();
+ /* package */ synchronized void setProperty(String name, String value) {
+ mProperties.put(name, value);
}
- private native String getNameNative();
public synchronized boolean setName(String name) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -557,90 +572,101 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (name == null) {
return false;
}
- // hcid handles persistance of the bluetooth name
- return setNameNative(name);
+ return setPropertyString("Name", name);
}
- private native boolean setNameNative(String name);
- /**
- * Returns the user-friendly name of a remote device. This value is
- * retrned from our local cache, which is updated during device discovery.
- * Do not expect to retrieve the updated remote name immediately after
- * changing the name on the remote device.
- *
- * @param address Bluetooth address of remote device.
- *
- * @return The user-friendly name of the specified remote device.
- */
- public synchronized String getRemoteName(String address) {
+ //TODO(): setPropertyString, setPropertyInteger, setPropertyBoolean
+ // Either have a single property function with Object as the parameter
+ // or have a function for each property and then obfuscate in the JNI layer.
+ // The following looks dirty.
+ private boolean setPropertyString(String key, String value) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
- }
- return getRemoteNameNative(address);
+ return setAdapterPropertyStringNative(key, value);
}
- private native String getRemoteNameNative(String address);
- /* pacakge */ native String getAdapterPathNative();
+ private boolean setPropertyInteger(String key, int value) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return setAdapterPropertyIntegerNative(key, value);
+ }
- public synchronized boolean startDiscovery(boolean resolveNames) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH_ADMIN permission");
- return startDiscoveryNative(resolveNames);
+ private boolean setPropertyBoolean(String key, boolean value) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return setAdapterPropertyBooleanNative(key, value ? 1 : 0);
}
- private native boolean startDiscoveryNative(boolean resolveNames);
- public synchronized boolean cancelDiscovery() {
+ /**
+ * Set the discoverability window for the device. A timeout of zero
+ * makes the device permanently discoverable (if the device is
+ * discoverable). Setting the timeout to a nonzero value does not make
+ * a device discoverable; you need to call setMode() to make the device
+ * explicitly discoverable.
+ *
+ * @param timeout_s The discoverable timeout in seconds.
+ */
+ public synchronized boolean setDiscoverableTimeout(int timeout) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
- return cancelDiscoveryNative();
+ return setPropertyInteger("DiscoverableTimeout", timeout);
}
- private native boolean cancelDiscoveryNative();
- public synchronized boolean isDiscovering() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return mIsDiscovering;
- }
+ public synchronized boolean setScanMode(int mode) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+ "Need BLUETOOTH_ADMIN permission");
+ boolean pairable = false, discoverable = false;
+ String modeString = scanModeToBluezString(mode);
+ if (modeString.equals("off")) {
+ pairable = false;
+ discoverable = false;
+ } else if (modeString.equals("pariable")) {
+ pairable = true;
+ discoverable = false;
+ } else if (modeString.equals("discoverable")) {
+ pairable = true;
+ discoverable = true;
+ }
+ setPropertyBoolean("Pairable", pairable);
+ setPropertyBoolean("Discoverable", discoverable);
- /* package */ void setIsDiscovering(boolean isDiscovering) {
- mIsDiscovering = isDiscovering;
+ return true;
}
- public synchronized boolean startPeriodicDiscovery() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH_ADMIN permission");
- return startPeriodicDiscoveryNative();
+ /*package*/ synchronized String getProperty (String name) {
+ if (!mProperties.isEmpty())
+ return mProperties.get(name);
+ getAllProperties();
+ return mProperties.get(name);
}
- private native boolean startPeriodicDiscoveryNative();
- public synchronized boolean stopPeriodicDiscovery() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH_ADMIN permission");
- return stopPeriodicDiscoveryNative();
+ public synchronized String getAddress() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return getProperty("Address");
}
- private native boolean stopPeriodicDiscoveryNative();
- public synchronized boolean isPeriodicDiscovery() {
+ public synchronized String getName() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return isPeriodicDiscoveryNative();
+ return getProperty("Name");
}
- private native boolean isPeriodicDiscoveryNative();
/**
- * Set the discoverability window for the device. A timeout of zero
- * makes the device permanently discoverable (if the device is
- * discoverable). Setting the timeout to a nonzero value does not make
- * a device discoverable; you need to call setMode() to make the device
- * explicitly discoverable.
+ * Returns the user-friendly name of a remote device. This value is
+ * returned from our local cache, which is updated when onPropertyChange
+ * event is received.
+ * Do not expect to retrieve the updated remote name immediately after
+ * changing the name on the remote device.
*
- * @param timeout_s The discoverable timeout in seconds.
+ * @param address Bluetooth address of remote device.
+ *
+ * @return The user-friendly name of the specified remote device.
*/
- public synchronized boolean setDiscoverableTimeout(int timeout) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
- "Need BLUETOOTH_ADMIN permission");
- return setDiscoverableTimeoutNative(timeout);
+ public synchronized String getRemoteName(String address) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (!BluetoothDevice.checkBluetoothAddress(address)) {
+ return null;
+ }
+ Map <String, String> properties = mRemoteDeviceProperties.get(address);
+ if (properties != null) return properties.get("Name");
+ return null;
}
- private native boolean setDiscoverableTimeoutNative(int timeout_s);
/**
* Get the discoverability window for the device. A timeout of zero
@@ -652,45 +678,46 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
*/
public synchronized int getDiscoverableTimeout() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getDiscoverableTimeoutNative();
+ String timeout = getProperty("DiscoverableTimeout");
+ if (timeout != null)
+ return Integer.valueOf(timeout);
+ else
+ return -1;
}
- private native int getDiscoverableTimeoutNative();
-
- public synchronized boolean isAclConnected(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return false;
- }
- return isConnectedNative(address);
- }
- private native boolean isConnectedNative(String address);
public synchronized int getScanMode() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return bluezStringToScanMode(getModeNative());
+ if (!isEnabled())
+ return BluetoothError.ERROR;
+
+ boolean pairable = getProperty("Pairable").equals("true");
+ boolean discoverable = getProperty("Discoverable").equals("true");
+ return bluezStringToScanMode (pairable, discoverable);
}
- private native String getModeNative();
- public synchronized boolean setScanMode(int mode) {
+ public synchronized boolean startDiscovery() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
- String bluezMode = scanModeToBluezString(mode);
- if (bluezMode != null) {
- return setModeNative(bluezMode);
+ if (!isEnabled()) {
+ return false;
}
- return false;
+ return startDiscoveryNative();
}
- private native boolean setModeNative(String mode);
- public synchronized boolean disconnectRemoteDeviceAcl(String address) {
+ public synchronized boolean cancelDiscovery() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return false;
- }
- return disconnectRemoteDeviceNative(address);
+ return stopDiscoveryNative();
+ }
+
+ public synchronized boolean isDiscovering() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return mIsDiscovering;
+ }
+
+ /* package */ void setIsDiscovering(boolean isDiscovering) {
+ mIsDiscovering = isDiscovering;
}
- private native boolean disconnectRemoteDeviceNative(String address);
public synchronized boolean createBond(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -715,14 +742,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
return false;
}
- if (!createBondingNative(address, 60000 /* 1 minute */)) {
+ if (!createPairedDeviceNative(address, 60000 /* 1 minute */)) {
return false;
}
mBondState.setBondState(address, BluetoothDevice.BOND_BONDING);
return true;
}
- private native boolean createBondingNative(String address, int timeout_ms);
public synchronized boolean cancelBondProcess(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -737,10 +763,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
- cancelBondingProcessNative(address);
+ cancelDeviceCreationNative(address);
return true;
}
- private native boolean cancelBondingProcessNative(String address);
public synchronized boolean removeBond(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -748,9 +773,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
- return removeBondingNative(address);
+ return removeDeviceNative(getObjectPathFromAddress(address));
}
- private native boolean removeBondingNative(String address);
public synchronized String[] listBonds() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
@@ -765,198 +789,57 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
return mBondState.getBondState(address.toUpperCase());
}
- public synchronized String[] listAclConnections() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return listConnectionsNative();
- }
- private native String[] listConnectionsNative();
-
- /**
- * This method lists all remote devices that this adapter is aware of.
- * This is a list not only of all most-recently discovered devices, but of
- * all devices discovered by this adapter up to some point in the past.
- * Note that many of these devices may not be in the neighborhood anymore,
- * and attempting to connect to them will result in an error.
- *
- * @return An array of strings representing the Bluetooth addresses of all
- * remote devices that this adapter is aware of.
- */
- public synchronized String[] listRemoteDevices() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return listRemoteDevicesNative();
- }
- private native String[] listRemoteDevicesNative();
-
- /**
- * Returns the version of the Bluetooth chip. This version is compiled from
- * the LMP version. In case of EDR the features attribute must be checked.
- * Example: "Bluetooth 2.0 + EDR".
- *
- * @return a String representation of the this Adapter's underlying
- * Bluetooth-chip version.
- */
- public synchronized String getVersion() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getVersionNative();
- }
- private native String getVersionNative();
-
- /**
- * Returns the revision of the Bluetooth chip. This is a vendor-specific
- * value and in most cases it represents the firmware version. This might
- * derive from the HCI revision and LMP subversion values or via extra
- * vendord specific commands.
- * In case the revision of a chip is not available. This method should
- * return the LMP subversion value as a string.
- * Example: "HCI 19.2"
- *
- * @return The HCI revision of this adapter.
- */
- public synchronized String getRevision() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getRevisionNative();
- }
- private native String getRevisionNative();
-
- /**
- * Returns the manufacturer of the Bluetooth chip. If the company id is not
- * known the sting "Company ID %d" where %d should be replaced with the
- * numeric value from the manufacturer field.
- * Example: "Cambridge Silicon Radio"
- *
- * @return Manufacturer name.
- */
- public synchronized String getManufacturer() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getManufacturerNative();
- }
- private native String getManufacturerNative();
-
- /**
- * Returns the company name from the OUI database of the Bluetooth device
- * address. This function will need a valid and up-to-date oui.txt from
- * the IEEE. This value will be different from the manufacturer string in
- * the most cases.
- * If the oui.txt file is not present or the OUI part of the Bluetooth
- * address is not listed, it should return the string "OUI %s" where %s is
- * the actual OUI.
- *
- * Example: "Apple Computer"
- *
- * @return company name
- */
- public synchronized String getCompany() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return getCompanyNative();
- }
- private native String getCompanyNative();
-
- /**
- * Like getVersion(), but for a remote device.
- *
- * @param address The Bluetooth address of the remote device.
- *
- * @return remote-device Bluetooth version
- *
- * @see #getVersion
- */
- public synchronized String getRemoteVersion(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
- }
- return getRemoteVersionNative(address);
- }
- private native String getRemoteVersionNative(String address);
-
- /**
- * Like getRevision(), but for a remote device.
- *
- * @param address The Bluetooth address of the remote device.
- *
- * @return remote-device HCI revision
- *
- * @see #getRevision
- */
- public synchronized String getRemoteRevision(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
- }
- return getRemoteRevisionNative(address);
- }
- private native String getRemoteRevisionNative(String address);
-
- /**
- * Like getManufacturer(), but for a remote device.
- *
- * @param address The Bluetooth address of the remote device.
- *
- * @return remote-device Bluetooth chip manufacturer
- *
- * @see #getManufacturer
- */
- public synchronized String getRemoteManufacturer(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
+ /*package*/ synchronized String getRemoteDeviceProperty(String address, String property) {
+ Map<String, String> properties = mRemoteDeviceProperties.get(address);
+ if (properties != null) {
+ return properties.get(property);
+ } else {
+ // Query for remote device properties, again.
+ // We will need to reload the cache when we switch Bluetooth on / off
+ // or if we crash.
+ String objectPath = getObjectPathFromAddress(address);
+ String propValues[] = (String [])getDevicePropertiesNative(objectPath);
+ if (propValues != null) {
+ addRemoteDeviceProperties(address, propValues);
+ return getRemoteDeviceProperty(address, property);
+ }
}
- return getRemoteManufacturerNative(address);
+ Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address);
+ return null;
}
- private native String getRemoteManufacturerNative(String address);
- /**
- * Like getCompany(), but for a remote device.
- *
- * @param address The Bluetooth address of the remote device.
- *
- * @return remote-device company
- *
- * @see #getCompany
- */
- public synchronized String getRemoteCompany(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
+ /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) {
+ Map<String, String> propertyValues = new HashMap<String, String>();
+ for (int i = 0; i < properties.length; i+=2) {
+ String value = null;
+ if (propertyValues.containsKey(properties[i])) {
+ value = propertyValues.get(properties[i]);
+ value = value + ',' + properties[i+1];
+ } else {
+ value = properties[i+1];
+ }
+ propertyValues.put(properties[i], value);
}
- return getRemoteCompanyNative(address);
+ mRemoteDeviceProperties.put(address, propertyValues);
}
- private native String getRemoteCompanyNative(String address);
- /**
- * Returns the date and time when the specified remote device has been seen
- * by a discover procedure.
- * Example: "2006-02-08 12:00:00 GMT"
- *
- * @return a String with the timestamp.
- */
- public synchronized String lastSeen(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
- }
- return lastSeenNative(address);
+ /* package */ void removeRemoteDeviceProperties(String address) {
+ mRemoteDeviceProperties.remove(address);
}
- private native String lastSeenNative(String address);
- /**
- * Returns the date and time when the specified remote device has last been
- * connected to
- * Example: "2006-02-08 12:00:00 GMT"
- *
- * @return a String with the timestamp.
- */
- public synchronized String lastUsed(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
+ /* package */ synchronized void setRemoteDeviceProperty(String address, String name,
+ String value) {
+ Map <String, String> propVal = mRemoteDeviceProperties.get(address);
+ if (propVal != null) {
+ propVal.put(name, value);
+ mRemoteDeviceProperties.put(address, propVal);
+ } else {
+ Log.e(TAG, "setRemoteDeviceProperty for a device not in cache:" + address);
}
- return lastUsedNative(address);
}
- private native String lastUsedNative(String address);
/**
- * Gets the remote major, minor, and service classes encoded as a 32-bit
+ * Gets the remote major, minor classes encoded as a 32-bit
* integer.
*
* Note: this value is retrieved from cache, because we get it during
@@ -964,120 +847,56 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
*
* @return 32-bit integer encoding the remote major, minor, and service
* classes.
- *
- * @see #getRemoteMajorClass
- * @see #getRemoteMinorClass
- * @see #getRemoteServiceClasses
*/
public synchronized int getRemoteClass(String address) {
if (!BluetoothDevice.checkBluetoothAddress(address)) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return BluetoothClass.ERROR;
}
- return getRemoteClassNative(address);
+ String val = getRemoteDeviceProperty(address, "Class");
+ if (val == null)
+ return BluetoothClass.ERROR;
+ else {
+ return Integer.valueOf(val);
+ }
}
- private native int getRemoteClassNative(String address);
+
/**
* Gets the remote features encoded as bit mask.
*
* Note: This method may be obsoleted soon.
*
- * @return byte array of features.
- */
- public synchronized byte[] getRemoteFeatures(String address) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
- }
- return getRemoteFeaturesNative(address);
- }
- private native byte[] getRemoteFeaturesNative(String address);
-
- /**
- * This method and {@link #getRemoteServiceRecord} query the SDP service
- * on a remote device. They do not interpret the data, but simply return
- * it raw to the user. To read more about SDP service handles and records,
- * consult the Bluetooth core documentation (www.bluetooth.com).
- *
- * @param address Bluetooth address of remote device.
- * @param match a String match to narrow down the service-handle search.
- * The only supported value currently is "hsp" for the headset
- * profile. To retrieve all service handles, simply pass an empty
- * match string.
- *
- * @return all service handles corresponding to the string match.
- *
- * @see #getRemoteServiceRecord
+ * @return String array of 128bit UUIDs
*/
- public synchronized int[] getRemoteServiceHandles(String address, String match) {
+ public synchronized String[] getRemoteUuids(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return null;
}
- if (match == null) {
- match = "";
- }
- return getRemoteServiceHandlesNative(address, match);
+ String value = getRemoteDeviceProperty(address, "UUIDs");
+ String[] uuids = null;
+ // The UUIDs are stored as a "," separated string.
+ if (value != null)
+ uuids = value.split(",");
+ return uuids;
}
- private native int[] getRemoteServiceHandlesNative(String address, String match);
/**
- * This method retrieves the service records corresponding to a given
- * service handle (method {@link #getRemoteServiceHandles} retrieves the
- * service handles.)
+ * Gets the rfcomm channel associated with the UUID.
*
- * This method and {@link #getRemoteServiceHandles} do not interpret their
- * data, but simply return it raw to the user. To read more about SDP
- * service handles and records, consult the Bluetooth core documentation
- * (www.bluetooth.com).
+ * @param address Address of the remote device
+ * @param uuid UUID of the service attribute
*
- * @param address Bluetooth address of remote device.
- * @param handle Service handle returned by {@link #getRemoteServiceHandles}
- *
- * @return a byte array of all service records corresponding to the
- * specified service handle.
- *
- * @see #getRemoteServiceHandles
+ * @return rfcomm channel associated with the service attribute
*/
- public synchronized byte[] getRemoteServiceRecord(String address, int handle) {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return null;
- }
- return getRemoteServiceRecordNative(address, handle);
- }
- private native byte[] getRemoteServiceRecordNative(String address, int handle);
-
- private static final int MAX_OUTSTANDING_ASYNC = 32;
-
- // AIDL does not yet support short's
- public synchronized boolean getRemoteServiceChannel(String address, int uuid16,
- IBluetoothDeviceCallback callback) {
+ public int getRemoteServiceChannel(String address, String uuid) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return false;
- }
- HashMap<String, IBluetoothDeviceCallback> callbacks =
- mEventLoop.getRemoteServiceChannelCallbacks();
- if (callbacks.containsKey(address)) {
- Log.w(TAG, "SDP request already in progress for " + address);
- return false;
+ return BluetoothError.ERROR_IPC;
}
- // Protect from malicious clients - only allow 32 bonding requests per minute.
- if (callbacks.size() > MAX_OUTSTANDING_ASYNC) {
- Log.w(TAG, "Too many outstanding SDP requests, dropping request for " + address);
- return false;
- }
- callbacks.put(address, callback);
-
- if (!getRemoteServiceChannelNative(address, (short)uuid16)) {
- callbacks.remove(address);
- return false;
- }
- return true;
+ return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid, 0x0004);
}
- private native boolean getRemoteServiceChannelNative(String address, short uuid16);
public synchronized boolean setPin(String address, byte[] pin) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -1104,7 +923,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
return setPinNative(address, pinString, data.intValue());
}
- private native boolean setPinNative(String address, String pin, int nativeData);
public synchronized boolean cancelPin(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
@@ -1122,7 +940,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
return cancelPinNative(address, data.intValue());
}
- private native boolean cancelPinNative(String address, int natveiData);
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -1186,20 +1003,22 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
BluetoothHeadset headset = new BluetoothHeadset(mContext, null);
- String[] addresses = listRemoteDevices();
-
pw.println("\n--Known devices--");
- for (String address : addresses) {
+ for (String address : mRemoteDeviceProperties.keySet()) {
pw.printf("%s %10s (%d) %s\n", address,
toBondStateString(mBondState.getBondState(address)),
mBondState.getAttempt(address),
getRemoteName(address));
}
- addresses = listAclConnections();
+ String value = getProperty("Devices");
+ String []devicesObjectPath = null;
+ if (value != null) {
+ devicesObjectPath = value.split(",");
+ }
pw.println("\n--ACL connected devices--");
- for (String address : addresses) {
- pw.println(address);
+ for (String device : devicesObjectPath) {
+ pw.println(getAddressFromObjectPath(device));
}
// Rather not do this from here, but no-where else and I need this
@@ -1223,20 +1042,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
headset.close();
}
- /* package */ static int bluezStringToScanMode(String mode) {
- if (mode == null) {
- return BluetoothError.ERROR;
- }
- mode = mode.toLowerCase();
- if (mode.equals("off")) {
- return BluetoothDevice.SCAN_MODE_NONE;
- } else if (mode.equals("connectable")) {
- return BluetoothDevice.SCAN_MODE_CONNECTABLE;
- } else if (mode.equals("discoverable")) {
+ /* package */ static int bluezStringToScanMode(boolean pairable, boolean discoverable) {
+ if (pairable && discoverable)
return BluetoothDevice.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
- } else {
- return BluetoothError.ERROR;
- }
+ else if (pairable && !discoverable)
+ return BluetoothDevice.SCAN_MODE_CONNECTABLE;
+ else
+ return BluetoothDevice.SCAN_MODE_NONE;
}
/* package */ static String scanModeToBluezString(int mode) {
@@ -1251,7 +1063,67 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
return null;
}
+ /*package*/ String getAddressFromObjectPath(String objectPath) {
+ String adapterObjectPath = getProperty("ObjectPath");
+ if (adapterObjectPath == null || objectPath == null) {
+ Log.e(TAG, "getAddressFromObjectPath: AdpaterObjectPath:" + adapterObjectPath +
+ " or deviceObjectPath:" + objectPath + " is null");
+ return null;
+ }
+ if (!objectPath.startsWith(adapterObjectPath)) {
+ Log.e(TAG, "getAddressFromObjectPath: AdpaterObjectPath:" + adapterObjectPath +
+ " is not a prefix of deviceObjectPath:" + objectPath +
+ "bluetoothd crashed ?");
+ return null;
+ }
+ String address = objectPath.substring(adapterObjectPath.length());
+ if (address != null) return address.replace('_', ':');
+
+ Log.e(TAG, "getAddressFromObjectPath: Address being returned is null");
+ return null;
+ }
+
+ /*package*/ String getObjectPathFromAddress(String address) {
+ String path = getProperty("ObjectPath");
+ if (path == null) {
+ Log.e(TAG, "Error: Object Path is null");
+ return null;
+ }
+ path = path + address.replace(":", "_");
+ return path;
+ }
+
private static void log(String msg) {
Log.d(TAG, msg);
}
+
+ private native static void classInitNative();
+ private native void initializeNativeDataNative();
+ private native boolean setupNativeDataNative();
+ private native boolean tearDownNativeDataNative();
+ private native void cleanupNativeDataNative();
+ private native String getAdapterPathNative();
+
+ private native int isEnabledNative();
+ private native int enableNative();
+ private native int disableNative();
+
+ private native Object[] getAdapterPropertiesNative();
+ private native Object[] getDevicePropertiesNative(String objectPath);
+ private native boolean setAdapterPropertyStringNative(String key, String value);
+ private native boolean setAdapterPropertyIntegerNative(String key, int value);
+ private native boolean setAdapterPropertyBooleanNative(String key, int value);
+
+ private native boolean startDiscoveryNative();
+ private native boolean stopDiscoveryNative();
+
+ private native boolean createPairedDeviceNative(String address, int timeout_ms);
+ private native boolean cancelDeviceCreationNative(String address);
+ private native boolean removeDeviceNative(String objectPath);
+ private native int getDeviceServiceChannelNative(String objectPath, String uuid,
+ int attributeId);
+
+ private native boolean cancelPinNative(String address, int nativeData);
+ private native boolean setPinNative(String address, String pin, int nativeData);
+
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 8cc229b..00c13b7 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -21,15 +21,15 @@ import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
-import android.bluetooth.IBluetoothDeviceCallback;
+import android.bluetooth.BluetoothUuid;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.util.Log;
import java.util.HashMap;
+import java.util.UUID;
/**
* TODO: Move this to
@@ -47,7 +47,6 @@ class BluetoothEventLoop {
private boolean mStarted;
private boolean mInterrupted;
private final HashMap<String, Integer> mPasskeyAgentRequestData;
- private final HashMap<String, IBluetoothDeviceCallback> mGetRemoteServiceChannelCallbacks;
private final BluetoothDeviceService mBluetoothService;
private final Context mContext;
@@ -89,10 +88,8 @@ class BluetoothEventLoop {
mBluetoothService = bluetoothService;
mContext = context;
mPasskeyAgentRequestData = new HashMap();
- mGetRemoteServiceChannelCallbacks = new HashMap();
initializeNativeDataNative();
}
- private native void initializeNativeDataNative();
protected void finalize() throws Throwable {
try {
@@ -101,20 +98,11 @@ class BluetoothEventLoop {
super.finalize();
}
}
- private native void cleanupNativeDataNative();
- /* pacakge */ HashMap<String, IBluetoothDeviceCallback> getRemoteServiceChannelCallbacks() {
- return mGetRemoteServiceChannelCallbacks;
- }
-
- /* pacakge */ HashMap<String, Integer> getPasskeyAgentRequestData() {
+ /* package */ HashMap<String, Integer> getPasskeyAgentRequestData() {
return mPasskeyAgentRequestData;
}
- private native void startEventLoopNative();
- private native void stopEventLoopNative();
- private native boolean isEventLoopRunningNative();
-
/* package */ void start() {
if (!isEventLoopRunningNative()) {
@@ -134,79 +122,37 @@ class BluetoothEventLoop {
return isEventLoopRunningNative();
}
- /*package*/ void onModeChanged(String bluezMode) {
- int mode = BluetoothDeviceService.bluezStringToScanMode(bluezMode);
- if (mode >= 0) {
- Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
- intent.putExtra(BluetoothIntent.SCAN_MODE, mode);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ private void onDeviceFound(String address, String[] properties) {
+ if (properties == null) {
+ Log.e(TAG, "ERROR: Remote device properties are null");
+ return;
+ }
+ mBluetoothService.addRemoteDeviceProperties(address, properties);
+ String rssi = mBluetoothService.getRemoteDeviceProperty(address, "RSSI");
+ String classValue = mBluetoothService.getRemoteDeviceProperty(address, "Class");
+
+ if (rssi != null && classValue != null) {
+ Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ intent.putExtra(BluetoothIntent.CLASS, classValue);
+ intent.putExtra(BluetoothIntent.RSSI, (short)Integer.valueOf(rssi).intValue());
+
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ } else {
+ log ("RSSI: " + rssi + " or ClassValue: " + classValue +
+ " for remote device: " + address + " is null");
}
}
- private void onDiscoveryStarted() {
- mBluetoothService.setIsDiscovering(true);
- Intent intent = new Intent(BluetoothIntent.DISCOVERY_STARTED_ACTION);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onDiscoveryCompleted() {
- mBluetoothService.setIsDiscovering(false);
- Intent intent = new Intent(BluetoothIntent.DISCOVERY_COMPLETED_ACTION);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
+ private void onDeviceDisappeared(String address) {
+ mBluetoothService.removeRemoteDeviceProperties(address);
- private void onRemoteDeviceFound(String address, int deviceClass, short rssi) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- intent.putExtra(BluetoothIntent.CLASS, deviceClass);
- intent.putExtra(BluetoothIntent.RSSI, rssi);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteDeviceDisappeared(String address) {
Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
}
- private void onRemoteClassUpdated(String address, int deviceClass) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- intent.putExtra(BluetoothIntent.CLASS, deviceClass);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteDeviceConnected(String address) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteDeviceDisconnectRequested(String address) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECT_REQUESTED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteDeviceDisconnected(String address) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteNameUpdated(String address, String name) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- intent.putExtra(BluetoothIntent.NAME, name);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteNameFailed(String address) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_FAILED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onRemoteNameChanged(String address, String name) {
- Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- intent.putExtra(BluetoothIntent.NAME, name);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- }
- private void onCreateBondingResult(String address, int result) {
+ private void onCreatePairedDeviceResult(String address, int result) {
address = address.toUpperCase();
if (result == BluetoothError.SUCCESS) {
mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
@@ -259,23 +205,118 @@ class BluetoothEventLoop {
mBluetoothService.getBondState().attempt(address);
}
- private void onBondingCreated(String address) {
- mBluetoothService.getBondState().setBondState(address.toUpperCase(),
- BluetoothDevice.BOND_BONDED);
+ private void onDeviceCreated(String deviceObjectPath) {
+ // do nothing.
+ return;
}
- private void onBondingRemoved(String address) {
- mBluetoothService.getBondState().setBondState(address.toUpperCase(),
- BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED);
+ private void onDeviceRemoved(String deviceObjectPath) {
+ String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+ if (address != null)
+ mBluetoothService.getBondState().setBondState(address.toUpperCase(),
+ BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED);
}
- private void onNameChanged(String name) {
- Intent intent = new Intent(BluetoothIntent.NAME_CHANGED_ACTION);
- intent.putExtra(BluetoothIntent.NAME, name);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ /*package*/ void onPropertyChanged(String[] propValues) {
+ String name = propValues[0];
+ if (name.equals("Name")) {
+ Intent intent = new Intent(BluetoothIntent.NAME_CHANGED_ACTION);
+ intent.putExtra(BluetoothIntent.NAME, propValues[1]);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ mBluetoothService.setProperty(name, propValues[1]);
+ } else if (name.equals("Pairable") || name.equals("Discoverable")) {
+ String pairable = name.equals("Pairable") ? propValues[1] :
+ mBluetoothService.getProperty("Pairable");
+ String discoverable = name.equals("Discoverable") ? propValues[1] :
+ mBluetoothService.getProperty("Discoverable");
+
+ // This shouldn't happen, unless Adapter Properties are null.
+ if (pairable == null || discoverable == null)
+ return;
+
+ int mode = BluetoothDeviceService.bluezStringToScanMode(
+ pairable.equals("true"),
+ discoverable.equals("true"));
+ if (mode >= 0) {
+ Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
+ intent.putExtra(BluetoothIntent.SCAN_MODE, mode);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ }
+ mBluetoothService.setProperty(name, propValues[1]);
+ } else if (name.equals("Discovering")) {
+ Intent intent;
+ if (propValues[1].equals("true")) {
+ mBluetoothService.setIsDiscovering(true);
+ intent = new Intent(BluetoothIntent.DISCOVERY_STARTED_ACTION);
+ } else {
+ // Stop the discovery.
+ mBluetoothService.cancelDiscovery();
+ mBluetoothService.setIsDiscovering(false);
+ intent = new Intent(BluetoothIntent.DISCOVERY_COMPLETED_ACTION);
+ }
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ mBluetoothService.setProperty(name, propValues[1]);
+ } else if (name.equals("Devices")) {
+ String value = "";
+ for (int i = 1; i < propValues.length; i++) {
+ value = value + propValues[i] + ',';
+ }
+ mBluetoothService.setProperty(name, value.equals("") ? null : value);
+ } else if (name.equals("Powered")) {
+ // bluetoothd has restarted, re-read all our properties.
+ // Note: bluez only sends this property change when it restarts.
+ if (propValues[1].equals("true"))
+ onRestartRequired();
+ }
+ }
+
+ private void onDevicePropertyChanged(String deviceObjectPath, String[] propValues) {
+ String name = propValues[0];
+ String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+ if (address == null) {
+ Log.e(TAG, "onDevicePropertyChanged: Address of the remote device in null");
+ return;
+ }
+ if (name.equals("Name")) {
+ Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ intent.putExtra(BluetoothIntent.NAME, propValues[1]);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
+ } else if (name.equals("Class")) {
+ Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION);
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ intent.putExtra(BluetoothIntent.CLASS, propValues[1]);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
+ } else if (name.equals("Connected")) {
+ Intent intent = null;
+ if (propValues[1].equals("true")) {
+ intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
+ } else {
+ intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION);
+ }
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
+ } else if (name.equals("UUIDs")) {
+ String uuid = "" ;
+ for (int i = 1; i < propValues.length; i++) {
+ uuid = uuid + propValues[i] + ",";
+ }
+ mBluetoothService.setRemoteDeviceProperty(address, name,
+ uuid.equals("") ? null : uuid);
+ }
+
}
- private void onPasskeyAgentRequest(String address, int nativeData) {
+ private void onRequestPinCode(String objectPath, int nativeData) {
+ String address = mBluetoothService.getAddressFromObjectPath(objectPath);
+ if (address == null) {
+ Log.e(TAG, "Unable to get device address in onRequestPinCode, returning null");
+ return;
+ }
address = address.toUpperCase();
mPasskeyAgentRequestData.put(address, new Integer(nativeData));
@@ -309,21 +350,21 @@ class BluetoothEventLoop {
Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ return;
}
- private void onPasskeyAgentCancel(String address) {
- address = address.toUpperCase();
- mBluetoothService.cancelPin(address);
- Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
- mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
- BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
- }
+ private boolean onAgentAuthorize(String objectPath, String deviceUuid) {
+ String address = mBluetoothService.getAddressFromObjectPath(objectPath);
+ if (address == null) {
+ Log.e(TAG, "Unable to get device address in onAuthAgentAuthorize");
+ return false;
+ }
- private boolean onAuthAgentAuthorize(String address, String service, String uuid) {
boolean authorized = false;
- if (mBluetoothService.isEnabled() && service.endsWith("service_audio")) {
+ UUID uuid = UUID.fromString(deviceUuid);
+ if (mBluetoothService.isEnabled() && (BluetoothUuid.isAudioSink(uuid) ||
+ BluetoothUuid.isAudioSource(uuid) ||
+ BluetoothUuid.isAdvAudioDist(uuid))) {
BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
authorized = a2dp.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;
if (authorized) {
@@ -332,30 +373,21 @@ class BluetoothEventLoop {
Log.i(TAG, "Rejecting incoming A2DP connection from " + address);
}
} else {
- Log.i(TAG, "Rejecting incoming " + service + " connection from " + address);
+ Log.i(TAG, "Rejecting incoming " + deviceUuid + " connection from " + address);
}
return authorized;
}
- private void onAuthAgentCancel(String address, String service, String uuid) {
+ private void onAgentCancel() {
// We immediately response to DBUS Authorize() so this should not
// usually happen
- log("onAuthAgentCancel(" + address + ", " + service + ", " + uuid + ")");
- }
-
- private void onGetRemoteServiceChannelResult(String address, int channel) {
- IBluetoothDeviceCallback callback = mGetRemoteServiceChannelCallbacks.get(address);
- if (callback != null) {
- mGetRemoteServiceChannelCallbacks.remove(address);
- try {
- callback.onGetRemoteServiceChannelResult(address, channel);
- } catch (RemoteException e) {}
- }
+ log("onAgentCancel");
}
private void onRestartRequired() {
if (mBluetoothService.isEnabled()) {
- Log.e(TAG, "*** A serious error occured (did hcid crash?) - restarting Bluetooth ***");
+ Log.e(TAG, "*** A serious error occured (did bluetoothd crash?) - " +
+ "restarting Bluetooth ***");
mHandler.sendEmptyMessage(EVENT_RESTART_BLUETOOTH);
}
}
@@ -363,4 +395,10 @@ class BluetoothEventLoop {
private static void log(String msg) {
Log.d(TAG, msg);
}
+
+ private native void initializeNativeDataNative();
+ private native void startEventLoopNative();
+ private native void stopEventLoopNative();
+ private native boolean isEventLoopRunningNative();
+ private native void cleanupNativeDataNative();
}
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index 060bcea..373e61f 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -17,15 +17,27 @@
package android.server.search;
import android.app.ISearchManager;
+import android.app.ISearchManagerCallback;
+import android.app.SearchDialog;
+import android.app.SearchManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Configuration;
+import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
/**
* This is a simplified version of the Search Manager service. It no longer handles
@@ -34,16 +46,24 @@ import java.util.List;
* invoked search) to specific searchable activities (where the search will be dispatched).
*/
public class SearchManagerService extends ISearchManager.Stub
+ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener
{
// general debugging support
private static final String TAG = "SearchManagerService";
- private static final boolean DEBUG = false;
+ private static final boolean DBG = false;
// class maintenance and general shared data
private final Context mContext;
private final Handler mHandler;
private boolean mSearchablesDirty;
- private Searchables mSearchables;
+ private final Searchables mSearchables;
+
+ final SearchDialog mSearchDialog;
+ ISearchManagerCallback mCallback = null;
+
+ private final boolean mDisabledOnBoot;
+
+ private static final String DISABLE_SEARCH_PROPERTY = "dev.disablesearchdialog";
/**
* Initializes the Search Manager service in the provided system context.
@@ -56,6 +76,9 @@ public class SearchManagerService extends ISearchManager.Stub
mHandler = new Handler();
mSearchablesDirty = true;
mSearchables = new Searchables(context);
+ mSearchDialog = new SearchDialog(context);
+ mSearchDialog.setOnCancelListener(this);
+ mSearchDialog.setOnDismissListener(this);
// Setup the infrastructure for updating and maintaining the list
// of searchable activities.
@@ -69,6 +92,9 @@ public class SearchManagerService extends ISearchManager.Stub
// After startup settles down, preload the searchables list,
// which will reduce the delay when the search UI is invoked.
mHandler.post(mRunUpdateSearchable);
+
+ // allows disabling of search dialog for stress testing runs
+ mDisabledOnBoot = !TextUtils.isEmpty(SystemProperties.get(DISABLE_SEARCH_PROPERTY));
}
/**
@@ -107,6 +133,7 @@ public class SearchManagerService extends ISearchManager.Stub
* a package add/remove broadcast message.
*/
private void updateSearchables() {
+ if (DBG) debug("updateSearchables()");
mSearchables.buildSearchableList();
mSearchablesDirty = false;
}
@@ -137,6 +164,10 @@ public class SearchManagerService extends ISearchManager.Stub
if (globalSearch) {
si = mSearchables.getDefaultSearchable();
} else {
+ if (launchActivity == null) {
+ Log.e(TAG, "getSearchableInfo(), activity == null");
+ return null;
+ }
si = mSearchables.getSearchableInfo(launchActivity);
}
@@ -150,6 +181,152 @@ public class SearchManagerService extends ISearchManager.Stub
updateSearchablesIfDirty();
return mSearchables.getSearchablesInGlobalSearchList();
}
+ /**
+ * Launches the search UI on the main thread of the service.
+ *
+ * @see SearchManager#startSearch(String, boolean, ComponentName, Bundle, boolean)
+ */
+ public void startSearch(final String initialQuery,
+ final boolean selectInitialQuery,
+ final ComponentName launchActivity,
+ final Bundle appSearchData,
+ final boolean globalSearch,
+ final ISearchManagerCallback searchManagerCallback) {
+ if (DBG) debug("startSearch()");
+ Runnable task = new Runnable() {
+ public void run() {
+ performStartSearch(initialQuery,
+ selectInitialQuery,
+ launchActivity,
+ appSearchData,
+ globalSearch,
+ searchManagerCallback);
+ }
+ };
+ mHandler.post(task);
+ }
+
+ /**
+ * Actually launches the search. This must be called on the service UI thread.
+ */
+ /*package*/ void performStartSearch(String initialQuery,
+ boolean selectInitialQuery,
+ ComponentName launchActivity,
+ Bundle appSearchData,
+ boolean globalSearch,
+ ISearchManagerCallback searchManagerCallback) {
+ if (DBG) debug("performStartSearch()");
+
+ if (mDisabledOnBoot) {
+ Log.d(TAG, "ignoring start search request because " + DISABLE_SEARCH_PROPERTY
+ + " system property is set.");
+ return;
+ }
+
+ mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
+ globalSearch);
+ if (searchManagerCallback != null) {
+ mCallback = searchManagerCallback;
+ }
+ }
+
+ /**
+ * Cancels the search dialog. Can be called from any thread.
+ */
+ public void stopSearch() {
+ if (DBG) debug("stopSearch()");
+ mHandler.post(new Runnable() {
+ public void run() {
+ performStopSearch();
+ }
+ });
+ }
+
+ /**
+ * Cancels the search dialog. Must be called from the service UI thread.
+ */
+ /*package*/ void performStopSearch() {
+ if (DBG) debug("performStopSearch()");
+ mSearchDialog.cancel();
+ }
+
+ /**
+ * Determines if the Search UI is currently displayed.
+ *
+ * @see SearchManager#isVisible()
+ */
+ public boolean isVisible() {
+ return postAndWait(mIsShowing, false, "isShowing()");
+ }
+
+ private final Callable<Boolean> mIsShowing = new Callable<Boolean>() {
+ public Boolean call() {
+ return mSearchDialog.isShowing();
+ }
+ };
+
+ public Bundle onSaveInstanceState() {
+ return postAndWait(mOnSaveInstanceState, null, "onSaveInstanceState()");
+ }
+
+ private final Callable<Bundle> mOnSaveInstanceState = new Callable<Bundle>() {
+ public Bundle call() {
+ if (mSearchDialog.isShowing()) {
+ return mSearchDialog.onSaveInstanceState();
+ } else {
+ return null;
+ }
+ }
+ };
+
+ public void onRestoreInstanceState(final Bundle searchDialogState) {
+ if (searchDialogState != null) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ mSearchDialog.onRestoreInstanceState(searchDialogState);
+ }
+ });
+ }
+ }
+
+ public void onConfigurationChanged(final Configuration newConfig) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ if (mSearchDialog.isShowing()) {
+ mSearchDialog.onConfigurationChanged(newConfig);
+ }
+ }
+ });
+ }
+
+ /**
+ * Called by {@link SearchDialog} when it goes away.
+ */
+ public void onDismiss(DialogInterface dialog) {
+ if (DBG) debug("onDismiss()");
+ if (mCallback != null) {
+ try {
+ mCallback.onDismiss();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "onDismiss() failed: " + ex);
+ }
+ }
+ }
+
+ /**
+ * Called by {@link SearchDialog} when the user or activity cancels search.
+ * When this is called, {@link #onDismiss} is called too.
+ */
+ public void onCancel(DialogInterface dialog) {
+ if (DBG) debug("onCancel()");
+ if (mCallback != null) {
+ try {
+ mCallback.onCancel();
+ } catch (RemoteException ex) {
+ Log.e(TAG, "onCancel() failed: " + ex);
+ }
+ }
+ }
/**
* Returns a list of the searchable activities that handle web searches.
@@ -173,4 +350,34 @@ public class SearchManagerService extends ISearchManager.Stub
public void setDefaultWebSearch(ComponentName component) {
mSearchables.setDefaultWebSearch(component);
}
+
+ /**
+ * Runs an operation on the handler for the service, blocks until it returns,
+ * and returns the value returned by the operation.
+ *
+ * @param <V> Return value type.
+ * @param callable Operation to run.
+ * @param errorResult Value to return if the operations throws an exception.
+ * @param name Operation name to include in error log messages.
+ * @return The value returned by the operation.
+ */
+ private <V> V postAndWait(Callable<V> callable, V errorResult, String name) {
+ FutureTask<V> task = new FutureTask<V>(callable);
+ mHandler.post(task);
+ try {
+ return task.get();
+ } catch (InterruptedException ex) {
+ Log.e(TAG, "Error calling " + name + ": " + ex);
+ return errorResult;
+ } catch (ExecutionException ex) {
+ Log.e(TAG, "Error calling " + name + ": " + ex);
+ return errorResult;
+ }
+ }
+
+ private static void debug(String msg) {
+ Thread thread = Thread.currentThread();
+ Log.d(TAG, msg + " (" + thread.getName() + "-" + thread.getId() + ")");
+ }
+
}
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index c083142..90dfa0b 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -66,6 +66,7 @@ public final class SearchableInfo implements Parcelable {
private final int mSearchInputType;
private final int mSearchImeOptions;
private final boolean mIncludeInGlobalSearch;
+ private final boolean mQueryAfterZeroResults;
private final String mSuggestAuthority;
private final String mSuggestPath;
private final String mSuggestSelection;
@@ -276,6 +277,8 @@ public final class SearchableInfo implements Parcelable {
EditorInfo.IME_ACTION_SEARCH);
mIncludeInGlobalSearch = a.getBoolean(
com.android.internal.R.styleable.Searchable_includeInGlobalSearch, false);
+ mQueryAfterZeroResults = a.getBoolean(
+ com.android.internal.R.styleable.Searchable_queryAfterZeroResults, false);
mSuggestAuthority = a.getString(
com.android.internal.R.styleable.Searchable_searchSuggestAuthority);
@@ -317,7 +320,7 @@ public final class SearchableInfo implements Parcelable {
// for now, implement some form of rules - minimal data
if (mLabelId == 0) {
- throw new IllegalArgumentException("No label.");
+ throw new IllegalArgumentException("Search label must be a resource reference.");
}
}
@@ -438,13 +441,17 @@ public final class SearchableInfo implements Parcelable {
xml.close();
if (DBG) {
- Log.d(LOG_TAG, "Checked " + activityInfo.name
- + ",label=" + searchable.getLabelId()
- + ",icon=" + searchable.getIconId()
- + ",suggestAuthority=" + searchable.getSuggestAuthority()
- + ",target=" + searchable.getSearchActivity().getClassName()
- + ",global=" + searchable.shouldIncludeInGlobalSearch()
- + ",threshold=" + searchable.getSuggestThreshold());
+ if (searchable != null) {
+ Log.d(LOG_TAG, "Checked " + activityInfo.name
+ + ",label=" + searchable.getLabelId()
+ + ",icon=" + searchable.getIconId()
+ + ",suggestAuthority=" + searchable.getSuggestAuthority()
+ + ",target=" + searchable.getSearchActivity().getClassName()
+ + ",global=" + searchable.shouldIncludeInGlobalSearch()
+ + ",threshold=" + searchable.getSuggestThreshold());
+ } else {
+ Log.d(LOG_TAG, "Checked " + activityInfo.name + ", no searchable meta-data");
+ }
}
return searchable;
}
@@ -637,6 +644,17 @@ public final class SearchableInfo implements Parcelable {
}
/**
+ * Checks whether this searchable activity should be invoked after a query returned zero
+ * results.
+ *
+ * @return The value of the <code>queryAfterZeroResults</code> attribute,
+ * or <code>false</code> if the attribute is not set.
+ */
+ public boolean queryAfterZeroResults() {
+ return mQueryAfterZeroResults;
+ }
+
+ /**
* Support for parcelable and aidl operations.
*/
public static final Parcelable.Creator<SearchableInfo> CREATOR
@@ -667,6 +685,7 @@ public final class SearchableInfo implements Parcelable {
mSearchInputType = in.readInt();
mSearchImeOptions = in.readInt();
mIncludeInGlobalSearch = in.readInt() != 0;
+ mQueryAfterZeroResults = in.readInt() != 0;
mSuggestAuthority = in.readString();
mSuggestPath = in.readString();
@@ -702,6 +721,7 @@ public final class SearchableInfo implements Parcelable {
dest.writeInt(mSearchInputType);
dest.writeInt(mSearchImeOptions);
dest.writeInt(mIncludeInGlobalSearch ? 1 : 0);
+ dest.writeInt(mQueryAfterZeroResults ? 1 : 0);
dest.writeString(mSuggestAuthority);
dest.writeString(mSuggestPath);
diff --git a/core/java/android/speech/IRecognitionListener.aidl b/core/java/android/speech/IRecognitionListener.aidl
index b4abfda..2da2258 100644
--- a/core/java/android/speech/IRecognitionListener.aidl
+++ b/core/java/android/speech/IRecognitionListener.aidl
@@ -45,10 +45,8 @@ interface IRecognitionListener {
void onEndOfSpeech();
/**
- * A network or recognition error occurred.
- * TODO: right now, the error code is given in voice search package
- * (vendor/google/apps/src/com/google/android/voicesearch/speechservice/SpeechServiceListener.java)
- * we need to find a place to define common error code.
+ * A network or recognition error occurred. The code is defined in
+ * {@link android.speech.RecognitionResult}
*/
void onError(in int error);
diff --git a/core/java/android/speech/RecognitionResult.java b/core/java/android/speech/RecognitionResult.java
index c3ac484..8d031fc 100644
--- a/core/java/android/speech/RecognitionResult.java
+++ b/core/java/android/speech/RecognitionResult.java
@@ -27,6 +27,17 @@ import android.os.Parcelable;
* {@hide}
*/
public class RecognitionResult implements Parcelable {
+ /**
+ * Status of the recognize request.
+ */
+ public static final int NETWORK_TIMEOUT = 1; // Network operation timed out.
+ public static final int NETWORK_ERROR = 2; // Other networkrelated errors.
+ public static final int AUDIO_ERROR = 3; // Audio recording error.
+ public static final int SERVER_ERROR = 4; // Server sends error status.
+ public static final int CLIENT_ERROR = 5; // Other client side errors.
+ public static final int SPEECH_TIMEOUT = 6; // No speech input
+ public static final int NO_MATCH = 7; // No recognition result matched.
+ public static final int SERVICE_BUSY = 8; // RecognitionService busy.
/**
* Type of the recognition results.
diff --git a/tts/java/android/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
index 1fe4a6a..739a8e4 100755
--- a/tts/java/android/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -1,59 +1,57 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.tts;
-
-import android.tts.ITtsCallback;
-
-import android.content.Intent;
-
-/**
- * AIDL for the TTS Service
- * ITts.java is autogenerated from this.
- *
- * {@hide}
- */
-interface ITts {
- void setEngine(in String engineName, in String[] requestedLanguages, in int strictness);
-
- void setEngineWithIntent(in Intent engineIntent);
-
- void setSpeechRate(in int speechRate);
-
- void speak(in String text, in int queueMode, in String[] params);
-
- boolean isSpeaking();
-
- void stop();
-
- void addSpeech(in String text, in String packageName, in int resId);
-
- void addSpeechFile(in String text, in String filename);
-
- void setLanguage(in String language);
-
- boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
-
- void playEarcon(in String earcon, in int queueMode, in String[] params);
-
- void addEarcon(in String earcon, in String packageName, in int resId);
-
- void addEarconFile(in String earcon, in String filename);
-
- void registerCallback(ITtsCallback cb);
-
- void unregisterCallback(ITtsCallback cb);
-}
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.speech.tts;
+
+import android.speech.tts.ITtsCallback;
+
+import android.content.Intent;
+
+/**
+ * AIDL for the TTS Service
+ * ITts.java is autogenerated from this.
+ *
+ * {@hide}
+ */
+interface ITts {
+ void setSpeechRate(in int speechRate);
+
+ void speak(in String text, in int queueMode, in String[] params);
+
+ boolean isSpeaking();
+
+ void stop();
+
+ void addSpeech(in String text, in String packageName, in int resId);
+
+ void addSpeechFile(in String text, in String filename);
+
+ void setLanguage(in String language);
+
+ boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
+
+ void playEarcon(in String earcon, in int queueMode, in String[] params);
+
+ void addEarcon(in String earcon, in String packageName, in int resId);
+
+ void addEarconFile(in String earcon, in String filename);
+
+ void registerCallback(ITtsCallback cb);
+
+ void unregisterCallback(ITtsCallback cb);
+
+ void playSilence(in long duration, in int queueMode, in String[] params);
+}
diff --git a/tts/java/android/tts/ITtsCallback.aidl b/core/java/android/speech/tts/ITtsCallback.aidl
index 1314010..48ed73e 100755
--- a/tts/java/android/tts/ITtsCallback.aidl
+++ b/core/java/android/speech/tts/ITtsCallback.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tts;
+package android.speech.tts;
/**
* AIDL for the callback from the TTS Service
diff --git a/tts/java/android/tts/Tts.java b/core/java/android/speech/tts/TextToSpeech.java
index 6c8b36d..2c0c09e 100755
--- a/tts/java/android/tts/Tts.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -13,7 +13,10 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package android.tts;
+package android.speech.tts;
+
+import android.speech.tts.ITts;
+import android.speech.tts.ITtsCallback;
import android.content.ComponentName;
import android.content.Context;
@@ -25,32 +28,39 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
+import java.util.HashMap;
+
/**
- * @hide
*
- * Synthesizes speech from text. This abstracts away the complexities of using
- * the TTS service such as setting up the IBinder connection and handling
- * RemoteExceptions, etc.
- *
- * The TTS should always be safe the use; if the user does not have the
- * necessary TTS apk installed, the behavior is that all calls to the TTS act as
- * no-ops.
+ * Synthesizes speech from text.
*
+ * {@hide}
*/
-//FIXME #TTS# review + complete javadoc
-public class Tts {
+//TODO #TTS# review + complete javadoc
+public class TextToSpeech {
+
+ /**
+ * Denotes a successful operation.
+ */
+ public static final int TTS_SUCCESS = 0;
+ /**
+ * Denotes a generic operation failure.
+ */
+ public static final int TTS_ERROR = -1;
+ /**
+ * Denotes a failure due to a missing resource.
+ */
+ public static final int TTS_ERROR_MISSING_RESOURCE = -2;
/**
* Called when the TTS has initialized
*
- * The InitListener must implement the onInit function. onInit is passed the
- * version number of the TTS library that the user has installed; since this
- * is called when the TTS has started, it is a good time to make sure that
- * the user's TTS library is up to date.
+ * The InitListener must implement the onInit function. onInit is passed a
+ * status code indicating the result of the TTS initialization.
*/
public interface OnInitListener {
- public void onInit(int version);
+ public void onInit(int status);
}
/**
@@ -67,74 +77,45 @@ public class Tts {
*/
private ServiceConnection serviceConnection;
- private ITts itts = null;
- private Context ctx = null;
- private OnInitListener cb = null;
- private int version = -1;
- private boolean started = false;
- private final Object startLock = new Object();
- private boolean showInstaller = false;
- private ITtsCallback ittscallback;
- private OnSpeechCompletedListener speechCompletedCallback = null;
+ private ITts mITts = null;
+ private Context mContext = null;
+ private OnInitListener mInitListener = null;
+ private boolean mStarted = false;
+ private final Object mStartLock = new Object();
+ private ITtsCallback mITtsCallback;
+ private OnSpeechCompletedListener mSpeechCompListener = null;
+ private final Object mSpeechCompListenerLock = new Object();
- /**
- * The constructor for the TTS.
- *
- * @param context
- * The context
- * @param callback
- * The InitListener that should be called when the TTS has
- * initialized successfully.
- * @param displayInstallMessage
- * Boolean indicating whether or not an installation prompt
- * should be displayed to users who do not have the TTS library.
- * If this is true, a generic alert asking the user to install
- * the TTS will be used. If you wish to specify the exact message
- * of that prompt, please use TTS(Context context, InitListener
- * callback, TTSVersionAlert alert) as the constructor instead.
- */
- public Tts(Context context, OnInitListener callback,
- boolean displayInstallMessage) {
- showInstaller = displayInstallMessage;
- ctx = context;
- cb = callback;
- if (dataFilesCheck()) {
- initTts();
- }
- }
/**
* The constructor for the TTS.
*
* @param context
* The context
- * @param callback
- * The InitListener that should be called when the TTS has
+ * @param listener
+ * The InitListener that will be called when the TTS has
* initialized successfully.
*/
- public Tts(Context context, OnInitListener callback) {
- // FIXME #TTS# support TtsVersionAlert
- // showInstaller = true;
- // versionAlert = alert;
- ctx = context;
- cb = callback;
- if (dataFilesCheck()) {
- initTts();
- }
+ public TextToSpeech(Context context, OnInitListener listener) {
+ mContext = context;
+ mInitListener = listener;
+ initTts();
}
public void setOnSpeechCompletedListener(
final OnSpeechCompletedListener listener) {
- speechCompletedCallback = listener;
+ synchronized(mSpeechCompListenerLock) {
+ mSpeechCompListener = listener;
+ }
}
private boolean dataFilesCheck() {
- // FIXME #TTS# config manager will be in settings
+ // TODO #TTS# config manager will be in settings
Log.i("TTS_FIXME", "FIXME in Tts: config manager will be in settings");
- // FIXME #TTS# implement checking of the correct installation of
+ // TODO #TTS# implement checking of the correct installation of
// the data files.
return true;
@@ -142,62 +123,63 @@ public class Tts {
private void initTts() {
- started = false;
+ mStarted = false;
// Initialize the TTS, run the callback after the binding is successful
serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
- synchronized(startLock) {
- itts = ITts.Stub.asInterface(service);
+ synchronized(mStartLock) {
+ mITts = ITts.Stub.asInterface(service);
try {
- ittscallback = new ITtsCallback.Stub() {
- //@Override
+ mITtsCallback = new ITtsCallback.Stub() {
public void markReached(String mark)
throws RemoteException {
- if (speechCompletedCallback != null) {
- speechCompletedCallback.onSpeechCompleted();
+ // call the listener of that event, but not
+ // while locked.
+ OnSpeechCompletedListener listener = null;
+ synchronized(mSpeechCompListenerLock) {
+ listener = mSpeechCompListener;
+ }
+ if (listener != null) {
+ listener.onSpeechCompleted();
}
}
};
- itts.registerCallback(ittscallback);
+ mITts.registerCallback(mITtsCallback);
} catch (RemoteException e) {
initTts();
return;
}
- started = true;
+ mStarted = true;
// The callback can become null if the Android OS decides to
// restart the TTS process as well as whatever is using it.
// In such cases, do nothing - the error handling from the
// speaking calls will kick in and force a proper restart of
// the TTS.
- if (cb != null) {
- cb.onInit(version);
+ if (mInitListener != null) {
+ // TODO manage failures and missing resources
+ mInitListener.onInit(TTS_SUCCESS);
}
}
}
public void onServiceDisconnected(ComponentName name) {
- synchronized(startLock) {
- itts = null;
- cb = null;
- started = false;
+ synchronized(mStartLock) {
+ mITts = null;
+ mInitListener = null;
+ mStarted = false;
}
}
};
Intent intent = new Intent("android.intent.action.USE_TTS");
intent.addCategory("android.intent.category.TTS");
- // Binding will fail only if the TTS doesn't exist;
- // the TTSVersionAlert will give users a chance to install
- // the needed TTS.
- if (!ctx.bindService(intent, serviceConnection,
- Context.BIND_AUTO_CREATE)) {
- if (showInstaller) {
- // FIXME #TTS# show version alert
- }
- }
+ mContext.bindService(intent, serviceConnection,
+ Context.BIND_AUTO_CREATE);
+ // TODO handle case where the binding works (should always work) but
+ // the plugin fails
}
@@ -208,7 +190,7 @@ public class Tts {
*/
public void shutdown() {
try {
- ctx.unbindService(serviceConnection);
+ mContext.unbindService(serviceConnection);
} catch (IllegalArgumentException e) {
// Do nothing and fail silently since an error here indicates that
// binding never succeeded in the first place.
@@ -242,23 +224,23 @@ public class Tts {
* Example: <b><code>R.raw.south_south_east</code></b>
*/
public void addSpeech(String text, String packagename, int resourceId) {
- synchronized(startLock) {
- if (!started) {
+ synchronized(mStartLock) {
+ if (!mStarted) {
return;
}
try {
- itts.addSpeech(text, packagename, resourceId);
+ mITts.addSpeech(text, packagename, resourceId);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
@@ -276,23 +258,23 @@ public class Tts {
* "/sdcard/mysounds/hello.wav")
*/
public void addSpeech(String text, String filename) {
- synchronized (startLock) {
- if (!started) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return;
}
try {
- itts.addSpeechFile(text, filename);
+ mITts.addSpeechFile(text, filename);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
@@ -312,32 +294,29 @@ public class Tts {
* The queuing strategy to use. Use 0 for no queuing, and 1 for
* queuing.
* @param params
- * The array of speech parameters to be used. Currently, only
- * params[0] is defined - it is for setting the type of voice if
- * the engine allows it. Possible values are "VOICE_MALE",
- * "VOICE_FEMALE", and "VOICE_ROBOT". Note that right now only
- * the pre-recorded voice has this support - this setting has no
- * effect on eSpeak.
+ * The hashmap of speech parameters to be used.
*/
- public void speak(String text, int queueMode, String[] params) {
- synchronized (startLock) {
+ public void speak(String text, int queueMode, HashMap<String,String> params)
+ {
+ synchronized (mStartLock) {
Log.i("TTS received: ", text);
- if (!started) {
+ if (!mStarted) {
return;
}
try {
- itts.speak(text, queueMode, params);
+ // TODO support extra parameters, passing null for the moment
+ mITts.speak(text, queueMode, null);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
@@ -353,30 +332,37 @@ public class Tts {
* 0 for no queue (interrupts all previous utterances), 1 for
* queued
* @param params
- * An ArrayList of parameters.
+ * The hashmap of parameters to be used.
*/
- public void playEarcon(String earcon, int queueMode, String[] params) {
- synchronized (startLock) {
- if (!started) {
+ public void playEarcon(String earcon, int queueMode,
+ HashMap<String,String> params) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return;
}
try {
- itts.playEarcon(earcon, queueMode, params);
+ // TODO support extra parameters, passing null for the moment
+ mITts.playEarcon(earcon, queueMode, null);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
}
+
+
+ public void playSilence(long durationInMs, int queueMode) {
+ // TODO implement, already present in TTS service
+ }
/**
@@ -385,23 +371,23 @@ public class Tts {
* @return Whether or not the TTS is busy speaking.
*/
public boolean isSpeaking() {
- synchronized (startLock) {
- if (!started) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return false;
}
try {
- return itts.isSpeaking();
+ return mITts.isSpeaking();
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
return false;
@@ -413,62 +399,29 @@ public class Tts {
* Stops speech from the TTS.
*/
public void stop() {
- synchronized (startLock) {
- if (!started) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return;
}
try {
- itts.stop();
+ mITts.stop();
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
}
- /**
- * Returns the version number of the TTS library that the user has
- * installed.
- *
- * @return The version number of the TTS library that the user has
- * installed.
- */
- public int getVersion() {
- return version;
- }
-
-
- /**
- * Sets the TTS engine to be used.
- *
- * @param selectedEngine
- * The TTS engine that should be used.
- */
- public void setEngine(String engineName, String[] requestedLanguages, int strictness) {
- synchronized (startLock) {
- if (!started) {
- return;
- }
- try {
- itts.setEngine(engineName, requestedLanguages, strictness);
- } catch (RemoteException e) {
- // TTS died; restart it.
- started = false;
- initTts();
- }
- }
- }
-
/**
* Sets the speech rate for the TTS engine.
@@ -484,15 +437,15 @@ public class Tts {
* The speech rate for the TTS engine.
*/
public void setSpeechRate(int speechRate) {
- synchronized (startLock) {
- if (!started) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return;
}
try {
- itts.setSpeechRate(speechRate);
+ mITts.setSpeechRate(speechRate);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
@@ -516,15 +469,15 @@ public class Tts {
* http://en.wikipedia.org/wiki/IETF_language_tag
*/
public void setLanguage(String language) {
- synchronized (startLock) {
- if (!started) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return;
}
try {
- itts.setLanguage(language);
+ mITts.setLanguage(language);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
}
@@ -537,32 +490,32 @@ public class Tts {
* @param text
* The String of text that should be synthesized
* @param params
- * An ArrayList of parameters. The first element of this array
- * controls the type of voice to use.
+ * A hashmap of parameters.
* @param filename
* The string that gives the full output filename; it should be
* something like "/sdcard/myappsounds/mysound.wav".
* @return A boolean that indicates if the synthesis succeeded
*/
- public boolean synthesizeToFile(String text, String[] params,
+ public boolean synthesizeToFile(String text, HashMap<String,String> params,
String filename) {
- synchronized (startLock) {
- if (!started) {
+ synchronized (mStartLock) {
+ if (!mStarted) {
return false;
}
try {
- return itts.synthesizeToFile(text, params, filename);
+ // TODO support extra parameters, passing null for the moment
+ return mITts.synthesizeToFile(text, null, filename);
} catch (RemoteException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (NullPointerException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
} catch (IllegalStateException e) {
// TTS died; restart it.
- started = false;
+ mStarted = false;
initTts();
}
return false;
@@ -570,36 +523,4 @@ public class Tts {
}
- /**
- * Displays an alert that prompts users to install the TTS engine.
- * This is useful if the application expects a newer version
- * of the TTS than what the user has.
- */
- public void showVersionAlert() {
- if (!started) {
- return;
- }
- // FIXME #TTS# implement show version alert
- }
-
-
- /**
- * Checks if the TTS service is installed or not
- *
- * @return A boolean that indicates whether the TTS service is installed
- */
- // TODO: TTS Service itself will always be installed. Factor this out
- // (may need to add another method to see if there are any working
- // TTS engines on the device).
- public static boolean isInstalled(Context ctx) {
- PackageManager pm = ctx.getPackageManager();
- Intent intent = new Intent("android.intent.action.USE_TTS");
- intent.addCategory("android.intent.category.TTS");
- ResolveInfo info = pm.resolveService(intent, 0);
- if (info == null) {
- return false;
- }
- return true;
- }
-
}
diff --git a/core/java/android/test/AndroidTestCase.java b/core/java/android/test/AndroidTestCase.java
index 9bafa32..de0587a 100644
--- a/core/java/android/test/AndroidTestCase.java
+++ b/core/java/android/test/AndroidTestCase.java
@@ -16,12 +16,14 @@
package android.test;
+import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import junit.framework.TestCase;
import java.lang.reflect.Field;
-import junit.framework.TestCase;
-
/**
* Extend this if you need to access Resources or other things that depend on Activity Context.
*/
@@ -53,6 +55,72 @@ public class AndroidTestCase extends TestCase {
}
/**
+ * Asserts that launching a given activity is protected by a particular permission by
+ * attempting to start the activity and validating that a {@link SecurityException}
+ * is thrown that mentions the permission in its error message.
+ *
+ * Note that an instrumentation isn't needed because all we are looking for is a security error
+ * and we don't need to wait for the activity to launch and get a handle to the activity.
+ *
+ * @param packageName The package name of the activity to launch.
+ * @param className The class of the activity to launch.
+ * @param permission The name of the permission.
+ */
+ public void assertActivityRequiresPermission(
+ String packageName, String className, String permission) {
+ final Intent intent = new Intent();
+ intent.setClassName(packageName, className);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ try {
+ getContext().startActivity(intent);
+ fail("expected security exception for " + permission);
+ } catch (SecurityException expected) {
+ assertNotNull("security exception's error message.", expected.getMessage());
+ assertTrue("error message should contain " + permission + ".",
+ expected.getMessage().contains(permission));
+ }
+ }
+
+
+ /**
+ * Asserts that reading from the content uri requires a particular permission by querying the
+ * uri and ensuring a {@link SecurityException} is thrown mentioning the particular permission.
+ *
+ * @param uri The uri that requires a permission to query.
+ * @param permission The permission that should be required.
+ */
+ public void assertReadingContentUriRequiresPermission(Uri uri, String permission) {
+ try {
+ getContext().getContentResolver().query(uri, null, null, null, null);
+ fail("expected SecurityException requiring " + permission);
+ } catch (SecurityException expected) {
+ assertNotNull("security exception's error message.", expected.getMessage());
+ assertTrue("error message should contain " + permission + ".",
+ expected.getMessage().contains(permission));
+ }
+ }
+
+ /**
+ * Asserts that writing to the content uri requires a particular permission by inserting into
+ * the uri and ensuring a {@link SecurityException} is thrown mentioning the particular
+ * permission.
+ *
+ * @param uri The uri that requires a permission to query.
+ * @param permission The permission that should be required.
+ */
+ public void assertWritingContentUriRequiresPermission(Uri uri, String permission) {
+ try {
+ getContext().getContentResolver().insert(uri, new ContentValues());
+ fail("expected SecurityException requiring " + permission);
+ } catch (SecurityException expected) {
+ assertNotNull("security exception's error message.", expected.getMessage());
+ assertTrue("error message should contain " + permission + ".",
+ expected.getMessage().contains(permission));
+ }
+ }
+
+ /**
* This function is called by various TestCase implementations, at tearDown() time, in order
* to scrub out any class variables. This protects against memory leaks in the case where a
* test case creates a non-static inner class (thus referencing the test case) and gives it to
diff --git a/core/java/android/text/LoginFilter.java b/core/java/android/text/LoginFilter.java
index 27c703f..9045c09 100644
--- a/core/java/android/text/LoginFilter.java
+++ b/core/java/android/text/LoginFilter.java
@@ -49,10 +49,6 @@ public abstract class LoginFilter implements InputFilter {
*/
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
- char[] out = new char[end - start]; // reserve enough space for whole string
- int outidx = 0;
- boolean changed = false;
-
onStart();
// Scan through beginning characters in dest, calling onInvalidCharacter()
@@ -63,14 +59,26 @@ public abstract class LoginFilter implements InputFilter {
}
// Scan through changed characters rejecting disallowed chars
+ SpannableStringBuilder modification = null;
+ int modoff = 0;
+
for (int i = start; i < end; i++) {
char c = source.charAt(i);
if (isAllowed(c)) {
- // Character allowed. Add it to the sequence.
- out[outidx++] = c;
+ // Character allowed.
+ modoff++;
} else {
- if (mAppendInvalid) out[outidx++] = c;
- else changed = true; // we changed the original string
+ if (mAppendInvalid) {
+ modoff++;
+ } else {
+ if (modification == null) {
+ modification = new SpannableStringBuilder(source, start, end);
+ modoff = i - start;
+ }
+
+ modification.delete(modoff, modoff + 1);
+ }
+
onInvalidCharacter(c);
}
}
@@ -84,20 +92,9 @@ public abstract class LoginFilter implements InputFilter {
onStop();
- if (!changed) {
- return null;
- }
-
- String s = new String(out, 0, outidx);
-
- if (source instanceof Spanned) {
- SpannableString sp = new SpannableString(s);
- TextUtils.copySpansFrom((Spanned) source,
- start, end, null, sp, 0);
- return sp;
- } else {
- return s;
- }
+ // Either returns null if we made no changes,
+ // or what we wanted to change it to if there were changes.
+ return modification;
}
/**
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 5b4c380..53096dd 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -916,6 +916,17 @@ public class TextUtils {
sp.setSpan(o, p.readInt(), p.readInt(), p.readInt());
}
+ /**
+ * Copies the spans from the region <code>start...end</code> in
+ * <code>source</code> to the region
+ * <code>destoff...destoff+end-start</code> in <code>dest</code>.
+ * Spans in <code>source</code> that begin before <code>start</code>
+ * or end after <code>end</code> but overlap this range are trimmed
+ * as if they began at <code>start</code> or ended at <code>end</code>.
+ *
+ * @throws IndexOutOfBoundsException if any of the copied spans
+ * are out of range in <code>dest</code>.
+ */
public static void copySpansFrom(Spanned source, int start, int end,
Class kind,
Spannable dest, int destoff) {
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 3156d8b..3d10f17 100644
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -242,27 +242,85 @@ public class DateFormat {
/**
* Returns a {@link java.text.DateFormat} object that can format the time according
- * to the current locale.
+ * to the current locale and the user's 12-/24-hour clock preference.
* @param context the application context
* @return the {@link java.text.DateFormat} object that properly formats the time.
*/
public static final java.text.DateFormat getTimeFormat(Context context) {
- return java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
+ boolean b24 = is24HourFormat(context);
+ int res;
+
+ if (b24) {
+ res = R.string.twenty_four_hour_time_format;
+ } else {
+ res = R.string.twelve_hour_time_format;
+ }
+
+ return new java.text.SimpleDateFormat(context.getString(res));
}
/**
* Returns a {@link java.text.DateFormat} object that can format the date
* in short form (such as 12/31/1999) according
- * to the current locale.
+ * to the current locale and the user's date-order preference.
* @param context the application context
* @return the {@link java.text.DateFormat} object that properly formats the date.
*/
public static final java.text.DateFormat getDateFormat(Context context) {
+ String value = Settings.System.getString(context.getContentResolver(),
+ Settings.System.DATE_FORMAT);
+
+ return getDateFormatForSetting(context, value);
+ }
+
+ /**
+ * Returns a {@link java.text.DateFormat} object to format the date
+ * as if the date format setting were set to <code>value</code>,
+ * including null to use the locale's default format.
+ * @param context the application context
+ * @param value the date format setting string to interpret for
+ * the current locale
+ * @hide
+ */
+ public static java.text.DateFormat getDateFormatForSetting(Context context,
+ String value) {
+ if (value != null) {
+ int month = value.indexOf('M');
+ int day = value.indexOf('d');
+ int year = value.indexOf('y');
+
+ if (month >= 0 && day >= 0 && year >= 0) {
+ String template = context.getString(R.string.numeric_date_template);
+ if (year < month) {
+ if (month < day) {
+ value = String.format(template, "yyyy", "MM", "dd");
+ } else {
+ value = String.format(template, "yyyy", "dd", "MM");
+ }
+ } else if (month < day) {
+ if (day < year) {
+ value = String.format(template, "MM", "dd", "yyyy");
+ } else { // unlikely
+ value = String.format(template, "MM", "yyyy", "dd");
+ }
+ } else { // day < month
+ if (month < year) {
+ value = String.format(template, "dd", "MM", "yyyy");
+ } else { // unlikely
+ value = String.format(template, "dd", "yyyy", "MM");
+ }
+ }
+
+ return new java.text.SimpleDateFormat(value);
+ }
+ }
+
/*
+ * The setting is not set; use the default.
* We use a resource string here instead of just DateFormat.SHORT
* so that we get a four-digit year instead a two-digit year.
*/
- String value = context.getString(R.string.numeric_date_format);
+ value = context.getString(R.string.numeric_date_format);
return new java.text.SimpleDateFormat(value);
}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 9073d82..bccb3a6 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -147,6 +147,9 @@ public class DateUtils
public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
+ /**
+ * This constant is actually the length of 364 days, not of a year!
+ */
public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;
// The following FORMAT_* symbols are used for specifying the format of
@@ -176,6 +179,9 @@ public class DateUtils
// Date and time format strings that are constant and don't need to be
// translated.
+ /**
+ * This is not actually the preferred 24-hour date format in all locales.
+ */
public static final String HOUR_MINUTE_24 = "%H:%M";
public static final String MONTH_FORMAT = "%B";
public static final String ABBREV_MONTH_FORMAT = "%b";
@@ -1106,7 +1112,9 @@ public class DateUtils
*
* <p>
* If FORMAT_CAP_AMPM is set and 12-hour time is used, then the "AM"
- * and "PM" are capitalized.
+ * and "PM" are capitalized. You should not use this flag
+ * because in some locales these terms cannot be capitalized, and in
+ * many others it doesn't make sense to do so even though it is possible.
*
* <p>
* If FORMAT_NO_NOON is set and 12-hour time is used, then "12pm" is
@@ -1114,15 +1122,19 @@ public class DateUtils
*
* <p>
* If FORMAT_CAP_NOON is set and 12-hour time is used, then "Noon" is
- * shown instead of "noon".
+ * shown instead of "noon". You should probably not use this flag
+ * because in many locales it will not make sense to capitalize
+ * the term.
*
* <p>
* If FORMAT_NO_MIDNIGHT is set and 12-hour time is used, then "12am" is
* shown instead of "midnight".
*
* <p>
- * If FORMAT_CAP_NOON is set and 12-hour time is used, then "Midnight" is
- * shown instead of "midnight".
+ * If FORMAT_CAP_MIDNIGHT is set and 12-hour time is used, then "Midnight"
+ * is shown instead of "midnight". You should probably not use this
+ * flag because in many locales it will not make sense to capitalize
+ * the term.
*
* <p>
* If FORMAT_12HOUR is set and the time is shown, then the time is
@@ -1264,8 +1276,8 @@ public class DateUtils
use24Hour = DateFormat.is24HourFormat(context);
}
if (use24Hour) {
- startTimeFormat = HOUR_MINUTE_24;
- endTimeFormat = HOUR_MINUTE_24;
+ startTimeFormat = endTimeFormat =
+ res.getString(com.android.internal.R.string.hour_minute_24);
} else {
boolean abbrevTime = (flags & (FORMAT_ABBREV_TIME | FORMAT_ABBREV_ALL)) != 0;
boolean capAMPM = (flags & FORMAT_CAP_AMPM) != 0;
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 1b30aa0..367b26c 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -59,9 +59,15 @@ public final class Formatter {
result = result / 1024;
}
if (result < 100) {
- return String.format("%.2f%s", result, context.getText(suffix).toString());
+ String value = String.format("%.2f", result);
+ return context.getResources().
+ getString(com.android.internal.R.string.fileSizeSuffix,
+ value, context.getString(suffix));
}
- return String.format("%.0f%s", result, context.getText(suffix).toString());
+ String value = String.format("%.0f", result);
+ return context.getResources().
+ getString(com.android.internal.R.string.fileSizeSuffix,
+ value, context.getString(suffix));
}
/**
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 987be2b..245148d 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -103,10 +103,10 @@ public class DisplayMetrics {
}
/**
- * Update the display metrics based on the compatibility info and configuration.
+ * Update the display metrics based on the compatibility info and orientation
* {@hide}
*/
- public void updateMetrics(CompatibilityInfo compatibilityInfo, Configuration configuration) {
+ public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
if (compatibilityInfo.mScalingRequired) {
float invertedRatio = compatibilityInfo.mApplicationInvertedScale;
density *= invertedRatio;
@@ -116,31 +116,42 @@ public class DisplayMetrics {
widthPixels *= invertedRatio;
heightPixels *= invertedRatio;
}
- if (!compatibilityInfo.mExpandable) {
+ if (!compatibilityInfo.mConfiguredExpandable) {
// Note: this assume that configuration is updated before calling
// updateMetrics method.
int defaultWidth;
int defaultHeight;
- switch (configuration.orientation) {
+ switch (orientation) {
case Configuration.ORIENTATION_LANDSCAPE: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
break;
}
- case Configuration.ORIENTATION_UNDEFINED:
case Configuration.ORIENTATION_PORTRAIT:
case Configuration.ORIENTATION_SQUARE:
default: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
+ break;
+ }
+ case Configuration.ORIENTATION_UNDEFINED: {
+ // don't change
+ return;
}
}
- // adjust the size only when the device's screen is bigger.
- if (defaultWidth < widthPixels) {
- widthPixels = defaultWidth;
- }
- if (defaultHeight < heightPixels) {
- heightPixels = defaultHeight;
+
+ if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
+ // the screen size is same as expected size. make it expandable
+ compatibilityInfo.mExpandable = true;
+ } else {
+ compatibilityInfo.mExpandable = false;
+ // adjust the size only when the device's screen is bigger.
+ if (defaultWidth < widthPixels) {
+ widthPixels = defaultWidth;
+ }
+ if (defaultHeight < heightPixels) {
+ heightPixels = defaultHeight;
+ }
}
}
}
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 24b4f73..7c87248 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -192,17 +192,21 @@ public class EventLog {
return decodeObject();
}
+ public byte[] getRawData() {
+ return mBuffer.array();
+ }
+
/** @return the loggable item at the current position in mBuffer. */
private Object decodeObject() {
if (mBuffer.remaining() < 1) return null;
switch (mBuffer.get()) {
case INT:
if (mBuffer.remaining() < 4) return null;
- return mBuffer.getInt();
+ return (Integer) mBuffer.getInt();
case LONG:
if (mBuffer.remaining() < 8) return null;
- return mBuffer.getLong();
+ return (Long) mBuffer.getLong();
case STRING:
try {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index f1bf0f4..69c6a7c 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -58,32 +58,32 @@ public final class MotionEvent implements Parcelable {
public static final int ACTION_OUTSIDE = 4;
private static final boolean TRACK_RECYCLED_LOCATION = false;
-
+
/**
* Flag indicating the motion event intersected the top edge of the screen.
*/
public static final int EDGE_TOP = 0x00000001;
-
+
/**
* Flag indicating the motion event intersected the bottom edge of the screen.
*/
public static final int EDGE_BOTTOM = 0x00000002;
-
+
/**
* Flag indicating the motion event intersected the left edge of the screen.
*/
public static final int EDGE_LEFT = 0x00000004;
-
+
/**
* Flag indicating the motion event intersected the right edge of the screen.
*/
public static final int EDGE_RIGHT = 0x00000008;
-
+
static private final int MAX_RECYCLED = 10;
static private Object gRecyclerLock = new Object();
static private int gRecyclerUsed = 0;
static private MotionEvent gRecyclerTop = null;
-
+
private long mDownTime;
private long mEventTime;
private long mEventTimeNano;
@@ -109,7 +109,7 @@ public final class MotionEvent implements Parcelable {
private MotionEvent() {
}
-
+
static private MotionEvent obtain() {
synchronized (gRecyclerLock) {
if (gRecyclerTop == null) {
@@ -183,22 +183,22 @@ public final class MotionEvent implements Parcelable {
/**
* Create a new MotionEvent, filling in all of the basic values that
* define the motion.
- *
- * @param downTime The time (in ms) when the user originally pressed down to start
+ *
+ * @param downTime The time (in ms) when the user originally pressed down to start
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param eventTime The the time (in ms) when this specific event was generated. This
+ * @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
* @param action The kind of action being performed -- one of either
* {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
* {@link #ACTION_CANCEL}.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
- * @param pressure The current pressure of this event. The pressure generally
- * ranges from 0 (no pressure at all) to 1 (normal pressure), however
- * values higher than 1 may be generated depending on the calibration of
+ * @param pressure The current pressure of this event. The pressure generally
+ * ranges from 0 (no pressure at all) to 1 (normal pressure), however
+ * values higher than 1 may be generated depending on the calibration of
* the input device.
* @param size A scaled value of the approximate size of the area being pressed when
- * touched with the finger. The actual value in pixels corresponding to the finger
+ * touched with the finger. The actual value in pixels corresponding to the finger
* touch is normalized with a device specific range of values
* and scaled to a value between 0 and 1.
* @param metaState The state of any meta / modifier keys that were in effect when
@@ -231,15 +231,15 @@ public final class MotionEvent implements Parcelable {
return ev;
}
-
+
/**
* Create a new MotionEvent, filling in a subset of the basic motion
* values. Those not specified here are: device id (always 0), pressure
* and size (always 1), x and y precision (always 1), and edgeFlags (always 0).
- *
- * @param downTime The time (in ms) when the user originally pressed down to start
+ *
+ * @param downTime The time (in ms) when the user originally pressed down to start
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param eventTime The the time (in ms) when this specific event was generated. This
+ * @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
* @param action The kind of action being performed -- one of either
* {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
@@ -287,9 +287,10 @@ public final class MotionEvent implements Parcelable {
float[] history = mHistory;
int length = history.length;
for (int i = 0; i < length; i += 4) {
- history[i] *= scale;
- history[i + 2] *= scale;
- history[i + 3] *= scale;
+ history[i] *= scale; // X
+ // history[i + 2] == pressure
+ history[i + 1] *= scale; // Y
+ history[i + 3] *= scale; // Size, TODO: square this?
}
}
}
@@ -324,7 +325,7 @@ public final class MotionEvent implements Parcelable {
}
return ev;
}
-
+
/**
* Recycle the MotionEvent, to be re-used by a later caller. After calling
* this function you must not ever touch the event again.
@@ -350,7 +351,7 @@ public final class MotionEvent implements Parcelable {
}
}
}
-
+
/**
* Return the kind of action being performed -- one of either
* {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
@@ -361,8 +362,8 @@ public final class MotionEvent implements Parcelable {
}
/**
- * Returns the time (in ms) when the user originally pressed down to start
- * a stream of position events.
+ * Returns the time (in ms) when the user originally pressed down to start
+ * a stream of position events.
*/
public final long getDownTime() {
return mDownTime;
@@ -376,6 +377,7 @@ public final class MotionEvent implements Parcelable {
}
/**
+<<<<<<< HEAD:core/java/android/view/MotionEvent.java
* Returns the time (in ns) when this specific event was generated.
* The value is in nanosecond precision but it may not have nanosecond accuracy.
*
@@ -388,23 +390,30 @@ public final class MotionEvent implements Parcelable {
/**
* Returns the X coordinate of this event. Whole numbers are pixels; the
* value may have a fraction for input devices that are sub-pixel precise.
+|||||||
+ * Returns the X coordinate of this event. Whole numbers are pixels; the
+ * value may have a fraction for input devices that are sub-pixel precise.
+=======
+ * Returns the X coordinate of this event. Whole numbers are pixels; the
+ * value may have a fraction for input devices that are sub-pixel precise.
+>>>>>>> cafdea61a85c8f5d0646cc9413a09346c637f43f:core/java/android/view/MotionEvent.java
*/
public final float getX() {
return mX;
}
/**
- * Returns the Y coordinate of this event. Whole numbers are pixels; the
- * value may have a fraction for input devices that are sub-pixel precise.
+ * Returns the Y coordinate of this event. Whole numbers are pixels; the
+ * value may have a fraction for input devices that are sub-pixel precise.
*/
public final float getY() {
return mY;
}
/**
- * Returns the current pressure of this event. The pressure generally
- * ranges from 0 (no pressure at all) to 1 (normal pressure), however
- * values higher than 1 may be generated depending on the calibration of
+ * Returns the current pressure of this event. The pressure generally
+ * ranges from 0 (no pressure at all) to 1 (normal pressure), however
+ * values higher than 1 may be generated depending on the calibration of
* the input device.
*/
public final float getPressure() {
@@ -413,9 +422,9 @@ public final class MotionEvent implements Parcelable {
/**
* Returns a scaled value of the approximate size, of the area being pressed when
- * touched with the finger. The actual value in pixels corresponding to the finger
+ * touched with the finger. The actual value in pixels corresponding to the finger
* touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1. The value of size can be used to
+ * and scaled to a value between 0 and 1. The value of size can be used to
* determine fat touch events.
*/
public final float getSize() {
@@ -465,7 +474,7 @@ public final class MotionEvent implements Parcelable {
public final float getXPrecision() {
return mXPrecision;
}
-
+
/**
* Return the precision of the Y coordinates being reported. You can
* multiple this number with {@link #getY} to find the actual hardware
@@ -475,89 +484,89 @@ public final class MotionEvent implements Parcelable {
public final float getYPrecision() {
return mYPrecision;
}
-
+
/**
* Returns the number of historical points in this event. These are
* movements that have occurred between this event and the previous event.
* This only applies to ACTION_MOVE events -- all other actions will have
* a size of 0.
- *
+ *
* @return Returns the number of historical points in the event.
*/
public final int getHistorySize() {
return mNumHistory;
}
-
+
/**
* Returns the time that a historical movement occurred between this event
* and the previous event. Only applies to ACTION_MOVE events.
- *
+ *
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
+ *
* @see #getHistorySize
* @see #getEventTime
*/
public final long getHistoricalEventTime(int pos) {
return mHistoryTimes[pos];
}
-
+
/**
* Returns a historical X coordinate that occurred between this event
* and the previous event. Only applies to ACTION_MOVE events.
- *
+ *
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
+ *
* @see #getHistorySize
* @see #getX
*/
public final float getHistoricalX(int pos) {
return mHistory[pos*4];
}
-
+
/**
* Returns a historical Y coordinate that occurred between this event
* and the previous event. Only applies to ACTION_MOVE events.
- *
+ *
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
+ *
* @see #getHistorySize
* @see #getY
*/
public final float getHistoricalY(int pos) {
return mHistory[pos*4 + 1];
}
-
+
/**
* Returns a historical pressure coordinate that occurred between this event
* and the previous event. Only applies to ACTION_MOVE events.
- *
+ *
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
+ *
* @see #getHistorySize
* @see #getPressure
*/
public final float getHistoricalPressure(int pos) {
return mHistory[pos*4 + 2];
}
-
+
/**
* Returns a historical size coordinate that occurred between this event
* and the previous event. Only applies to ACTION_MOVE events.
- *
+ *
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
+ *
* @see #getHistorySize
* @see #getSize
*/
public final float getHistoricalSize(int pos) {
return mHistory[pos*4 + 3];
}
-
+
/**
* Return the id for the device that this event came from. An id of
* zero indicates that the event didn't come from a physical device; other
@@ -566,12 +575,12 @@ public final class MotionEvent implements Parcelable {
public final int getDeviceId() {
return mDeviceId;
}
-
+
/**
* Returns a bitfield indicating which edges, if any, where touched by this
- * MotionEvent. For touch events, clients can use this to determine if the
- * user's finger was touching the edge of the display.
- *
+ * MotionEvent. For touch events, clients can use this to determine if the
+ * user's finger was touching the edge of the display.
+ *
* @see #EDGE_LEFT
* @see #EDGE_TOP
* @see #EDGE_RIGHT
@@ -580,12 +589,12 @@ public final class MotionEvent implements Parcelable {
public final int getEdgeFlags() {
return mEdgeFlags;
}
-
+
/**
* Sets the bitfield indicating which edges, if any, where touched by this
- * MotionEvent.
- *
+ * MotionEvent.
+ *
* @see #getEdgeFlags()
*/
public final void setEdgeFlags(int flags) {
@@ -617,11 +626,11 @@ public final class MotionEvent implements Parcelable {
pos[i+1] += deltaY;
}
}
-
+
/**
* Set this event's location. Applies {@link #offsetLocation} with a
* delta from the current location to the given new location.
- *
+ *
* @param x New absolute X location.
* @param y New absolute Y location.
*/
@@ -632,13 +641,13 @@ public final class MotionEvent implements Parcelable {
offsetLocation(deltaX, deltaY);
}
}
-
+
/**
* Add a new movement to the batch of movements in this event. The event's
* current location, position and size is updated to the new values. In
* the future, the current values in the event will be added to a list of
* historic values.
- *
+ *
* @param x The new X position.
* @param y The new Y position.
* @param pressure The new pressure.
@@ -668,16 +677,16 @@ public final class MotionEvent implements Parcelable {
mHistoryTimes = historyTimes = newHistoryTimes;
}
}
-
+
historyTimes[N] = mEventTime;
-
+
final int pos = N*4;
history[pos] = mX;
history[pos+1] = mY;
history[pos+2] = mPressure;
history[pos+3] = mSize;
mNumHistory = N+1;
-
+
mEventTime = eventTime;
mX = mRawX = x;
mY = mRawY = y;
@@ -685,7 +694,7 @@ public final class MotionEvent implements Parcelable {
mSize = size;
mMetaState |= metaState;
}
-
+
@Override
public String toString() {
return "MotionEvent{" + Integer.toHexString(System.identityHashCode(this))
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bcb97ed..0497344 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -75,17 +75,17 @@ import java.util.WeakHashMap;
* This class represents the basic building block for user interface components. A View
* occupies a rectangular area on the screen and is responsible for drawing and
* event handling. View is the base class for <em>widgets</em>, which are
- * used to create interactive UI components (buttons, text fields, etc.). The
+ * used to create interactive UI components (buttons, text fields, etc.). The
* {@link android.view.ViewGroup} subclass is the base class for <em>layouts</em>, which
* are invisible containers that hold other Views (or other ViewGroups) and define
* their layout properties.
* </p>
*
* <div class="special">
- * <p>For an introduction to using this class to develop your
- * application's user interface, read the Developer Guide documentation on
+ * <p>For an introduction to using this class to develop your
+ * application's user interface, read the Developer Guide documentation on
* <strong><a href="{@docRoot}guide/topics/ui/index.html">User Interface</a></strong>. Special topics
- * include:
+ * include:
* <br/><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a>
* <br/><a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>
* <br/><a href="{@docRoot}guide/topics/ui/layout-objects.html">Common Layout Objects</a>
@@ -96,7 +96,7 @@ import java.util.WeakHashMap;
* <br/><a href="{@docRoot}guide/topics/ui/how-android-draws.html">How Android Draws Views</a>.
* </p>
* </div>
- *
+ *
* <a name="Using"></a>
* <h3>Using Views</h3>
* <p>
@@ -422,7 +422,7 @@ import java.util.WeakHashMap;
* </p>
*
* <p>
- * Note that the framework will not draw views that are not in the invalid region.
+ * Note that the framework will not draw views that are not in the invalid region.
* </p>
*
* <p>
@@ -1830,7 +1830,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
int viewFlagMasks = 0;
boolean setScrollContainer = false;
-
+
int x = 0;
int y = 0;
@@ -2464,7 +2464,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
if (!(parent instanceof View)) {
break;
}
-
+
child = (View) parent;
parent = child.getParent();
}
@@ -2556,7 +2556,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* and previouslyFocusedRect provide insight into where the focus is coming from.
* When overriding, be sure to call up through to the super class so that
* the standard focus handling will occur.
- *
+ *
* @param gainFocus True if the View has focus; false otherwise.
* @param direction The direction focus has moved when requestFocus()
* is called to give this view focus. Values are
@@ -2587,7 +2587,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
&& mAttachInfo.mHasWindowFocus) {
imm.focusIn(this);
}
-
+
invalidate();
if (mOnFocusChangeListener != null) {
mOnFocusChangeListener.onFocusChange(this, gainFocus);
@@ -2676,7 +2676,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* Subclasses of View overriding this method should always call super.onFocusLost().
*
* @see #onFocusChanged(boolean, int, android.graphics.Rect)
- * @see #onWindowFocusChanged(boolean)
+ * @see #onWindowFocusChanged(boolean)
*
* @hide pending API council approval
*/
@@ -3578,14 +3578,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
*/
public void onStartTemporaryDetach() {
}
-
+
/**
* Called after {@link #onStartTemporaryDetach} when the container is done
* changing the view.
*/
public void onFinishTemporaryDetach() {
}
-
+
/**
* capture information of this view for later analysis: developement only
* check dynamic switch to make sure we only dump view
@@ -3970,25 +3970,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* a call on that method would return a non-null InputConnection, and
* they are really a first-class editor that the user would normally
* start typing on when the go into a window containing your view.
- *
+ *
* <p>The default implementation always returns false. This does
* <em>not</em> mean that its {@link #onCreateInputConnection(EditorInfo)}
* will not be called or the user can not otherwise perform edits on your
* view; it is just a hint to the system that this is not the primary
* purpose of this view.
- *
+ *
* @return Returns true if this view is a text editor, else false.
*/
public boolean onCheckIsTextEditor() {
return false;
}
-
+
/**
* Create a new InputConnection for an InputMethod to interact
* with the view. The default implementation returns null, since it doesn't
* support input methods. You can override this to implement such support.
* This is only needed for views that take focus and text input.
- *
+ *
* <p>When implementing this, you probably also want to implement
* {@link #onCheckIsTextEditor()} to indicate you will return a
* non-null InputConnection.
@@ -4012,7 +4012,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
public boolean checkInputConnectionProxy(View view) {
return false;
}
-
+
/**
* Show the context menu for this view. It is not safe to hold on to the
* menu after returning from this method.
@@ -4743,7 +4743,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* whether an instance is opaque. Opaque Views are treated in a special way by
* the View hierarchy, possibly allowing it to perform optimizations during
* invalidate/draw passes.
- *
+ *
* @return True if this View is guaranteed to be fully opaque, false otherwise.
*
* @hide Pending API council approval
@@ -5343,9 +5343,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
}
}
-
+
/**
- * Override this if the vertical scrollbar needs to be hidden in a subclass, like when
+ * Override this if the vertical scrollbar needs to be hidden in a subclass, like when
* FastScroller is visible.
* @return whether to temporarily hide the vertical scrollbar
* @hide
@@ -5868,8 +5868,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
EventLog.writeEvent(60002, hashCode());
}
- final int width = mRight - mLeft;
- final int height = mBottom - mTop;
+ int width = mRight - mLeft;
+ int height = mBottom - mTop;
+
+ final AttachInfo attachInfo = mAttachInfo;
+ if (attachInfo != null) {
+ final boolean scalingRequired = attachInfo.mScalingRequired;
+ if (scalingRequired) {
+ width = (int) ((width * attachInfo.mApplicationScale) + 0.5f);
+ height = (int) ((height * attachInfo.mApplicationScale) + 0.5f);
+ }
+ }
final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
final boolean opaque = drawingCacheBackgroundColor != 0 ||
@@ -5925,11 +5934,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
Canvas canvas;
- final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
canvas = attachInfo.mCanvas;
if (canvas == null) {
canvas = new Canvas();
+
+ // NOTE: This should have to happen only once since compatibility
+ // mode should not change at runtime
+ if (attachInfo.mScalingRequired) {
+ final float scale = attachInfo.mApplicationScale;
+ canvas.scale(scale, scale);
+ }
}
canvas.setBitmap(bitmap);
// Temporarily clobber the cached Canvas in case one of our children
@@ -6031,7 +6046,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
// Restore the cached Canvas for our siblings
attachInfo.mCanvas = canvas;
}
-
+
return bitmap;
}
@@ -6971,7 +6986,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
mUserPaddingBottom = bottom;
final int viewFlags = mViewFlags;
-
+
// Common case is there are no scroll bars.
if ((viewFlags & (SCROLLBARS_VERTICAL|SCROLLBARS_HORIZONTAL)) != 0) {
// TODO: Deal with RTL languages to adjust left padding instead of right.
@@ -6984,7 +6999,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
? 0 : getHorizontalScrollbarHeight();
}
}
-
+
if (mPaddingLeft != left) {
changed = true;
mPaddingLeft = left;
@@ -7121,7 +7136,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
return v;
}
}
-
+
View parent = this;
while (parent.mParent != null && parent.mParent instanceof View) {
@@ -7169,7 +7184,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
location[1] += view.mTop - view.mScrollY;
viewParent = view.mParent;
}
-
+
if (viewParent instanceof ViewRoot) {
// *cough*
final ViewRoot vr = (ViewRoot)viewParent;
@@ -7320,7 +7335,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* @return the Object stored in this view as a tag
*
* @see #setTag(int, Object)
- * @see #getTag()
+ * @see #getTag()
*/
public Object getTag(int key) {
SparseArray<Object> tags = null;
@@ -7376,7 +7391,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
+ "resource id.");
}
- setTagInternal(this, key, tag);
+ setTagInternal(this, key, tag);
}
private static void setTagInternal(View view, int key, Object tag) {
@@ -7411,7 +7426,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
/**
* Method that subclasses should implement to check their consistency. The type of
* consistency check is indicated by the bit field passed as a parameter.
- *
+ *
* @param consistency The type of consistency. See ViewDebug for more information.
*
* @throws IllegalStateException if the view is in an inconsistent state.
@@ -7966,7 +7981,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
/**
* BZZZTT!!1!
- *
+ *
* <p>Provide haptic feedback to the user for this view.
*
* <p>The framework will provide haptic feedback for some built in actions,
@@ -7985,7 +8000,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
/**
* BZZZTT!!1!
- *
+ *
* <p>Like {@link #performHapticFeedback(int)}, with additional options.
*
* @param feedbackConstant One of the constants defined in
@@ -8448,11 +8463,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* The top view of the hierarchy.
*/
View mRootView;
-
+
IBinder mPanelParentWindowToken;
Surface mSurface;
/**
+ * Scale factor used by the compatibility mode
+ */
+ float mApplicationScale;
+
+ /**
+ * Indicates whether the application is in compatibility mode
+ */
+ boolean mScalingRequired;
+
+ /**
* Left position of this view's window
*/
int mWindowLeft;
@@ -8639,18 +8664,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
// use use a height of 1, and then wack the matrix each time we
// actually use it.
shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
-
+
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
-
+
public void setFadeColor(int color) {
if (color != 0 && color != mLastColor) {
mLastColor = color;
color |= 0xFF000000;
-
+
shader = new LinearGradient(0, 0, 0, 1, color, 0, Shader.TileMode.CLAMP);
-
+
paint.setShader(shader);
// Restore the default transfer mode (src_over)
paint.setXfermode(null);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 8b0629c..f803b5a 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -99,7 +99,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/**
* Internal flags.
- *
+ *
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
@@ -152,7 +152,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to get the index of the child to draw for that iteration.
*/
protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400;
-
+
/**
* When set, this ViewGroup supports static transformations on children; this causes
* {@link #getChildStaticTransformation(View, android.view.animation.Transformation)} to be
@@ -161,7 +161,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* Any subclass overriding
* {@link #getChildStaticTransformation(View, android.view.animation.Transformation)} should
* set this flags in {@link #mGroupFlags}.
- *
+ *
* {@hide}
*/
protected static final int FLAG_SUPPORT_STATIC_TRANSFORMATIONS = 0x800;
@@ -222,7 +222,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* When set, this ViewGroup should not intercept touch events.
*/
private static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
-
+
/**
* Indicates which types of drawing caches are to be kept in memory.
* This field should be made private, so it is hidden from the SDK.
@@ -698,7 +698,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
ViewParent parent = mParent;
if (parent != null) parent.recomputeViewAttributes(this);
}
-
+
@Override
void dispatchCollectViewAttributes(int visibility) {
visibility |= mViewFlags&VISIBILITY_MASK;
@@ -830,16 +830,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
}
-
+
boolean isUpOrCancel = (action == MotionEvent.ACTION_UP) ||
- (action == MotionEvent.ACTION_CANCEL);
+ (action == MotionEvent.ACTION_CANCEL);
if (isUpOrCancel) {
// Note, we've already copied the previous state to our local
// variable, so this takes effect on the next event
mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
}
-
+
// The event wasn't an ACTION_DOWN, dispatch it to our target if
// we have one.
final View target = mMotionTarget;
@@ -886,18 +886,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* {@inheritDoc}
*/
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-
+
if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
// We're already in this state, assume our ancestors are too
return;
}
-
+
if (disallowIntercept) {
mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
} else {
mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
}
-
+
// Pass it up to our parent
if (mParent != null) {
mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
@@ -1301,7 +1301,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
post(end);
}
}
-
+
/**
* Returns the index of the child to draw for this iteration. Override this
* if you want to change the drawing order of children. By default, it
@@ -1309,14 +1309,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* <p>
* NOTE: In order for this method to be called, the
* {@link #FLAG_USE_CHILD_DRAWING_ORDER} must be set.
- *
+ *
* @param i The current iteration.
* @return The index of the child to draw this iteration.
*/
protected int getChildDrawingOrder(int childCount, int i) {
return i;
}
-
+
private void notifyAnimationListener() {
mGroupFlags &= ~FLAG_NOTIFY_ANIMATION_LISTENER;
mGroupFlags |= FLAG_ANIMATION_DONE;
@@ -1444,10 +1444,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int sx = child.mScrollX;
final int sy = child.mScrollY;
+ boolean scalingRequired = false;
Bitmap cache = null;
if ((flags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE ||
(flags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE) {
cache = child.getDrawingCache();
+ if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
}
final boolean hasNoCache = cache == null;
@@ -1457,6 +1459,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
canvas.translate(cl - sx, ct - sy);
} else {
canvas.translate(cl, ct);
+ if (scalingRequired) {
+ // mAttachInfo cannot be null, otherwise scalingRequired == false
+ final float scale = 1.0f / mAttachInfo.mApplicationScale;
+ canvas.scale(scale, scale);
+ }
}
float alpha = 1.0f;
@@ -1499,7 +1506,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (hasNoCache) {
canvas.clipRect(sx, sy, sx + (cr - cl), sy + (cb - ct));
} else {
- canvas.clipRect(0, 0, cr - cl, cb - ct);
+ if (!scalingRequired) {
+ canvas.clipRect(0, 0, cr - cl, cb - ct);
+ } else {
+ canvas.clipRect(0, 0, cache.getWidth(), cache.getHeight());
+ }
}
}
@@ -1509,7 +1520,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
}
- child.mPrivateFlags &= ~DIRTY_MASK;
+ child.mPrivateFlags &= ~DIRTY_MASK;
child.dispatchDraw(canvas);
} else {
child.draw(canvas);
@@ -1574,7 +1585,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
children[i].setSelected(selected);
}
}
-
+
@Override
protected void dispatchSetPressed(boolean pressed) {
final View[] children = mChildren;
@@ -1605,7 +1616,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/**
* {@inheritDoc}
*
- * @see #setStaticTransformationsEnabled(boolean)
+ * @see #setStaticTransformationsEnabled(boolean)
*/
protected boolean getChildStaticTransformation(View child, Transformation t) {
return false;
@@ -1872,10 +1883,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (child.hasFocus()) {
requestChildFocus(child, child.findFocus());
}
-
+
AttachInfo ai = mAttachInfo;
if (ai != null) {
- boolean lastKeepOn = ai.mKeepScreenOn;
+ boolean lastKeepOn = ai.mKeepScreenOn;
ai.mKeepScreenOn = false;
child.dispatchAttachedToWindow(mAttachInfo, (mViewFlags&VISIBILITY_MASK));
if (ai.mKeepScreenOn) {
@@ -2075,7 +2086,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
needGlobalAttributesUpdate(false);
-
+
removeFromArray(index);
if (clearChildFocus) {
@@ -2108,7 +2119,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
needGlobalAttributesUpdate(false);
-
+
if (notifyListener) {
onHierarchyChangeListener.onChildViewRemoved(this, view);
}
@@ -2156,7 +2167,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
View clearChildFocus = null;
needGlobalAttributesUpdate(false);
-
+
for (int i = count - 1; i >= 0; i--) {
final View view = children[i];
@@ -2201,7 +2212,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (child == mFocused) {
child.clearFocus();
}
-
+
if (animate && child.getAnimation() != null) {
addDisappearingView(child);
} else if (child.mAttachInfo != null) {
@@ -3164,7 +3175,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
}
-
+
@Override
protected boolean fitSystemWindows(Rect insets) {
@@ -3298,7 +3309,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* laid out. See
* {@link android.R.styleable#ViewGroup_Layout ViewGroup Layout Attributes}
* for a list of all child view attributes that this class supports.
- *
+ *
* <p>
* 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:
@@ -3429,7 +3440,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @param output the String to prepend to the internal representation
* @return a String with the following format: output +
* "ViewGroup.LayoutParams={ width=WIDTH, height=HEIGHT }"
- *
+ *
* @hide
*/
public String debug(String output) {
@@ -3442,7 +3453,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*
* @param size the size to convert
* @return a String instance representing the supplied size
- *
+ *
* @hide
*/
protected static String sizeToString(int size) {
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index e15a61c..fe5edc2 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -97,18 +97,18 @@ public final class ViewRoot extends Handler implements ViewParent,
static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>();
- private static int sDrawTime;
+ private static int sDrawTime;
long mLastTrackballTime = 0;
final TrackballAxis mTrackballAxisX = new TrackballAxis();
final TrackballAxis mTrackballAxisY = new TrackballAxis();
final int[] mTmpLocation = new int[2];
-
+
final InputMethodCallback mInputMethodCallback;
final SparseArray<Object> mPendingEvents = new SparseArray<Object>();
int mPendingEventSeq = 0;
-
+
final Thread mThread;
final WindowLeaked mLocation;
@@ -130,9 +130,8 @@ public final class ViewRoot extends Handler implements ViewParent,
int mHeight;
Rect mDirty; // will be a graphics.Region soon
boolean mIsAnimating;
-
+
private CompatibilityInfo mCompatibilityInfo;
- private int[] mWindowLayoutParamsBackup = null;
final View.AttachInfo mAttachInfo;
@@ -174,7 +173,7 @@ public final class ViewRoot extends Handler implements ViewParent,
int mScrollY;
int mCurScrollY;
Scroller mScroller;
-
+
EGL10 mEgl;
EGLDisplay mEglDisplay;
EGLContext mEglContext;
@@ -184,7 +183,7 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean mUseGL;
boolean mGlWanted;
- final ViewConfiguration mViewConfiguration;
+ final ViewConfiguration mViewConfiguration;
/**
* see {@link #playSoundEffect(int)}
@@ -395,10 +394,11 @@ public final class ViewRoot extends Handler implements ViewParent,
if (mView == null) {
mView = view;
mWindowAttributes.copyFrom(attrs);
- mCompatibilityInfo =
- mView.getContext().getResources().getCompatibilityInfo();
- if (mCompatibilityInfo.mScalingRequired) {
- mWindowLayoutParamsBackup = new int[4];
+ mCompatibilityInfo = mView.getContext().getResources().getCompatibilityInfo();
+ boolean restore = false;
+ if (mCompatibilityInfo.mScalingRequired || !mCompatibilityInfo.mExpandable) {
+ restore = true;
+ mWindowAttributes.backup();
}
if (!mCompatibilityInfo.mExpandable) {
adjustWindowAttributesForCompatibleMode(mWindowAttributes);
@@ -406,13 +406,15 @@ public final class ViewRoot extends Handler implements ViewParent,
mSoftInputMode = attrs.softInputMode;
mWindowAttributesChanged = true;
mAttachInfo.mRootView = view;
+ mAttachInfo.mScalingRequired = mCompatibilityInfo.mScalingRequired;
+ mAttachInfo.mApplicationScale = mCompatibilityInfo.mApplicationScale;
if (panelParentView != null) {
mAttachInfo.mPanelParentWindowToken
= panelParentView.getApplicationWindowToken();
}
mAdded = true;
int res; /* = WindowManagerImpl.ADD_OKAY; */
-
+
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
@@ -427,6 +429,11 @@ public final class ViewRoot extends Handler implements ViewParent,
unscheduleTraversals();
throw new RuntimeException("Adding window failed", e);
}
+
+ if (restore) {
+ mWindowAttributes.restore();
+ }
+
if (mCompatibilityInfo.mScalingRequired) {
mAttachInfo.mContentInsets.scale(
mCompatibilityInfo.mApplicationInvertedScale);
@@ -596,7 +603,7 @@ public final class ViewRoot extends Handler implements ViewParent,
int getHostVisibility() {
return mAppVisible ? mView.getVisibility() : View.GONE;
}
-
+
private void performTraversals() {
// cache mView since it is used so much below...
final View host = mView;
@@ -640,7 +647,7 @@ public final class ViewRoot extends Handler implements ViewParent,
fullRedrawNeeded = true;
mLayoutRequested = true;
- DisplayMetrics packageMetrics =
+ DisplayMetrics packageMetrics =
mView.getContext().getResources().getDisplayMetrics();
desiredWindowWidth = packageMetrics.widthPixels;
desiredWindowHeight = packageMetrics.heightPixels;
@@ -687,7 +694,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
boolean insetsChanged = false;
-
+
if (mLayoutRequested) {
if (mFirst) {
host.fitSystemWindows(mAttachInfo.mContentInsets);
@@ -712,7 +719,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|| lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
windowResizesToFitContent = true;
- DisplayMetrics packageMetrics =
+ DisplayMetrics packageMetrics =
mView.getContext().getResources().getDisplayMetrics();
desiredWindowWidth = packageMetrics.widthPixels;
desiredWindowHeight = packageMetrics.heightPixels;
@@ -772,7 +779,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
if (params != null && (host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) {
if (!PixelFormat.formatHasAlpha(params.format)) {
params.format = PixelFormat.TRANSLUCENT;
@@ -801,7 +808,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// computed insets.
insetsPending = computesInternalInsets
&& (mFirst || viewVisibilityChanged);
-
+
if (mWindowAttributes.memoryType == WindowManager.LayoutParams.MEMORY_TYPE_GPU) {
if (params == null) {
params = mWindowAttributes;
@@ -837,7 +844,7 @@ public final class ViewRoot extends Handler implements ViewParent,
+ " content=" + mPendingContentInsets.toShortString()
+ " visible=" + mPendingVisibleInsets.toShortString()
+ " surface=" + mSurface);
-
+
contentInsetsChanged = !mPendingContentInsets.equals(
mAttachInfo.mContentInsets);
visibleInsetsChanged = !mPendingVisibleInsets.equals(
@@ -865,7 +872,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// all at once.
newSurface = true;
fullRedrawNeeded = true;
-
+
if (mGlWanted && !mUseGL) {
initializeGL();
initialized = mGlCanvas != null;
@@ -910,7 +917,7 @@ public final class ViewRoot extends Handler implements ViewParent,
+ " mHeight=" + mHeight
+ " measuredHeight" + host.mMeasuredHeight
+ " coveredInsetsChanged=" + contentInsetsChanged);
-
+
// Ask host how big it wants to be
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
@@ -985,7 +992,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mTmpLocation[1] + host.mBottom - host.mTop);
host.gatherTransparentRegion(mTransparentRegion);
- mTransparentRegion.scale(appScale);
+ mTransparentRegion.scale(appScale);
if (!mTransparentRegion.equals(mPreviousTransparentRegion)) {
mPreviousTransparentRegion.set(mTransparentRegion);
// reconfigure window manager
@@ -1029,7 +1036,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
if (mFirst) {
// handle first focus request
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: mView.hasFocus()="
@@ -1067,7 +1074,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
boolean cancelDraw = attachInfo.mTreeObserver.dispatchOnPreDraw();
if (!cancelDraw && !newSurface) {
@@ -1155,7 +1162,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mAttachInfo.mViewScrollChanged = false;
mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
}
-
+
int yoff;
final boolean scrolling = mScroller != null && mScroller.computeScrollOffset();
if (scrolling) {
@@ -1320,7 +1327,7 @@ public final class ViewRoot extends Handler implements ViewParent,
EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
}
}
-
+
} finally {
surface.unlockCanvasAndPost(canvas);
}
@@ -1328,7 +1335,7 @@ public final class ViewRoot extends Handler implements ViewParent,
if (LOCAL_LOGV) {
Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost");
}
-
+
if (scrolling) {
mFullRedrawNeeded = true;
scheduleTraversals();
@@ -1341,7 +1348,7 @@ public final class ViewRoot extends Handler implements ViewParent,
final Rect vi = attachInfo.mVisibleInsets;
int scrollY = 0;
boolean handled = false;
-
+
if (vi.left > ci.left || vi.top > ci.top
|| vi.right > ci.right || vi.bottom > ci.bottom) {
// We'll assume that we aren't going to change the scroll
@@ -1428,7 +1435,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
if (scrollY != mScrollY) {
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Pan scroll changed: old="
+ mScrollY + " , new=" + scrollY);
@@ -1442,10 +1449,10 @@ public final class ViewRoot extends Handler implements ViewParent,
}
mScrollY = scrollY;
}
-
+
return handled;
}
-
+
public void requestChildFocus(View child, View focused) {
checkThread();
if (mFocusedView != focused) {
@@ -1525,7 +1532,7 @@ public final class ViewRoot extends Handler implements ViewParent,
} catch (RemoteException e) {
}
}
-
+
/**
* Return true if child is an ancestor of parent, (or equal to the parent).
*/
@@ -1745,10 +1752,10 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
mLastWasImTarget = WindowManager.LayoutParams
.mayUseInputMethod(mWindowAttributes.flags);
-
+
InputMethodManager imm = InputMethodManager.peekInstance();
if (mView != null) {
if (hasWindowFocus && imm != null && mLastWasImTarget) {
@@ -1944,9 +1951,6 @@ public final class ViewRoot extends Handler implements ViewParent,
} else {
didFinish = false;
}
- if (event != null && mCompatibilityInfo.mScalingRequired) {
- event.scale(mCompatibilityInfo.mApplicationInvertedScale);
- }
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
@@ -2172,50 +2176,50 @@ public final class ViewRoot extends Handler implements ViewParent,
}
/**
- * log motion events
+ * log motion events
*/
private static void captureMotionLog(String subTag, MotionEvent ev) {
- //check dynamic switch
+ //check dynamic switch
if (ev == null ||
SystemProperties.getInt(ViewDebug.SYSTEM_PROPERTY_CAPTURE_EVENT, 0) == 0) {
return;
- }
-
- StringBuilder sb = new StringBuilder(subTag + ": ");
- sb.append(ev.getDownTime()).append(',');
- sb.append(ev.getEventTime()).append(',');
- sb.append(ev.getAction()).append(',');
- sb.append(ev.getX()).append(',');
- sb.append(ev.getY()).append(',');
- sb.append(ev.getPressure()).append(',');
- sb.append(ev.getSize()).append(',');
- sb.append(ev.getMetaState()).append(',');
- sb.append(ev.getXPrecision()).append(',');
- sb.append(ev.getYPrecision()).append(',');
- sb.append(ev.getDeviceId()).append(',');
+ }
+
+ StringBuilder sb = new StringBuilder(subTag + ": ");
+ sb.append(ev.getDownTime()).append(',');
+ sb.append(ev.getEventTime()).append(',');
+ sb.append(ev.getAction()).append(',');
+ sb.append(ev.getX()).append(',');
+ sb.append(ev.getY()).append(',');
+ sb.append(ev.getPressure()).append(',');
+ sb.append(ev.getSize()).append(',');
+ sb.append(ev.getMetaState()).append(',');
+ sb.append(ev.getXPrecision()).append(',');
+ sb.append(ev.getYPrecision()).append(',');
+ sb.append(ev.getDeviceId()).append(',');
sb.append(ev.getEdgeFlags());
- Log.d(TAG, sb.toString());
+ Log.d(TAG, sb.toString());
}
/**
- * log motion events
+ * log motion events
*/
private static void captureKeyLog(String subTag, KeyEvent ev) {
- //check dynamic switch
- if (ev == null ||
+ //check dynamic switch
+ if (ev == null ||
SystemProperties.getInt(ViewDebug.SYSTEM_PROPERTY_CAPTURE_EVENT, 0) == 0) {
return;
}
- StringBuilder sb = new StringBuilder(subTag + ": ");
+ StringBuilder sb = new StringBuilder(subTag + ": ");
sb.append(ev.getDownTime()).append(',');
sb.append(ev.getEventTime()).append(',');
sb.append(ev.getAction()).append(',');
- sb.append(ev.getKeyCode()).append(',');
+ sb.append(ev.getKeyCode()).append(',');
sb.append(ev.getRepeatCount()).append(',');
sb.append(ev.getMetaState()).append(',');
sb.append(ev.getDeviceId()).append(',');
sb.append(ev.getScanCode());
- Log.d(TAG, sb.toString());
- }
+ Log.d(TAG, sb.toString());
+ }
int enqueuePendingEvent(Object event, boolean sendDone) {
int seq = mPendingEventSeq+1;
@@ -2233,7 +2237,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
return event;
}
-
+
private void deliverKeyEvent(KeyEvent event, boolean sendDone) {
// If mView is null, we just consume the key event because it doesn't
// make sense to do anything else with it.
@@ -2290,7 +2294,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
private void deliverKeyEventToViewHierarchy(KeyEvent event, boolean sendDone) {
try {
if (mView != null && mAdded) {
@@ -2299,8 +2303,8 @@ public final class ViewRoot extends Handler implements ViewParent,
if (checkForLeavingTouchModeAndConsume(event)) {
return;
- }
-
+ }
+
if (Config.LOGV) {
captureKeyLog("captureDispatchKeyEvent", event);
}
@@ -2378,13 +2382,15 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean restore = false;
float appScale = mCompatibilityInfo.mApplicationScale;
boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
-
if (params != null && !mCompatibilityInfo.mExpandable) {
+ restore = true;
+ params.backup();
adjustWindowAttributesForCompatibleMode(params);
}
if (params != null && scalingRequired) {
+ if (!restore) params.backup();
restore = true;
- params.scale(appScale, mWindowLayoutParamsBackup);
+ params.scale(appScale);
}
int relayoutResult = sWindowSession.relayout(
mWindow, params,
@@ -2393,7 +2399,7 @@ public final class ViewRoot extends Handler implements ViewParent,
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets, mSurface);
if (restore) {
- params.restore(mWindowLayoutParamsBackup);
+ params.restore();
}
if (scalingRequired) {
float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
@@ -2403,12 +2409,12 @@ public final class ViewRoot extends Handler implements ViewParent,
}
return relayoutResult;
}
-
+
/**
* Adjust the window's layout parameter for compatibility mode. It replaces FILL_PARENT
* with the default window size, and centers if the window wanted to fill
* horizontally.
- *
+ *
* @param attrs the window's layout params to adjust
*/
private void adjustWindowAttributesForCompatibleMode(WindowManager.LayoutParams attrs) {
@@ -2419,12 +2425,15 @@ public final class ViewRoot extends Handler implements ViewParent,
if (attrs.width == ViewGroup.LayoutParams.FILL_PARENT) {
attrs.width = metrics.widthPixels;
attrs.gravity |= Gravity.CENTER_HORIZONTAL;
+ mWindowAttributesChanged = attrs == mWindowAttributes;
}
if (attrs.height == ViewGroup.LayoutParams.FILL_PARENT) {
attrs.height = metrics.heightPixels;
+ attrs.gravity |= Gravity.TOP;
+ mWindowAttributesChanged = attrs == mWindowAttributes;
}
if (DEBUG_LAYOUT) {
- Log.d(TAG, "Attributes fixed for compatibility : " + attrs);
+ Log.d(TAG, "Adjusted Attributes for compatibility : " + attrs);
}
}
}
@@ -2644,14 +2653,14 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean immediate) {
return scrollToRectOrFocus(rectangle, immediate);
}
-
+
static class InputMethodCallback extends IInputMethodCallback.Stub {
private WeakReference<ViewRoot> mViewRoot;
public InputMethodCallback(ViewRoot viewRoot) {
mViewRoot = new WeakReference<ViewRoot>(viewRoot);
}
-
+
public void finishedEvent(int seq, boolean handled) {
final ViewRoot viewRoot = mViewRoot.get();
if (viewRoot != null) {
@@ -2663,13 +2672,13 @@ public final class ViewRoot extends Handler implements ViewParent,
// Stub -- not for use in the client.
}
}
-
+
static class EventCompletion extends Handler {
final IWindow mWindow;
final KeyEvent mKeyEvent;
final boolean mIsPointer;
final MotionEvent mMotionEvent;
-
+
EventCompletion(Looper looper, IWindow window, KeyEvent key,
boolean isPointer, MotionEvent motion) {
super(looper);
@@ -2679,7 +2688,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mMotionEvent = motion;
sendEmptyMessage(0);
}
-
+
@Override
public void handleMessage(Message msg) {
if (mKeyEvent != null) {
@@ -2721,7 +2730,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
-
+
static class W extends IWindow.Stub {
private final WeakReference<ViewRoot> mViewRoot;
private final Looper mMainLooper;
@@ -2847,14 +2856,14 @@ public final class ViewRoot extends Handler implements ViewParent,
* The maximum amount of acceleration we will apply.
*/
static final float MAX_ACCELERATION = 20;
-
+
/**
* The maximum amount of time (in milliseconds) between events in order
* for us to consider the user to be doing fast trackball movements,
* and thus apply an acceleration.
*/
static final long FAST_MOVE_TIME = 150;
-
+
/**
* Scaling factor to the time (in milliseconds) between events to how
* much to multiple/divide the current acceleration. When movement
@@ -2862,7 +2871,7 @@ public final class ViewRoot extends Handler implements ViewParent,
* FAST_MOVE_TIME it divides it.
*/
static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/40);
-
+
float position;
float absPosition;
float acceleration = 1;
@@ -2914,7 +2923,7 @@ public final class ViewRoot extends Handler implements ViewParent,
} else {
normTime = 0;
}
-
+
// The number of milliseconds between each movement that is
// considered "normal" and will not result in any acceleration
// or deceleration, scaled by the offset we have here.
@@ -3072,7 +3081,7 @@ public final class ViewRoot extends Handler implements ViewParent,
sRunQueues.set(rq);
return rq;
}
-
+
/**
* @hide
*/
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index ec2069c..e1c4687 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -818,6 +818,9 @@ public interface WindowManager extends ViewManager {
public static final int SCREEN_ORIENTATION_CHANGED = 1<<10;
public static final int SCREEN_BRIGHTNESS_CHANGED = 1<<11;
+ // internal buffer to backup/restore parameters under compatibility mode.
+ private int[] mCompatibilityParamsBackup = null;
+
public final int copyFrom(LayoutParams o) {
int changes = 0;
@@ -975,37 +978,47 @@ public interface WindowManager extends ViewManager {
/**
* Scale the layout params' coordinates and size.
- * Returns the original info as a backup so that the caller can
- * restore the layout params;
- */
- void scale(float scale, int[] backup) {
- if (scale != 1.0f) {
- backup[0] = x;
- backup[1] = y;
- x *= scale;
- y *= scale;
- if (width > 0) {
- backup[2] = width;
- width *= scale;
- }
- if (height > 0) {
- backup[3] = height;
- height *= scale;
- }
+ */
+ void scale(float scale) {
+ x *= scale;
+ y *= scale;
+ if (width > 0) {
+ width *= scale;
+ }
+ if (height > 0) {
+ height *= scale;
}
}
/**
- * Restore the layout params' coordinates and size.
- */
- void restore(int[] backup) {
- x = backup[0];
- y = backup[1];
- if (width > 0) {
- width = backup[2];
+ * Backup the layout parameters used in compatibility mode.
+ * @see LayoutParams#restore()
+ */
+ void backup() {
+ int[] backup = mCompatibilityParamsBackup;
+ if (backup == null) {
+ // we backup 5 elements, x, y, width, height and gravity.
+ backup = mCompatibilityParamsBackup = new int[5];
}
- if (height > 0) {
+ backup[0] = x;
+ backup[1] = y;
+ backup[2] = width;
+ backup[3] = height;
+ backup[4] = gravity;
+ }
+
+ /**
+ * Restore the layout params' coordinates, size and gravity
+ * @see LayoutParams#backup()
+ */
+ void restore() {
+ int[] backup = mCompatibilityParamsBackup;
+ if (backup != null) {
+ x = backup[0];
+ y = backup[1];
+ width = backup[2];
height = backup[3];
+ gravity = backup[4];
}
}
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index 878b690..507fce3 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -222,6 +222,21 @@ final class JWebCoreJavaBridge extends Handler {
mHasDeferredTimers = false;
}
+ private String[] getKeyStrengthList() {
+ // FIXME: fake the list for now
+ String[] list = new String[2];
+ list[0] = "1024";
+ list[1] = "512";
+ return list;
+ }
+
+ private String getSignedPublicKey(int index, String challenge, String url) {
+ // FIXME: do nothing for now
+ Log.w(LOGTAG, "getSignedPublicKey for " + index + " and challenge="
+ + challenge + " and url=" + url);
+ return "";
+ }
+
private native void nativeConstructor();
private native void nativeFinalize();
private native void sharedTimerFired();
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index ea186fd..f57c647 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -163,6 +163,7 @@ public class WebSettings {
private boolean mDatabaseEnabled = false;
private String mAppCachePath = "";
private boolean mAppCacheEnabled = false;
+ private boolean mDomStorageEnabled = false;
// Class to handle messages before WebCore is ready.
private class EventHandler {
@@ -963,6 +964,28 @@ public class WebSettings {
}
/**
+ * Set whether the DOM storage API is enabled.
+ * @param flag boolean True if the WebView should use the DOM storage
+ * API.
+ * @hide pending API council.
+ */
+ public synchronized void setDomStorageEnabled(boolean flag) {
+ if (mDomStorageEnabled != flag) {
+ mDomStorageEnabled = flag;
+ postSync();
+ }
+ }
+
+ /**
+ * Returns true if the DOM Storage API's are enabled.
+ * @return True if the DOM Storage API's are enabled.
+ * @hide pending API council.
+ */
+ public synchronized boolean getDomStorageEnabled() {
+ return mDomStorageEnabled;
+ }
+
+ /**
* Return the path to where database storage API databases are saved for
* the current WebView.
* @return the String path to the database storage API databases.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 2940983..41e007e 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -80,7 +80,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
/**
@@ -207,18 +206,25 @@ public class WebView extends AbsoluteLayout
static final String LOGTAG = "webview";
+ static class ScaleLimitData {
+ int mMinScale;
+ int mMaxScale;
+ }
+
private static class ExtendedZoomControls extends FrameLayout {
public ExtendedZoomControls(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(com.android.internal.R.layout.zoom_magnify, this, true);
- mZoomControls = (ZoomControls) findViewById(com.android.internal.R.id.zoomControls);
+ mPlusMinusZoomControls = (ZoomControls) findViewById(
+ com.android.internal.R.id.zoomControls);
mZoomMagnify = (ImageView) findViewById(com.android.internal.R.id.zoomMagnify);
}
public void show(boolean showZoom, boolean canZoomOut) {
- mZoomControls.setVisibility(showZoom ? View.VISIBLE : View.GONE);
+ mPlusMinusZoomControls.setVisibility(
+ showZoom ? View.VISIBLE : View.GONE);
mZoomMagnify.setVisibility(canZoomOut ? View.VISIBLE : View.GONE);
fade(View.VISIBLE, 0.0f, 1.0f);
}
@@ -239,23 +245,23 @@ public class WebView extends AbsoluteLayout
}
public boolean hasFocus() {
- return mZoomControls.hasFocus() || mZoomMagnify.hasFocus();
+ return mPlusMinusZoomControls.hasFocus() || mZoomMagnify.hasFocus();
}
public void setOnZoomInClickListener(OnClickListener listener) {
- mZoomControls.setOnZoomInClickListener(listener);
+ mPlusMinusZoomControls.setOnZoomInClickListener(listener);
}
public void setOnZoomOutClickListener(OnClickListener listener) {
- mZoomControls.setOnZoomOutClickListener(listener);
+ mPlusMinusZoomControls.setOnZoomOutClickListener(listener);
}
public void setOnZoomMagnifyClickListener(OnClickListener listener) {
mZoomMagnify.setOnClickListener(listener);
}
- ZoomControls mZoomControls;
- ImageView mZoomMagnify;
+ ZoomControls mPlusMinusZoomControls;
+ ImageView mZoomMagnify;
}
/**
@@ -360,10 +366,6 @@ public class WebView extends AbsoluteLayout
// take control of touch events unless it says no for touch down event.
private boolean mPreventDrag;
- // If rebuildWebTextView gets called while we are out of focus, use this
- // variable to remember to do it next time we gain focus.
- private boolean mNeedsRebuildWebTextView = false;
-
// Whether or not to draw the cursor ring.
private boolean mDrawCursorRing = true;
@@ -447,9 +449,7 @@ public class WebView extends AbsoluteLayout
static final int WEBCORE_INITIALIZED_MSG_ID = 16;
static final int UPDATE_TEXTFIELD_TEXT_MSG_ID = 17;
static final int DID_FIRST_LAYOUT_MSG_ID = 18;
- static final int RECOMPUTE_FOCUS_MSG_ID = 19;
- static final int MARK_NODE_INVALID_ID = 21;
static final int UPDATE_CLIPBOARD = 22;
static final int LONG_PRESS_CENTER = 23;
static final int PREVENT_TOUCH_ID = 24;
@@ -476,9 +476,9 @@ public class WebView extends AbsoluteLayout
"WEBCORE_INITIALIZED_MSG_ID", // = 16;
"UPDATE_TEXTFIELD_TEXT_MSG_ID", // = 17;
"DID_FIRST_LAYOUT_MSG_ID", // = 18;
- "RECOMPUTE_FOCUS_MSG_ID", // = 19;
+ "19",
"20",
- "MARK_NODE_INVALID_ID", // = 21;
+ "21", // = 21;
"UPDATE_CLIPBOARD", // = 22;
"LONG_PRESS_CENTER", // = 23;
"PREVENT_TOUCH_ID", // = 24;
@@ -633,8 +633,6 @@ public class WebView extends AbsoluteLayout
private Runnable mZoomControlRunnable;
private ZoomButtonsController mZoomButtonsController;
- private ImageView mZoomOverviewButton;
- private ImageView mZoomFitPageButton;
// These keep track of the center point of the zoom. They are used to
// determine the point around which we should zoom.
@@ -694,41 +692,18 @@ public class WebView extends AbsoluteLayout
mDatabase = WebViewDatabase.getInstance(context);
mScroller = new Scroller(context);
- initZoomController(context);
- }
-
- private void initZoomController(Context context) {
- // Create the buttons controller
mZoomButtonsController = new ZoomButtonsController(this);
mZoomButtonsController.setOnZoomListener(mZoomListener);
-
- // Create the accessory buttons
- LayoutInflater inflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- ViewGroup container = mZoomButtonsController.getContainer();
- inflater.inflate(com.android.internal.R.layout.zoom_browser_accessory_buttons, container);
- mZoomOverviewButton =
- (ImageView) container.findViewById(com.android.internal.R.id.zoom_page_overview);
- mZoomOverviewButton.setOnClickListener(
- new View.OnClickListener() {
- public void onClick(View v) {
- mZoomButtonsController.setVisible(false);
- zoomScrollOut();
- if (mLogEvent) {
- Checkin.updateStats(mContext.getContentResolver(),
- Checkin.Stats.Tag.BROWSER_ZOOM_OVERVIEW, 1, 0.0);
- }
- }
- });
- mZoomFitPageButton =
- (ImageView) container.findViewById(com.android.internal.R.id.zoom_fit_page);
- mZoomFitPageButton.setOnClickListener(
- new View.OnClickListener() {
- public void onClick(View v) {
- zoomWithPreview(1f);
- updateZoomButtonsEnabled();
- }
- });
+ // ZoomButtonsController positions the buttons at the bottom, but in
+ // the middle. Change their layout parameters so they appear on the
+ // right.
+ View controls = mZoomButtonsController.getZoomControls();
+ ViewGroup.LayoutParams params = controls.getLayoutParams();
+ if (params instanceof FrameLayout.LayoutParams) {
+ FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams)
+ params;
+ frameParams.gravity = Gravity.RIGHT;
+ }
}
private void updateZoomButtonsEnabled() {
@@ -738,20 +713,15 @@ public class WebView extends AbsoluteLayout
// Hide the zoom in and out buttons, as well as the fit to page
// button, if the page cannot zoom
mZoomButtonsController.getZoomControls().setVisibility(View.GONE);
- mZoomFitPageButton.setVisibility(View.GONE);
} else {
// Bring back the hidden zoom controls.
mZoomButtonsController.getZoomControls()
.setVisibility(View.VISIBLE);
- mZoomFitPageButton.setVisibility(View.VISIBLE);
// Set each one individually, as a page may be able to zoom in
// or out.
mZoomButtonsController.setZoomInEnabled(canZoomIn);
mZoomButtonsController.setZoomOutEnabled(canZoomOut);
- mZoomFitPageButton.setEnabled(mActualScale != 1);
}
- mZoomOverviewButton.setVisibility(canZoomScrollOut() ? View.VISIBLE:
- View.GONE);
}
private void init() {
@@ -1220,9 +1190,9 @@ public class WebView extends AbsoluteLayout
public void postUrl(String url, byte[] postData) {
if (URLUtil.isNetworkUrl(url)) {
switchOutDrawHistory();
- HashMap arg = new HashMap();
- arg.put("url", url);
- arg.put("data", postData);
+ WebViewCore.PostUrlData arg = new WebViewCore.PostUrlData();
+ arg.mUrl = url;
+ arg.mPostData = postData;
mWebViewCore.sendMessage(EventHub.POST_URL, arg);
clearTextEntry();
} else {
@@ -1273,12 +1243,12 @@ public class WebView extends AbsoluteLayout
return;
}
switchOutDrawHistory();
- HashMap arg = new HashMap();
- arg.put("baseUrl", baseUrl);
- arg.put("data", data);
- arg.put("mimeType", mimeType);
- arg.put("encoding", encoding);
- arg.put("failUrl", failUrl);
+ WebViewCore.BaseUrlData arg = new WebViewCore.BaseUrlData();
+ arg.mBaseUrl = baseUrl;
+ arg.mData = data;
+ arg.mMimeType = mimeType;
+ arg.mEncoding = encoding;
+ arg.mFailUrl = failUrl;
mWebViewCore.sendMessage(EventHub.LOAD_DATA, arg);
clearTextEntry();
}
@@ -1407,7 +1377,7 @@ public class WebView extends AbsoluteLayout
if (mNativeClass == 0) {
return false;
}
- nativeClearFocus(-1, -1);
+ nativeClearCursor(); // start next trackball movement from page edge
if (top) {
// go to the top of the document
return pinScrollTo(mScrollX, 0, true, 0);
@@ -1434,7 +1404,7 @@ public class WebView extends AbsoluteLayout
if (mNativeClass == 0) {
return false;
}
- nativeClearFocus(-1, -1);
+ nativeClearCursor(); // start next trackball movement from page edge
if (bottom) {
return pinScrollTo(mScrollX, mContentHeight, true, 0);
}
@@ -1530,7 +1500,7 @@ public class WebView extends AbsoluteLayout
}
/**
- * Return a HitTestResult based on the current focus node. If a HTML::a tag
+ * Return a HitTestResult based on the current cursor node. If a HTML::a tag
* is found and the anchor has a non-javascript url, the HitTestResult type
* is set to SRC_ANCHOR_TYPE and the url is set in the "extra" field. If the
* anchor does not have a url or if it is a javascript url, the type will
@@ -1602,15 +1572,15 @@ public class WebView extends AbsoluteLayout
* request as the data member with "url" as key. The result can
* be null.
*/
+ // FIXME: API change required to change the name of this function. We now
+ // look at the cursor node, and not the focus node. Also, what is
+ // getFocusNodePath?
public void requestFocusNodeHref(Message hrefMsg) {
if (hrefMsg == null || mNativeClass == 0) {
return;
}
if (nativeCursorIsAnchor()) {
- // NOTE: We may already have the url of the anchor stored in
- // node.mText but it may be out of date or the caller may want
- // to know about javascript urls.
- mWebViewCore.sendMessage(EventHub.REQUEST_FOCUS_HREF,
+ mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
nativeCursorFramePointer(), nativeCursorNodePointer(),
hrefMsg);
}
@@ -1981,6 +1951,15 @@ public class WebView extends AbsoluteLayout
}
/**
+ * Call this to inform the view that memory is low so that it can
+ * free any available memory.
+ * @hide
+ */
+ public void freeMemory() {
+ mWebViewCore.sendMessage(EventHub.FREE_MEMORY);
+ }
+
+ /**
* Clear the resource cache. Note that the cache is per-application, so
* this will clear the cache for all WebViews used.
*
@@ -2337,10 +2316,9 @@ public class WebView extends AbsoluteLayout
* @param interfaceName The name to used to expose the class in Javascript
*/
public void addJavascriptInterface(Object obj, String interfaceName) {
- // Use Hashmap rather than Bundle as Bundles can't cope with Objects
- HashMap arg = new HashMap();
- arg.put("object", obj);
- arg.put("interfaceName", interfaceName);
+ WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+ arg.mObject = obj;
+ arg.mInterfaceName = interfaceName;
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
}
@@ -2400,12 +2378,11 @@ public class WebView extends AbsoluteLayout
if (mTouchMode >= FIRST_SCROLL_ZOOM && mTouchMode <= LAST_SCROLL_ZOOM) {
scrollZoomDraw(canvas);
} else {
- nativeRecomputeFocus();
// Update the buttons in the picture, so when we draw the picture
// to the screen, they are in the correct state.
// Tell the native side if user is a) touching the screen,
// b) pressing the trackball down, or c) pressing the enter key
- // If the focus is a button, we need to draw it in the pressed
+ // If the cursor is on a button, we need to draw it in the pressed
// state.
// If mNativeClass is 0, we should not reach here, so we do not
// need to check it again.
@@ -2439,7 +2416,7 @@ public class WebView extends AbsoluteLayout
}
private void drawCoreAndCursorRing(Canvas canvas, int color,
- boolean drawFocus) {
+ boolean drawCursorRing) {
if (mDrawHistory) {
canvas.scale(mActualScale, mActualScale);
canvas.drawPicture(mHistoryPicture);
@@ -2497,7 +2474,7 @@ public class WebView extends AbsoluteLayout
nativeDrawSelection(canvas, mSelectX, mSelectY,
mExtendSelection);
}
- } else if (drawFocus) {
+ } else if (drawCursorRing) {
if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
mTouchMode = TOUCH_SHORTPRESS_MODE;
HitTestResult hitTest = getHitTestResult();
@@ -2723,7 +2700,10 @@ public class WebView extends AbsoluteLayout
}
}
- private boolean canZoomScrollOut() {
+ /**
+ * @hide
+ */
+ public boolean canZoomScrollOut() {
if (mContentWidth == 0 || mContentHeight == 0) {
return false;
}
@@ -2786,7 +2766,10 @@ public class WebView extends AbsoluteLayout
}
}
- private void zoomScrollOut() {
+ /**
+ * @hide
+ */
+ public void zoomScrollOut() {
if (canZoomScrollOut() == false) {
mTouchMode = TOUCH_DONE_MODE;
return;
@@ -2955,23 +2938,21 @@ public class WebView extends AbsoluteLayout
}
/*
- * This method checks the current focus and potentially rebuilds
+ * This method checks the current focus and cursor and potentially rebuilds
* mWebTextView to have the appropriate properties, such as password,
* multiline, and what text it contains. It also removes it if necessary.
*/
private void rebuildWebTextView() {
- // If we do not have focus, do nothing until we gain focus.
+ // If the WebView does not have focus, do nothing until it gains focus.
if (!hasFocus() && (null == mWebTextView || !mWebTextView.hasFocus())
|| (mTouchMode >= FIRST_SCROLL_ZOOM
&& mTouchMode <= LAST_SCROLL_ZOOM)) {
- mNeedsRebuildWebTextView = true;
return;
}
boolean alreadyThere = inEditingMode();
// inEditingMode can only return true if mWebTextView is non-null,
// so we can safely call remove() if (alreadyThere)
- if (0 == mNativeClass || (!nativeFocusIsTextInput()
- && !nativeCursorIsTextInput())) {
+ if (0 == mNativeClass || !nativeFocusCandidateIsTextInput()) {
if (alreadyThere) {
mWebTextView.remove();
}
@@ -2984,17 +2965,17 @@ public class WebView extends AbsoluteLayout
// Initialize our generation number.
mTextGeneration = 0;
}
- mWebTextView.setTextSize(contentToView(nativeFocusTextSize()));
+ mWebTextView.setTextSize(contentToView(nativeFocusCandidateTextSize()));
Rect visibleRect = sendOurVisibleRect();
// Note that sendOurVisibleRect calls viewToContent, so the coordinates
// should be in content coordinates.
- Rect bounds = nativeFocusNodeBounds();
+ Rect bounds = nativeFocusCandidateNodeBounds();
if (!Rect.intersects(bounds, visibleRect)) {
// Node is not on screen, so do not bother.
return;
}
- String text = nativeFocusText();
- int nodePointer = nativeFocusNodePointer();
+ String text = nativeFocusCandidateText();
+ int nodePointer = nativeFocusCandidatePointer();
if (alreadyThere && mWebTextView.isSameTextField(nodePointer)) {
// It is possible that we have the same textfield, but it has moved,
// i.e. In the case of opening/closing the screen.
@@ -3018,22 +2999,20 @@ public class WebView extends AbsoluteLayout
Rect vBox = contentToView(bounds);
mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
vBox.height());
- mWebTextView.setGravity(nativeFocusIsRtlText() ? Gravity.RIGHT :
- Gravity.NO_GRAVITY);
+ mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
+ Gravity.RIGHT : Gravity.NO_GRAVITY);
// this needs to be called before update adapter thread starts to
// ensure the mWebTextView has the same node pointer
mWebTextView.setNodePointer(nodePointer);
int maxLength = -1;
- boolean isTextField = nativeFocusIsTextField();
+ boolean isTextField = nativeFocusCandidateIsTextField();
if (isTextField) {
- maxLength = nativeFocusMaxLength();
- String name = nativeFocusName();
+ maxLength = nativeFocusCandidateMaxLength();
+ String name = nativeFocusCandidateName();
if (mWebViewCore.getSettings().getSaveFormData()
&& name != null) {
- HashMap data = new HashMap();
- data.put("text", text);
Message update = mPrivateHandler.obtainMessage(
- REQUEST_FORM_DATA, nodePointer, 0, data);
+ REQUEST_FORM_DATA, nodePointer);
RequestFormData updater = new RequestFormData(name,
getUrl(), update);
Thread t = new Thread(updater);
@@ -3044,7 +3023,7 @@ public class WebView extends AbsoluteLayout
AutoCompleteAdapter adapter = null;
mWebTextView.setAdapterCustom(adapter);
mWebTextView.setSingleLine(isTextField);
- mWebTextView.setInPassword(nativeFocusIsPassword());
+ mWebTextView.setInPassword(nativeFocusCandidateIsPassword());
if (null == text) {
mWebTextView.setText("", 0, 0);
} else {
@@ -3090,7 +3069,7 @@ public class WebView extends AbsoluteLayout
if (pastEntries.size() > 0) {
AutoCompleteAdapter adapter = new
AutoCompleteAdapter(mContext, pastEntries);
- ((HashMap) mUpdateMessage.obj).put("adapter", adapter);
+ mUpdateMessage.obj = adapter;
mUpdateMessage.sendToTarget();
}
}
@@ -3143,9 +3122,7 @@ public class WebView extends AbsoluteLayout
mSelectX = mScrollX + (int) mLastTouchX;
mSelectY = mScrollY + (int) mLastTouchY;
}
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
- nativeClearFocus(contentX, contentY);
+ nativeHideCursor();
}
if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
@@ -3212,6 +3189,19 @@ public class WebView extends AbsoluteLayout
}
}
+ if (nativeCursorWantsKeyEvents() && !nativeCursorMatchesFocus()) {
+ // This message will put the node in focus, for the DOM's notion
+ // of focus
+ mWebViewCore.sendMessage(EventHub.CLICK);
+ if (nativeCursorIsTextInput()) {
+ // This will bring up the WebTextView and put it in focus, for
+ // our view system's notion of focus
+ rebuildWebTextView();
+ // Now we need to pass the event to it
+ return mWebTextView.onKeyDown(keyCode, event);
+ }
+ }
+
// TODO: should we pass all the keys to DOM or check the meta tag
if (nativeCursorWantsKeyEvents() || true) {
// pass the key to DOM
@@ -3235,7 +3225,7 @@ public class WebView extends AbsoluteLayout
return false;
}
- // special CALL handling when focus node's href is "tel:XXX"
+ // special CALL handling when cursor node's href is "tel:XXX"
if (keyCode == KeyEvent.KEYCODE_CALL && nativeHasCursorNode()) {
String text = nativeCursorText();
if (!nativeCursorIsTextInput() && text != null
@@ -3319,9 +3309,7 @@ public class WebView extends AbsoluteLayout
public void emulateShiftHeld() {
mExtendSelection = false;
mShiftIsPressed = true;
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
- nativeClearFocus(contentX, contentY);
+ nativeHideCursor();
}
private boolean commitCopy() {
@@ -3377,7 +3365,6 @@ public class WebView extends AbsoluteLayout
if (child == this) {
if (inEditingMode()) {
clearTextEntry();
- mNeedsRebuildWebTextView = true;
}
}
}
@@ -3398,16 +3385,11 @@ public class WebView extends AbsoluteLayout
if (hasWindowFocus) {
if (hasFocus()) {
// If our window regained focus, and we have focus, then begin
- // drawing the cursor ring, and restore the TextView if
- // necessary.
+ // drawing the cursor ring
mDrawCursorRing = true;
- if (mNeedsRebuildWebTextView) {
- rebuildWebTextView();
- }
if (mNativeClass != 0) {
nativeRecordButtons(true, false, true);
}
- setFocusControllerActive(true);
} else {
// If our window gained focus, but we do not have it, do not
// draw the cursor ring.
@@ -3433,20 +3415,23 @@ public class WebView extends AbsoluteLayout
if (mNativeClass != 0) {
nativeRecordButtons(false, false, true);
}
- setFocusControllerActive(false);
+ setFocusControllerInactive();
}
invalidate();
super.onWindowFocusChanged(hasWindowFocus);
}
/*
- * Pass a message to WebCore Thread, determining whether the WebCore::Page's
- * FocusController is "active" so that it will draw the blinking cursor.
+ * Pass a message to WebCore Thread, telling the WebCore::Page's
+ * FocusController to be "inactive" so that it will
+ * not draw the blinking cursor. It gets set to "active" to draw the cursor
+ * in WebViewCore.cpp, when the WebCore thread receives key events/clicks.
*/
- private void setFocusControllerActive(boolean active) {
- if (mWebViewCore != null) {
- mWebViewCore.sendMessage(EventHub.SET_ACTIVE, active ? 1 : 0, 0);
- }
+ private void setFocusControllerInactive() {
+ // Do not need to also check whether mWebViewCore is null, because
+ // mNativeClass is only set if mWebViewCore is non null
+ if (mNativeClass == 0) return;
+ mWebViewCore.sendMessage(EventHub.SET_INACTIVE);
}
@Override
@@ -3457,20 +3442,12 @@ public class WebView extends AbsoluteLayout
}
if (focused) {
// When we regain focus, if we have window focus, resume drawing
- // the cursor ring, and add the TextView if necessary.
+ // the cursor ring
if (hasWindowFocus()) {
mDrawCursorRing = true;
- if (mNeedsRebuildWebTextView) {
- rebuildWebTextView();
- mNeedsRebuildWebTextView = false;
- }
if (mNativeClass != 0) {
nativeRecordButtons(true, false, true);
}
- // FIXME: This is unnecessary if we are gaining focus from the
- // WebTextView. How can we tell if it was the last thing in
- // focus?
- setFocusControllerActive(true);
//} else {
// The WebView has gained focus while we do not have
// windowfocus. When our window lost focus, we should have
@@ -3484,7 +3461,7 @@ public class WebView extends AbsoluteLayout
if (mNativeClass != 0) {
nativeRecordButtons(false, false, true);
}
- setFocusControllerActive(false);
+ setFocusControllerInactive();
}
mGotKeyDown = false;
}
@@ -3694,9 +3671,7 @@ public class WebView extends AbsoluteLayout
mTouchMode = TOUCH_DRAG_MODE;
WebViewCore.pauseUpdate(mWebViewCore);
- int contentX = viewToContent((int) x + mScrollX);
- int contentY = viewToContent((int) y + mScrollY);
- nativeClearFocus(contentX, contentY);
+ nativeHideCursor();
// remove the zoom anchor if there is any
if (mZoomScale != 0) {
mWebViewCore
@@ -3871,9 +3846,7 @@ public class WebView extends AbsoluteLayout
mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mTouchMode = TOUCH_DONE_MODE;
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
- nativeClearFocus(contentX, contentY);
+ nativeHideCursor();
break;
}
}
@@ -3901,8 +3874,8 @@ public class WebView extends AbsoluteLayout
private boolean mShiftIsPressed = false;
private boolean mTrackballDown = false;
private long mTrackballUpTime = 0;
- private long mLastFocusTime = 0;
- private Rect mLastFocusBounds;
+ private long mLastCursorTime = 0;
+ private Rect mLastCursorBounds;
// Set by default; BrowserActivity clears to interpret trackball data
// directly for movement. Currently, the framework only passes
@@ -3931,14 +3904,14 @@ public class WebView extends AbsoluteLayout
if (mNativeClass != 0) {
nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true);
}
- if (time - mLastFocusTime <= TRACKBALL_TIMEOUT
- && !mLastFocusBounds.equals(nativeGetCursorRingBounds())) {
- nativeSelectBestAt(mLastFocusBounds);
+ if (time - mLastCursorTime <= TRACKBALL_TIMEOUT
+ && !mLastCursorBounds.equals(nativeGetCursorRingBounds())) {
+ nativeSelectBestAt(mLastCursorBounds);
}
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "onTrackballEvent down ev=" + ev
+ " time=" + time
- + " mLastFocusTime=" + mLastFocusTime);
+ + " mLastCursorTime=" + mLastCursorTime);
}
if (isInTouchMode()) requestFocusFromTouch();
return false; // let common code in onKeyDown at it
@@ -4170,7 +4143,6 @@ public class WebView extends AbsoluteLayout
}
mUserScroll = true;
}
- mWebViewCore.sendMessage(EventHub.UNBLOCK_FOCUS);
}
public void flingScroll(int vx, int vy) {
@@ -4534,18 +4506,21 @@ public class WebView extends AbsoluteLayout
/* package */ void replaceTextfieldText(int oldStart, int oldEnd,
String replace, int newStart, int newEnd) {
- HashMap arg = new HashMap();
- arg.put("replace", replace);
- arg.put("start", Integer.valueOf(newStart));
- arg.put("end", Integer.valueOf(newEnd));
+ WebViewCore.ReplaceTextData arg = new WebViewCore.ReplaceTextData();
+ arg.mReplace = replace;
+ arg.mNewStart = newStart;
+ arg.mNewEnd = newEnd;
mTextGeneration++;
mWebViewCore.sendMessage(EventHub.REPLACE_TEXT, oldStart, oldEnd, arg);
}
/* package */ void passToJavaScript(String currentText, KeyEvent event) {
- HashMap arg = new HashMap();
- arg.put("event", event);
- arg.put("currentText", currentText);
+ if (nativeCursorWantsKeyEvents() && !nativeCursorMatchesFocus()) {
+ mWebViewCore.sendMessage(EventHub.CLICK);
+ }
+ WebViewCore.JSKeyData arg = new WebViewCore.JSKeyData();
+ arg.mEvent = event;
+ arg.mCurrentText = currentText;
// Increase our text generation number, and pass it to webcore thread
mTextGeneration++;
mWebViewCore.sendMessage(EventHub.PASS_TO_JS, mTextGeneration, 0, arg);
@@ -4714,14 +4689,8 @@ public class WebView extends AbsoluteLayout
if (mNativeClass == 0) {
break;
}
-// Do not reset the focus or clear the text; the user may have already
-// navigated or entered text at this point. The focus should have gotten
-// reset, if need be, when the focus cache was built. Similarly, the text
-// view should already be torn down and rebuilt if needed.
-// nativeResetFocus();
-// clearTextEntry();
- HashMap scaleLimit = (HashMap) msg.obj;
- int minScale = (Integer) scaleLimit.get("minScale");
+ ScaleLimitData scaleLimit = (ScaleLimitData) msg.obj;
+ int minScale = scaleLimit.mMinScale;
if (minScale == 0) {
mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
mMinZoomScaleFixed = false;
@@ -4729,7 +4698,7 @@ public class WebView extends AbsoluteLayout
mMinZoomScale = (float) (minScale / 100.0);
mMinZoomScaleFixed = true;
}
- int maxScale = (Integer) scaleLimit.get("maxScale");
+ int maxScale = scaleLimit.mMaxScale;
if (maxScale == 0) {
mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE;
} else {
@@ -4768,9 +4737,6 @@ public class WebView extends AbsoluteLayout
}
setNewZoomScale(scale, false);
break;
- case MARK_NODE_INVALID_ID:
- nativeMarkNodeInvalid(msg.arg1);
- break;
case UPDATE_TEXT_ENTRY_MSG_ID:
// this is sent after finishing resize in WebViewCore. Make
// sure the text edit box is still on the screen.
@@ -4779,11 +4745,6 @@ public class WebView extends AbsoluteLayout
}
rebuildWebTextView();
break;
- case RECOMPUTE_FOCUS_MSG_ID:
- if (mNativeClass != 0) {
- nativeRecomputeFocus();
- }
- break;
case INVAL_RECT_MSG_ID: {
Rect r = (Rect)msg.obj;
if (r == null) {
@@ -4796,10 +4757,8 @@ public class WebView extends AbsoluteLayout
break;
}
case REQUEST_FORM_DATA:
- HashMap data = (HashMap) msg.obj;
+ AutoCompleteAdapter adapter = (AutoCompleteAdapter) msg.obj;
if (mWebTextView.isSameTextField(msg.arg1)) {
- AutoCompleteAdapter adapter =
- (AutoCompleteAdapter) data.get("adapter");
mWebTextView.setAdapterCustom(adapter);
}
break;
@@ -5106,7 +5065,10 @@ public class WebView extends AbsoluteLayout
}
// called by JNI
- private void sendMoveMouseIfLatest() {
+ private void sendMoveMouseIfLatest(boolean setFocusControllerInactive) {
+ if (setFocusControllerInactive) {
+ setFocusControllerInactive();
+ }
mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE_IF_LATEST, cursorData());
}
@@ -5165,45 +5127,51 @@ public class WebView extends AbsoluteLayout
if (mNativeClass == 0) {
return false;
}
- mLastFocusTime = time;
- mLastFocusBounds = nativeGetCursorRingBounds();
- boolean keyHandled = nativeMoveFocus(keyCode, count, noScroll) == false;
+ mLastCursorTime = time;
+ mLastCursorBounds = nativeGetCursorRingBounds();
+ boolean keyHandled
+ = nativeMoveCursor(keyCode, count, noScroll) == false;
if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "navHandledKey mLastFocusBounds=" + mLastFocusBounds
- + " mLastFocusTime=" + mLastFocusTime
+ Log.v(LOGTAG, "navHandledKey mLastCursorBounds=" + mLastCursorBounds
+ + " mLastCursorTime=" + mLastCursorTime
+ " handled=" + keyHandled);
}
if (keyHandled == false || mHeightCanMeasure == false) {
return keyHandled;
}
- Rect contentFocus = nativeGetCursorRingBounds();
- if (contentFocus.isEmpty()) return keyHandled;
- Rect viewFocus = contentToView(contentFocus);
+ Rect contentCursorRingBounds = nativeGetCursorRingBounds();
+ if (contentCursorRingBounds.isEmpty()) return keyHandled;
+ Rect viewCursorRingBounds = contentToView(contentCursorRingBounds);
Rect visRect = new Rect();
calcOurVisibleRect(visRect);
Rect outset = new Rect(visRect);
int maxXScroll = visRect.width() / 2;
int maxYScroll = visRect.height() / 2;
outset.inset(-maxXScroll, -maxYScroll);
- if (Rect.intersects(outset, viewFocus) == false) {
+ if (Rect.intersects(outset, viewCursorRingBounds) == false) {
return keyHandled;
}
// FIXME: Necessary because ScrollView/ListView do not scroll left/right
- int maxH = Math.min(viewFocus.right - visRect.right, maxXScroll);
+ int maxH = Math.min(viewCursorRingBounds.right - visRect.right,
+ maxXScroll);
if (maxH > 0) {
pinScrollBy(maxH, 0, true, 0);
} else {
- maxH = Math.max(viewFocus.left - visRect.left, -maxXScroll);
+ maxH = Math.max(viewCursorRingBounds.left - visRect.left,
+ -maxXScroll);
if (maxH < 0) {
pinScrollBy(maxH, 0, true, 0);
}
}
- if (mLastFocusBounds.isEmpty()) return keyHandled;
- if (mLastFocusBounds.equals(contentFocus)) return keyHandled;
+ if (mLastCursorBounds.isEmpty()) return keyHandled;
+ if (mLastCursorBounds.equals(contentCursorRingBounds)) {
+ return keyHandled;
+ }
if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "navHandledKey contentFocus=" + contentFocus);
+ Log.v(LOGTAG, "navHandledKey contentCursorRingBounds="
+ + contentCursorRingBounds);
}
- requestRectangleOnScreen(viewFocus);
+ requestRectangleOnScreen(viewCursorRingBounds);
mUserScroll = true;
return keyHandled;
}
@@ -5233,7 +5201,7 @@ public class WebView extends AbsoluteLayout
nativeUpdateCachedTextfield(updatedText, mTextGeneration);
}
- private native void nativeClearFocus(int x, int y);
+ private native void nativeClearCursor();
private native void nativeCreate(int ptr);
private native int nativeCursorFramePointer();
private native Rect nativeCursorNodeBounds();
@@ -5243,6 +5211,10 @@ public class WebView extends AbsoluteLayout
private native boolean nativeCursorIsAnchor();
private native boolean nativeCursorIsTextInput();
private native String nativeCursorText();
+ /**
+ * Returns true if the native cursor node says it wants to handle key events
+ * (ala plugins). This can only be called if mNativeClass is non-zero!
+ */
private native boolean nativeCursorWantsKeyEvents();
private native void nativeDebugDump();
private native void nativeDestroy();
@@ -5254,36 +5226,31 @@ public class WebView extends AbsoluteLayout
private native void nativeDumpDisplayTree(String urlOrNull);
private native int nativeFindAll(String findLower, String findUpper);
private native void nativeFindNext(boolean forward);
- private native boolean nativeFocusIsPassword();
- private native boolean nativeFocusIsRtlText();
- private native boolean nativeFocusIsTextField();
- private native boolean nativeFocusIsTextInput();
- private native int nativeFocusMaxLength();
- private native String nativeFocusName();
- private native Rect nativeFocusNodeBounds();
- /* package */ native int nativeFocusNodePointer();
- private native String nativeFocusText();
- private native int nativeFocusTextSize();
- /**
- * Returns true if the native focus nodes says it wants to handle key events
- * (ala plugins). This can only be called if mNativeClass is non-zero!
- */
+ private native boolean nativeFocusCandidateIsPassword();
+ private native boolean nativeFocusCandidateIsRtlText();
+ private native boolean nativeFocusCandidateIsTextField();
+ private native boolean nativeFocusCandidateIsTextInput();
+ private native int nativeFocusCandidateMaxLength();
+ private native String nativeFocusCandidateName();
+ private native Rect nativeFocusCandidateNodeBounds();
+ /* package */ native int nativeFocusCandidatePointer();
+ private native String nativeFocusCandidateText();
+ private native int nativeFocusCandidateTextSize();
private native Rect nativeGetCursorRingBounds();
private native Region nativeGetSelection();
private native boolean nativeHasCursorNode();
private native boolean nativeHasFocusNode();
+ private native void nativeHideCursor();
private native String nativeImageURI(int x, int y);
private native void nativeInstrumentReport();
- private native void nativeMarkNodeInvalid(int node);
// return true if the page has been scrolled
private native boolean nativeMotionUp(int x, int y, int slop);
// returns false if it handled the key
- private native boolean nativeMoveFocus(int keyCode, int count,
+ private native boolean nativeMoveCursor(int keyCode, int count,
boolean noScroll);
private native int nativeMoveGeneration();
private native void nativeMoveSelection(int x, int y,
boolean extendSelection);
- private native void nativeRecomputeFocus();
// Like many other of our native methods, you must make sure that
// mNativeClass is not null before calling this method.
private native void nativeRecordButtons(boolean focused,
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index f4b99b9..90d0709 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -34,7 +34,6 @@ import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import java.util.ArrayList;
-import java.util.HashMap;
import junit.framework.Assert;
@@ -376,7 +375,7 @@ final class WebViewCore {
String currentText, int keyCode, int keyValue, boolean down,
boolean cap, boolean fn, boolean sym);
- private native void nativeSetFocusControllerActive(boolean active);
+ private native void nativeSetFocusControllerInactive();
private native void nativeSaveDocumentState(int frame);
@@ -395,8 +394,6 @@ final class WebViewCore {
private native boolean nativeHandleTouchEvent(int action, int x, int y);
- private native void nativeUnblockFocus();
-
private native void nativeUpdateFrameCache();
private native void nativeSetSnapAnchor(int x, int y);
@@ -515,6 +512,14 @@ final class WebViewCore {
}
}
+ static class BaseUrlData {
+ String mBaseUrl;
+ String mData;
+ String mMimeType;
+ String mEncoding;
+ String mFailUrl;
+ }
+
static class CursorData {
CursorData() {}
CursorData(int frame, int node, int x, int y) {
@@ -531,6 +536,27 @@ final class WebViewCore {
boolean mIgnoreNullFocus;
}
+ static class JSInterfaceData {
+ Object mObject;
+ String mInterfaceName;
+ }
+
+ static class JSKeyData {
+ String mCurrentText;
+ KeyEvent mEvent;
+ }
+
+ static class PostUrlData {
+ String mUrl;
+ byte[] mPostData;
+ }
+
+ static class ReplaceTextData {
+ String mReplace;
+ int mNewStart;
+ int mNewEnd;
+ }
+
static class TouchUpData {
int mMoveGeneration;
int mFrame;
@@ -574,7 +600,7 @@ final class WebViewCore {
"SINGLE_LISTBOX_CHOICE", // = 124;
"MESSAGE_RELAY", // = 125;
"SET_BACKGROUND_COLOR", // = 126;
- "UNBLOCK_FOCUS", // = 127;
+ "127", // = 127;
"SAVE_DOCUMENT_STATE", // = 128;
"GET_SELECTION", // = 129;
"WEBKIT_DRAW", // = 130;
@@ -584,14 +610,15 @@ final class WebViewCore {
"CLEAR_CONTENT", // = 134;
"SET_MOVE_MOUSE", // = 135;
"SET_MOVE_MOUSE_IF_LATEST", // = 136;
- "REQUEST_FOCUS_HREF", // = 137;
+ "REQUEST_CURSOR_HREF", // = 137;
"ADD_JS_INTERFACE", // = 138;
"LOAD_DATA", // = 139;
"TOUCH_UP", // = 140;
"TOUCH_EVENT", // = 141;
- "SET_ACTIVE", // = 142;
+ "SET_INACTIVE", // = 142;
"ON_PAUSE", // = 143
"ON_RESUME", // = 144
+ "FREE_MEMORY", // = 145
};
class EventHub {
@@ -623,7 +650,6 @@ final class WebViewCore {
static final int SINGLE_LISTBOX_CHOICE = 124;
static final int MESSAGE_RELAY = 125;
static final int SET_BACKGROUND_COLOR = 126;
- static final int UNBLOCK_FOCUS = 127;
static final int SAVE_DOCUMENT_STATE = 128;
static final int GET_SELECTION = 129;
static final int WEBKIT_DRAW = 130;
@@ -635,7 +661,7 @@ final class WebViewCore {
// UI nav messages
static final int SET_MOVE_MOUSE = 135;
static final int SET_MOVE_MOUSE_IF_LATEST = 136;
- static final int REQUEST_FOCUS_HREF = 137;
+ static final int REQUEST_CURSOR_HREF = 137;
static final int ADD_JS_INTERFACE = 138;
static final int LOAD_DATA = 139;
@@ -644,14 +670,16 @@ final class WebViewCore {
// message used to pass UI touch events to WebCore
static final int TOUCH_EVENT = 141;
- // Used to tell the focus controller whether to draw the blinking cursor
- // or not, based on whether the WebView has focus.
- static final int SET_ACTIVE = 142;
+ // Used to tell the focus controller not to draw the blinking cursor,
+ // based on whether the WebView has focus and whether the WebView's
+ // cursor matches the webpage's focus.
+ static final int SET_INACTIVE = 142;
- // pause/resume activity for just this DOM (unlike pauseTimers, which
+ // lifecycle activities for just this DOM (unlike pauseTimers, which
// is global)
static final int ON_PAUSE = 143;
static final int ON_RESUME = 144;
+ static final int FREE_MEMORY = 145;
// Network-based messaging
static final int CLEAR_SSL_PREF_TABLE = 150;
@@ -697,7 +725,7 @@ final class WebViewCore {
public void handleMessage(Message msg) {
if (DebugFlags.WEB_VIEW_CORE) {
Log.v(LOGTAG, msg.what < LOAD_URL || msg.what
- > SET_ACTIVE ? Integer.toString(msg.what)
+ > SET_INACTIVE ? Integer.toString(msg.what)
: HandlerDebugString[msg.what - LOAD_URL]);
}
switch (msg.what) {
@@ -718,15 +746,13 @@ final class WebViewCore {
break;
case POST_URL: {
- HashMap param = (HashMap) msg.obj;
- String url = (String) param.get("url");
- byte[] data = (byte[]) param.get("data");
- mBrowserFrame.postUrl(url, data);
+ PostUrlData param = (PostUrlData) msg.obj;
+ mBrowserFrame.postUrl(param.mUrl, param.mPostData);
break;
}
case LOAD_DATA:
- HashMap loadParams = (HashMap) msg.obj;
- String baseUrl = (String) loadParams.get("baseUrl");
+ BaseUrlData loadParams = (BaseUrlData) msg.obj;
+ String baseUrl = loadParams.mBaseUrl;
if (baseUrl != null) {
int i = baseUrl.indexOf(':');
if (i > 0) {
@@ -750,10 +776,10 @@ final class WebViewCore {
}
}
mBrowserFrame.loadData(baseUrl,
- (String) loadParams.get("data"),
- (String) loadParams.get("mimeType"),
- (String) loadParams.get("encoding"),
- (String) loadParams.get("failUrl"));
+ loadParams.mData,
+ loadParams.mMimeType,
+ loadParams.mEncoding,
+ loadParams.mFailUrl);
break;
case STOP_LOADING:
@@ -851,6 +877,11 @@ final class WebViewCore {
nativeResume();
break;
+ case FREE_MEMORY:
+ clearCache(false);
+ nativeFreeMemory();
+ break;
+
case SET_NETWORK_STATE:
if (BrowserFrame.sJavaBridge == null) {
throw new IllegalStateException("No WebView " +
@@ -861,10 +892,7 @@ final class WebViewCore {
break;
case CLEAR_CACHE:
- mBrowserFrame.clearCache();
- if (msg.arg1 == 1) {
- CacheManager.removeAllCacheFiles();
- }
+ clearCache(msg.arg1 == 1);
break;
case CLEAR_HISTORY:
@@ -873,24 +901,19 @@ final class WebViewCore {
break;
case REPLACE_TEXT:
- HashMap jMap = (HashMap) msg.obj;
- String replace = (String) jMap.get("replace");
- int newStart =
- ((Integer) jMap.get("start")).intValue();
- int newEnd =
- ((Integer) jMap.get("end")).intValue();
- nativeReplaceTextfieldText(msg.arg1,
- msg.arg2, replace, newStart, newEnd);
+ ReplaceTextData rep = (ReplaceTextData) msg.obj;
+ nativeReplaceTextfieldText(msg.arg1, msg.arg2,
+ rep.mReplace, rep.mNewStart, rep.mNewEnd);
break;
case PASS_TO_JS: {
- HashMap jsMap = (HashMap) msg.obj;
- KeyEvent evt = (KeyEvent) jsMap.get("event");
+ JSKeyData jsData = (JSKeyData) msg.obj;
+ KeyEvent evt = jsData.mEvent;
int keyCode = evt.getKeyCode();
int keyValue = evt.getUnicodeChar();
int generation = msg.arg1;
passToJs(generation,
- (String) jsMap.get("currentText"),
+ jsData.mCurrentText,
keyCode,
keyValue,
evt.isDown(),
@@ -900,8 +923,8 @@ final class WebViewCore {
}
case SAVE_DOCUMENT_STATE: {
- CursorData fDat = (CursorData) msg.obj;
- nativeSaveDocumentState(fDat.mFrame);
+ CursorData cDat = (CursorData) msg.obj;
+ nativeSaveDocumentState(cDat.mFrame);
break;
}
@@ -928,17 +951,14 @@ final class WebViewCore {
break;
}
- case SET_ACTIVE:
- nativeSetFocusControllerActive(msg.arg1 == 1);
+ case SET_INACTIVE:
+ nativeSetFocusControllerInactive();
break;
case ADD_JS_INTERFACE:
- HashMap map = (HashMap) msg.obj;
- Object obj = map.get("object");
- String interfaceName = (String)
- map.get("interfaceName");
- mBrowserFrame.addJavascriptInterface(obj,
- interfaceName);
+ JSInterfaceData jsData = (JSInterfaceData) msg.obj;
+ mBrowserFrame.addJavascriptInterface(jsData.mObject,
+ jsData.mInterfaceName);
break;
case REQUEST_EXT_REPRESENTATION:
@@ -951,25 +971,21 @@ final class WebViewCore {
break;
case SET_MOVE_MOUSE:
- CursorData finalData = (CursorData) msg.obj;
- nativeMoveMouse(finalData.mFrame,
- finalData.mNode, finalData.mX,
- finalData.mY);
- break;
-
- case UNBLOCK_FOCUS:
- nativeUnblockFocus();
+ CursorData cursorData = (CursorData) msg.obj;
+ nativeMoveMouse(cursorData.mFrame,
+ cursorData.mNode, cursorData.mX,
+ cursorData.mY);
break;
case SET_MOVE_MOUSE_IF_LATEST:
- CursorData focusData = (CursorData) msg.obj;
- nativeMoveMouseIfLatest(focusData.mMoveGeneration,
- focusData.mFrame, focusData.mNode,
- focusData.mX, focusData.mY,
- focusData.mIgnoreNullFocus);
+ CursorData cData = (CursorData) msg.obj;
+ nativeMoveMouseIfLatest(cData.mMoveGeneration,
+ cData.mFrame, cData.mNode,
+ cData.mX, cData.mY,
+ cData.mIgnoreNullFocus);
break;
- case REQUEST_FOCUS_HREF: {
+ case REQUEST_CURSOR_HREF: {
Message hrefMsg = (Message) msg.obj;
String res = nativeRetrieveHref(msg.arg1, msg.arg2);
hrefMsg.getData().putString("url", res);
@@ -1230,6 +1246,13 @@ final class WebViewCore {
// WebViewCore private methods
//-------------------------------------------------------------------------
+ private void clearCache(boolean includeDiskFiles) {
+ mBrowserFrame.clearCache();
+ if (includeDiskFiles) {
+ CacheManager.removeAllCacheFiles();
+ }
+ }
+
private void loadUrl(String url) {
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, " CORE loadUrl " + url);
mBrowserFrame.loadUrl(url);
@@ -1550,14 +1573,6 @@ final class WebViewCore {
}
// called by JNI
- private void sendMarkNodeInvalid(int node) {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
- WebView.MARK_NODE_INVALID_ID, node, 0).sendToTarget();
- }
- }
-
- // called by JNI
private void sendNotifyProgressFinished() {
sendUpdateTextEntry();
// as CacheManager can behave based on database transaction, we need to
@@ -1568,14 +1583,6 @@ final class WebViewCore {
contentDraw();
}
- // called by JNI
- private void sendRecomputeFocus() {
- if (mWebView != null) {
- Message.obtain(mWebView.mPrivateHandler,
- WebView.RECOMPUTE_FOCUS_MSG_ID).sendToTarget();
- }
- }
-
/* Called by JNI. The coordinates are in doc coordinates, so they need to
be scaled before they can be used by the view system, which happens
in WebView since it (and its thread) know the current scale factor.
@@ -1651,9 +1658,9 @@ final class WebViewCore {
// now notify webview
if (mWebView != null) {
- HashMap scaleLimit = new HashMap();
- scaleLimit.put("minScale", mViewportMinimumScale);
- scaleLimit.put("maxScale", mViewportMaximumScale);
+ WebView.ScaleLimitData scaleLimit = new WebView.ScaleLimitData();
+ scaleLimit.mMinScale = mViewportMinimumScale;
+ scaleLimit.mMaxScale = mViewportMaximumScale;
if (mRestoredScale > 0) {
Message.obtain(mWebView.mPrivateHandler,
@@ -1744,4 +1751,5 @@ final class WebViewCore {
private native void nativePause();
private native void nativeResume();
+ private native void nativeFreeMemory();
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 14a85f8..23a38db 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -41,18 +41,12 @@ import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import android.view.KeyCharacterMap;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;
import android.view.inputmethod.InputMethodManager;
import android.view.ContextMenu.ContextMenuInfo;
-import android.gesture.GestureOverlayView;
-import android.gesture.Gesture;
-import android.gesture.LetterRecognizer;
-import android.gesture.Prediction;
-import android.gesture.LetterRecognizers;
import com.android.internal.R;
@@ -73,7 +67,6 @@ import java.util.List;
* @attr ref android.R.styleable#AbsListView_cacheColorHint
* @attr ref android.R.styleable#AbsListView_fastScrollEnabled
* @attr ref android.R.styleable#AbsListView_smoothScrollbar
- * @attr ref android.R.styleable#AbsListView_gestures
*/
public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,
ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
@@ -102,31 +95,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
public static final int TRANSCRIPT_MODE_ALWAYS_SCROLL = 2;
/**
- * Disables gestures.
- *
- * @see #setGestures(int)
- * @see #GESTURES_JUMP
- * @see #GESTURES_FILTER
- */
- public static final int GESTURES_NONE = 0;
- /**
- * When a letter gesture is recognized the list jumps to a matching position.
- *
- * @see #setGestures(int)
- * @see #GESTURES_NONE
- * @see #GESTURES_FILTER
- */
- public static final int GESTURES_JUMP = 1;
- /**
- * When a letter gesture is recognized the letter is added to the filter.
- *
- * @see #setGestures(int)
- * @see #GESTURES_NONE
- * @see #GESTURES_JUMP
- */
- public static final int GESTURES_FILTER = 2;
-
- /**
* Indicates that we are not in the middle of a touch gesture
*/
static final int TOUCH_MODE_REST = -1;
@@ -461,19 +429,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*/
private FastScroller mFastScroller;
- /**
- * Indicates the type of gestures to use: GESTURES_NONE, GESTURES_FILTER or GESTURES_NONE
- */
- private int mGestures;
-
- // Used to implement the gestures overlay
- private GestureOverlayView mGesturesOverlay;
- private PopupWindow mGesturesPopup;
- private ViewTreeObserver.OnGlobalLayoutListener mGesturesLayoutListener;
- private boolean mGlobalLayoutListenerAddedGestures;
- private boolean mInstallGesturesOverlay;
- private boolean mPreviousGesturing;
-
private boolean mGlobalLayoutListenerAddedFilter;
private int mTouchSlop;
@@ -584,15 +539,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
setSmoothScrollbarEnabled(smoothScrollbar);
- int defaultGestures = GESTURES_NONE;
- if (useTextFilter) {
- defaultGestures = GESTURES_FILTER;
- } else if (enableFastScroll) {
- defaultGestures = GESTURES_JUMP;
- }
- int gestures = a.getInt(R.styleable.AbsListView_gestures, defaultGestures);
- setGestures(gestures);
-
a.recycle();
}
@@ -608,177 +554,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
- * <p>Sets the type of gestures to use with this list. When gestures are enabled,
- * that is if the <code>gestures</code> parameter is not {@link #GESTURES_NONE},
- * the user can draw characters on top of this view. When a character is
- * recognized and matches a known character, the list will either:</p>
- * <ul>
- * <li>Jump to the appropriate position ({@link #GESTURES_JUMP})</li>
- * <li>Add the character to the current filter ({@link #GESTURES_FILTER})</li>
- * </ul>
- * <p>Using {@link #GESTURES_JUMP} requires {@link #isFastScrollEnabled()} to
- * be true. Using {@link #GESTURES_FILTER} requires {@link #isTextFilterEnabled()}
- * to be true.</p>
- *
- * @param gestures The type of gestures to enable for this list:
- * {@link #GESTURES_NONE}, {@link #GESTURES_JUMP} or {@link #GESTURES_FILTER}
- *
- * @see #GESTURES_NONE
- * @see #GESTURES_JUMP
- * @see #GESTURES_FILTER
- * @see #getGestures()
- */
- public void setGestures(int gestures) {
- switch (gestures) {
- case GESTURES_JUMP:
- if (!mFastScrollEnabled) {
- throw new IllegalStateException("Jump gestures can only be used with "
- + "fast scroll enabled");
- }
- break;
- case GESTURES_FILTER:
- if (!mTextFilterEnabled) {
- throw new IllegalStateException("Filter gestures can only be used with "
- + "text filtering enabled");
- }
- break;
- }
-
- final int oldGestures = mGestures;
- mGestures = gestures;
-
- // Install overlay later
- if (oldGestures == GESTURES_NONE && gestures != GESTURES_NONE) {
- mInstallGesturesOverlay = true;
- // Uninstall overlay
- } else if (oldGestures != GESTURES_NONE && gestures == GESTURES_NONE) {
- uninstallGesturesOverlay();
- }
- }
-
- /**
- * Indicates what gestures are enabled on this view.
- *
- * @return {@link #GESTURES_NONE}, {@link #GESTURES_JUMP} or {@link #GESTURES_FILTER}
- *
- * @see #GESTURES_NONE
- * @see #GESTURES_JUMP
- * @see #GESTURES_FILTER
- * @see #setGestures(int)
- */
- @ViewDebug.ExportedProperty(mapping = {
- @ViewDebug.IntToString(from = GESTURES_NONE, to = "NONE"),
- @ViewDebug.IntToString(from = GESTURES_JUMP, to = "JUMP"),
- @ViewDebug.IntToString(from = GESTURES_FILTER, to = "FILTER")
- })
- public int getGestures() {
- return mGestures;
- }
-
- private void dismissGesturesPopup() {
- if (mGesturesPopup != null) {
- mGesturesPopup.dismiss();
- }
- }
-
- private void showGesturesPopup() {
- // Make sure we have a window before showing the popup
- if (getWindowVisibility() == View.VISIBLE) {
- installGesturesOverlay();
- positionGesturesPopup();
- }
- }
-
- private void positionGesturesPopup() {
- final int[] xy = new int[2];
- getLocationOnScreen(xy);
- if (!mGesturesPopup.isShowing()) {
- mGesturesPopup.showAtLocation(this, Gravity.LEFT | Gravity.TOP, xy[0], xy[1]);
- } else {
- mGesturesPopup.update(xy[0], xy[1], -1, -1);
- }
- }
-
- private void installGesturesOverlay() {
- mInstallGesturesOverlay = false;
-
- if (mGesturesPopup == null) {
- final Context c = getContext();
- final LayoutInflater layoutInflater = (LayoutInflater)
- c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mGesturesOverlay = (GestureOverlayView)
- layoutInflater.inflate(R.layout.list_gestures_overlay, null);
-
- final PopupWindow p = new PopupWindow(c);
- p.setFocusable(false);
- p.setTouchable(false);
- p.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
- p.setContentView(mGesturesOverlay);
- p.setWidth(getWidth());
- p.setHeight(getHeight());
- p.setBackgroundDrawable(null);
-
- if (mGesturesLayoutListener == null) {
- mGesturesLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
- public void onGlobalLayout() {
- if (isShown()) {
- showGesturesPopup();
- } else if (mGesturesPopup.isShowing()) {
- dismissGesturesPopup();
- }
- }
- };
- }
- getViewTreeObserver().addOnGlobalLayoutListener(mGesturesLayoutListener);
- mGlobalLayoutListenerAddedGestures = true;
-
- mGesturesPopup = p;
-
- mGesturesOverlay.removeAllOnGestureListeners();
- mGesturesOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
- mGesturesOverlay.addOnGesturePerformedListener(new GesturesProcessor());
-
- mPreviousGesturing = false;
- }
- }
-
- private void uninstallGesturesOverlay() {
- dismissGesturesPopup();
- mGesturesPopup = null;
- if (mGesturesLayoutListener != null) {
- getViewTreeObserver().removeGlobalOnLayoutListener(mGesturesLayoutListener);
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (mGestures != GESTURES_NONE) {
- if (ev.getAction() != MotionEvent.ACTION_DOWN || mFastScroller == null ||
- !mFastScroller.isPointInside(ev.getX(), ev.getY())) {
-
- if (mGesturesPopup.isShowing()) {
- mGesturesOverlay.dispatchTouchEvent(ev);
-
- final boolean isGesturing = mGesturesOverlay.isGesturing();
-
- if (!isGesturing) {
- mPreviousGesturing = isGesturing;
- return super.dispatchTouchEvent(ev);
- } else if (!mPreviousGesturing){
- mPreviousGesturing = isGesturing;
- final MotionEvent event = MotionEvent.obtain(ev);
- event.setAction(MotionEvent.ACTION_CANCEL);
- super.dispatchTouchEvent(event);
- return true;
- }
- }
- }
- }
-
- return super.dispatchTouchEvent(ev);
- }
-
- /**
* Enables fast scrolling by letting the user quickly scroll through lists by
* dragging the fast scroll thumb. The adapter attached to the list may want
* to implement {@link SectionIndexer} if it wishes to display alphabet preview and
@@ -1061,7 +836,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* about having leaked the window.
*/
dismissPopup();
- dismissGesturesPopup();
Parcelable superState = super.onSaveInstanceState();
@@ -1349,11 +1123,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mFiltered && visible && mPopup != null && mPopup.isShowing()) {
positionPopup();
}
-
- if (mGestures != GESTURES_NONE && visible && mGesturesPopup != null &&
- mGesturesPopup.isShowing()) {
- positionGesturesPopup();
- }
}
return changed;
@@ -1568,13 +1337,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mFastScroller != null) {
mFastScroller.onSizeChanged(w, h, oldw, oldh);
}
-
- if (mInstallGesturesOverlay) {
- installGesturesOverlay();
- positionGesturesPopup();
- } else if (mGesturesPopup != null && mGesturesPopup.isShowing()) {
- mGesturesPopup.update(w, h);
- }
}
/**
@@ -1761,10 +1523,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mTextFilterEnabled && mPopup != null && !mGlobalLayoutListenerAddedFilter) {
treeObserver.addOnGlobalLayoutListener(this);
}
- if (mGestures != GESTURES_NONE && mGesturesPopup != null &&
- !mGlobalLayoutListenerAddedGestures) {
- treeObserver.addOnGlobalLayoutListener(mGesturesLayoutListener);
- }
}
}
@@ -1779,10 +1537,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
treeObserver.removeGlobalOnLayoutListener(this);
mGlobalLayoutListenerAddedFilter = false;
}
- if (mGesturesLayoutListener != null && mGesturesPopup != null) {
- mGlobalLayoutListenerAddedGestures = false;
- treeObserver.removeGlobalOnLayoutListener(mGesturesLayoutListener);
- }
}
}
@@ -1797,7 +1551,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
removeCallbacks(mFlingRunnable);
// Always hide the type filter
dismissPopup();
- dismissGesturesPopup();
if (touchMode == TOUCH_MODE_OFF) {
// Remember the last selected element
@@ -1808,9 +1561,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Show the type filter only if a filter is in effect
showPopup();
}
- if (mGestures != GESTURES_NONE) {
- showGesturesPopup();
- }
// If we changed touch mode since the last time we had focus
if (touchMode != mLastTouchMode && mLastTouchMode != TOUCH_MODE_UNKNOWN) {
@@ -1931,8 +1681,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int longPressPosition, final long longPressId) {
boolean handled = false;
- dismissGesturesPopup();
-
if (mOnItemLongClickListener != null) {
handled = mOnItemLongClickListener.onItemLongClick(AbsListView.this, child,
longPressPosition, longPressId);
@@ -3853,79 +3601,4 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
-
- private class GesturesProcessor implements GestureOverlayView.OnGesturePerformedListener {
-
- private static final double SCORE_THRESHOLD = 0.1;
-
- private LetterRecognizer mRecognizer;
- private ArrayList<Prediction> mPredictions;
- private final KeyCharacterMap mKeyMap;
- private final char[] mHolder;
-
- GesturesProcessor() {
- mRecognizer = LetterRecognizers.fromType(getContext(),
- LetterRecognizers.RECOGNIZER_LATIN_LOWERCASE);
- if (mRecognizer == null) {
- setGestures(GESTURES_NONE);
- }
- if (mGestures == GESTURES_FILTER) {
- mKeyMap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
- mHolder = new char[1];
- } else {
- mKeyMap = null;
- mHolder = null;
- }
- }
-
- public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
- mPredictions = mRecognizer.recognize(gesture, mPredictions);
- if (!mPredictions.isEmpty()) {
- final Prediction prediction = mPredictions.get(0);
- if (prediction.score > SCORE_THRESHOLD) {
- switch (mGestures) {
- case GESTURES_JUMP:
- processJump(prediction);
- break;
- case GESTURES_FILTER:
- processFilter(prediction);
- break;
- }
- }
- }
- }
-
- private void processJump(Prediction prediction) {
- final Object[] sections = mFastScroller.getSections();
- if (sections != null) {
- final String name = prediction.name;
- final int count = sections.length;
-
- int index = -1;
- for (int i = 0; i < count; i++) {
- if (name.equalsIgnoreCase((String) sections[i])) {
- index = i;
- break;
- }
- }
-
- if (index != -1) {
- final SectionIndexer indexer = mFastScroller.getSectionIndexer();
- final int position = indexer.getPositionForSection(index);
- setSelection(position);
- }
- }
- }
-
- private void processFilter(Prediction prediction) {
- mHolder[0] = prediction.name.charAt(0);
- final KeyEvent[] events = mKeyMap.getEvents(mHolder);
- if (events != null) {
- for (KeyEvent event : events) {
- sendToTextFilter(event.getKeyCode(), event.getRepeatCount(),
- event);
- }
- }
- }
- }
}
diff --git a/core/java/android/widget/AlphabetIndexer.java b/core/java/android/widget/AlphabetIndexer.java
index 4e466a0..59b2c2a 100644
--- a/core/java/android/widget/AlphabetIndexer.java
+++ b/core/java/android/widget/AlphabetIndexer.java
@@ -28,7 +28,7 @@ import android.util.SparseIntArray;
* invalidates the cache if changes occur in the cursor.
* <p/>
* Your adapter is responsible for updating the cursor by calling {@link #setCursor} if the
- * cursor changes. {@link #getPositionForSection} method does the binary search for the starting
+ * cursor changes. {@link #getPositionForSection} method does the binary search for the starting
* index of a given section (alphabet).
*/
public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
@@ -37,33 +37,33 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
* Cursor that is used by the adapter of the list view.
*/
protected Cursor mDataCursor;
-
+
/**
* The index of the cursor column that this list is sorted on.
*/
protected int mColumnIndex;
-
+
/**
* The string of characters that make up the indexing sections.
*/
protected CharSequence mAlphabet;
-
+
/**
* Cached length of the alphabet array.
*/
private int mAlphabetLength;
-
+
/**
* This contains a cache of the computed indices so far. It will get reset whenever
* the dataset changes or the cursor changes.
*/
private SparseIntArray mAlphaMap;
-
+
/**
* Use a collator to compare strings in a localized manner.
*/
private java.text.Collator mCollator;
-
+
/**
* The section array converted from the alphabet string.
*/
@@ -72,9 +72,9 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
/**
* Constructs the indexer.
* @param cursor the cursor containing the data set
- * @param sortedColumnIndex the column number in the cursor that is sorted
+ * @param sortedColumnIndex the column number in the cursor that is sorted
* alphabetically
- * @param alphabet string containing the alphabet, with space as the first character.
+ * @param alphabet string containing the alphabet, with space as the first character.
* For example, use the string " ABCDEFGHIJKLMNOPQRSTUVWXYZ" for English indexing.
* The characters must be uppercase and be sorted in ascii/unicode order. Basically
* characters in the alphabet will show up as preview letters.
@@ -104,7 +104,7 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
public Object[] getSections() {
return mAlphabetArray;
}
-
+
/**
* Sets a new cursor as the data set and resets the cache of indices.
* @param cursor the new cursor to use as the data set
@@ -124,9 +124,16 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
* Default implementation compares the first character of word with letter.
*/
protected int compare(String word, String letter) {
- return mCollator.compare(word.substring(0, 1), letter);
+ final String firstLetter;
+ if (word.length() == 0) {
+ firstLetter = " ";
+ } else {
+ firstLetter = word.substring(0, 1);
+ }
+
+ return mCollator.compare(firstLetter, letter);
}
-
+
/**
* Performs a binary search or cache lookup to find the first row that
* matches a given section's starting letter.
@@ -143,7 +150,7 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
if (cursor == null || mAlphabet == null) {
return 0;
}
-
+
// Check bounds
if (sectionIndex <= 0) {
return 0;
@@ -164,7 +171,7 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
int key = letter;
// Check map
if (Integer.MIN_VALUE != (pos = alphaMap.get(key, Integer.MIN_VALUE))) {
- // Is it approximate? Using negative value to indicate that it's
+ // Is it approximate? Using negative value to indicate that it's
// an approximation and positive value when it is the accurate
// position.
if (pos < 0) {
@@ -204,7 +211,7 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
}
int diff = compare(curName, targetLetter);
if (diff != 0) {
- // Commenting out approximation code because it doesn't work for certain
+ // TODO: Commenting out approximation code because it doesn't work for certain
// lists with custom comparators
// Enter approximation in hash if a better solution doesn't exist
// String startingLetter = Character.toString(getFirstLetter(curName));
@@ -248,8 +255,8 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
public int getSectionForPosition(int position) {
int savedCursorPos = mDataCursor.getPosition();
mDataCursor.moveToPosition(position);
- mDataCursor.moveToPosition(savedCursorPos);
String curName = mDataCursor.getString(mColumnIndex);
+ mDataCursor.moveToPosition(savedCursorPos);
// Linear search, as there are only a few items in the section index
// Could speed this up later if it actually gets used.
for (int i = 0; i < mAlphabetLength; i++) {
@@ -259,9 +266,9 @@ public class AlphabetIndexer extends DataSetObserver implements SectionIndexer {
return i;
}
}
- return 0; // Don't recognize the letter - falls under zero'th section
+ return 0; // Don't recognize the letter - falls under zero'th section
}
-
+
/*
* @hide
*/
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index bfc5f08..ff95203 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -123,10 +123,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
private AutoCompleteTextView.ListSelectorHider mHideSelector;
- // Indicates whether this AutoCompleteTextView is attached to a window or not
- // The widget is attached to a window when mAttachCount > 0
- private int mAttachCount;
-
private AutoCompleteTextView.PassThroughClickListener mPassThroughClickListener;
public AutoCompleteTextView(Context context) {
@@ -936,6 +932,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
* @param text the selected suggestion in the drop down list
*/
protected void replaceText(CharSequence text) {
+ clearComposingText();
+
setText(text);
// make sure we keep the caret at the end of the text view
Editable spannable = getText();
@@ -944,7 +942,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
/** {@inheritDoc} */
public void onFilterComplete(int count) {
- if (mAttachCount <= 0) return;
+ // Not attached to window, don't update drop-down
+ if (getWindowVisibility() == View.GONE) return;
/*
* This checks enoughToFilter() again because filtering requests
@@ -983,13 +982,11 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- mAttachCount++;
}
@Override
protected void onDetachedFromWindow() {
dismissDropDown();
- mAttachCount--;
super.onDetachedFromWindow();
}
diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java
index 05abc26..ae80277 100644
--- a/core/java/android/widget/MultiAutoCompleteTextView.java
+++ b/core/java/android/widget/MultiAutoCompleteTextView.java
@@ -195,6 +195,8 @@ public class MultiAutoCompleteTextView extends AutoCompleteTextView {
*/
@Override
protected void replaceText(CharSequence text) {
+ clearComposingText();
+
int end = getSelectionEnd();
int start = mTokenizer.findTokenStart(getText(), end);
diff --git a/core/java/android/widget/SimpleCursorTreeAdapter.java b/core/java/android/widget/SimpleCursorTreeAdapter.java
index c456f56..a1c65f0 100644
--- a/core/java/android/widget/SimpleCursorTreeAdapter.java
+++ b/core/java/android/widget/SimpleCursorTreeAdapter.java
@@ -26,9 +26,16 @@ import android.view.View;
* defined in an XML file. You can specify which columns you want, which views
* you want to display the columns, and the XML file that defines the appearance
* of these views. Separate XML files for child and groups are possible.
- * TextViews bind the values to their text property (see
- * {@link TextView#setText(CharSequence)}). ImageViews bind the values to their
- * image's Uri property (see {@link ImageView#setImageURI(android.net.Uri)}).
+ *
+ * Binding occurs in two phases. First, if a
+ * {@link android.widget.SimpleCursorTreeAdapter.ViewBinder} is available,
+ * {@link ViewBinder#setViewValue(android.view.View, android.database.Cursor, int)}
+ * is invoked. If the returned value is true, binding has occurred. If the
+ * returned value is false and the view to bind is a TextView,
+ * {@link #setViewText(TextView, String)} is invoked. If the returned value
+ * is false and the view to bind is an ImageView,
+ * {@link #setViewImage(ImageView, String)} is invoked. If no appropriate
+ * binding can be found, an {@link IllegalStateException} is thrown.
*/
public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter {
/** The indices of columns that contain data to display for a group. */
@@ -48,6 +55,11 @@ public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter
private int[] mChildTo;
/**
+ * View binder, if supplied
+ */
+ private ViewBinder mViewBinder;
+
+ /**
* Constructor.
*
* @param context The context where the {@link ExpandableListView}
@@ -193,21 +205,53 @@ public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter
initFromColumns(childCursor, childFromNames, mChildFrom);
}
+ /**
+ * Returns the {@link ViewBinder} used to bind data to views.
+ *
+ * @return a ViewBinder or null if the binder does not exist
+ *
+ * @see #setViewBinder(android.widget.SimpleCursorTreeAdapter.ViewBinder)
+ */
+ public ViewBinder getViewBinder() {
+ return mViewBinder;
+ }
+
+ /**
+ * Sets the binder used to bind data to views.
+ *
+ * @param viewBinder the binder used to bind data to views, can be null to
+ * remove the existing binder
+ *
+ * @see #getViewBinder()
+ */
+ public void setViewBinder(ViewBinder viewBinder) {
+ mViewBinder = viewBinder;
+ }
+
private void bindView(View view, Context context, Cursor cursor, int[] from, int[] to) {
+ final ViewBinder binder = mViewBinder;
+
for (int i = 0; i < to.length; i++) {
View v = view.findViewById(to[i]);
if (v != null) {
- String text = cursor.getString(from[i]);
- if (text == null) {
- text = "";
+ boolean bound = false;
+ if (binder != null) {
+ bound = binder.setViewValue(v, cursor, from[i]);
}
- if (v instanceof TextView) {
- ((TextView) v).setText(text);
- } else if (v instanceof ImageView) {
- setViewImage((ImageView) v, text);
- } else {
- throw new IllegalStateException("SimpleCursorAdapter can bind values only to" +
- " TextView and ImageView!");
+
+ if (!bound) {
+ String text = cursor.getString(from[i]);
+ if (text == null) {
+ text = "";
+ }
+ if (v instanceof TextView) {
+ setViewText((TextView) v, text);
+ } else if (v instanceof ImageView) {
+ setViewImage((ImageView) v, text);
+ } else {
+ throw new IllegalStateException("SimpleCursorTreeAdapter can bind values" +
+ " only to TextView and ImageView!");
+ }
}
}
}
@@ -238,4 +282,48 @@ public abstract class SimpleCursorTreeAdapter extends ResourceCursorTreeAdapter
v.setImageURI(Uri.parse(value));
}
}
+
+ /**
+ * Called by bindView() to set the text for a TextView but only if
+ * there is no existing ViewBinder or if the existing ViewBinder cannot
+ * handle binding to an TextView.
+ *
+ * Intended to be overridden by Adapters that need to filter strings
+ * retrieved from the database.
+ *
+ * @param v TextView to receive text
+ * @param text the text to be set for the TextView
+ */
+ public void setViewText(TextView v, String text) {
+ v.setText(text);
+ }
+
+ /**
+ * This class can be used by external clients of SimpleCursorTreeAdapter
+ * to bind values from the Cursor to views.
+ *
+ * You should use this class to bind values from the Cursor to views
+ * that are not directly supported by SimpleCursorTreeAdapter or to
+ * change the way binding occurs for views supported by
+ * SimpleCursorTreeAdapter.
+ *
+ * @see SimpleCursorTreeAdapter#setViewImage(ImageView, String)
+ * @see SimpleCursorTreeAdapter#setViewText(TextView, String)
+ */
+ public static interface ViewBinder {
+ /**
+ * Binds the Cursor column defined by the specified index to the specified view.
+ *
+ * When binding is handled by this ViewBinder, this method must return true.
+ * If this method returns false, SimpleCursorTreeAdapter will attempts to handle
+ * the binding on its own.
+ *
+ * @param view the view to bind the data to
+ * @param cursor the cursor to get the data from
+ * @param columnIndex the column at which the data can be found in the cursor
+ *
+ * @return true if the data was bound to the view, false otherwise
+ */
+ boolean setViewValue(View view, Cursor cursor, int columnIndex);
+ }
}
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 5bf8035..103d44d 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -177,7 +177,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
// leaving touch mode.. if nothing has focus, let's give it to
// the indicator of the current tab
if (!mCurrentView.hasFocus() || mCurrentView.isFocused()) {
- mTabWidget.getChildAt(mCurrentTab).requestFocus();
+ mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
}
}
}
@@ -197,6 +197,12 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
}
View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView();
tabIndicator.setOnKeyListener(mTabKeyListener);
+
+ // If this is a custom view, then do not draw the bottom strips for
+ // the tab indicators.
+ if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) {
+ mTabWidget.setDrawBottomStrips(false);
+ }
mTabWidget.addView(tabIndicator);
mTabSpecs.add(tabSpec);
@@ -235,7 +241,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
public View getCurrentTabView() {
if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
- return mTabWidget.getChildAt(mCurrentTab);
+ return mTabWidget.getChildTabViewAt(mCurrentTab);
}
return null;
}
@@ -273,7 +279,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
&& (mCurrentView.isRootNamespace())
&& (mCurrentView.hasFocus())
&& (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
- mTabWidget.getChildAt(mCurrentTab).requestFocus();
+ mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
return true;
}
@@ -411,6 +417,14 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
}
/**
+ * Specify a view as the tab indicator.
+ */
+ public TabSpec setIndicator(View view) {
+ mIndicatorStrategy = new ViewIndicatorStrategy(view);
+ return this;
+ }
+
+ /**
* Specify the id of the view that should be used as the content
* of the tab.
*/
@@ -437,7 +451,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
}
- String getTag() {
+ public String getTag() {
return mTag;
}
}
@@ -526,6 +540,22 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
}
/**
+ * How to create a tab indicator by specifying a view.
+ */
+ private class ViewIndicatorStrategy implements IndicatorStrategy {
+
+ private final View mView;
+
+ private ViewIndicatorStrategy(View view) {
+ mView = view;
+ }
+
+ public View createIndicatorView() {
+ return mView;
+ }
+ }
+
+ /**
* How to create the tab content via a view id.
*/
private class ViewIdContentStrategy implements ContentStrategy {
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 20cddcb..a26bfa2 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -49,6 +49,8 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
private Drawable mBottomLeftStrip;
private Drawable mBottomRightStrip;
private boolean mStripMoved;
+ private Drawable mDividerDrawable;
+ private boolean mDrawBottomStrips = true;
public TabWidget(Context context) {
this(context, null);
@@ -87,9 +89,68 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
setOnFocusChangeListener(this);
}
+ /**
+ * Returns the tab indicator view at the given index.
+ *
+ * @param index the zero-based index of the tab indicator view to return
+ * @return the tab indicator view at the given index
+ */
+ public View getChildTabViewAt(int index) {
+ // If we are using dividers, then instead of tab views at 0, 1, 2, ...
+ // we have tab views at 0, 2, 4, ...
+ if (mDividerDrawable != null) {
+ index *= 2;
+ }
+ return getChildAt(index);
+ }
+
+ /**
+ * Returns the number of tab indicator views.
+ * @return the number of tab indicator views.
+ */
+ public int getTabCount() {
+ int children = getChildCount();
+
+ // If we have dividers, then we will always have an odd number of
+ // children: 1, 3, 5, ... and we want to convert that sequence to
+ // this: 1, 2, 3, ...
+ if (mDividerDrawable != null) {
+ children = (children + 1) / 2;
+ }
+ return children;
+ }
+
+ /**
+ * Sets the drawable to use as a divider between the tab indicators.
+ * @param drawable the divider drawable
+ */
+ public void setDividerDrawable(Drawable drawable) {
+ mDividerDrawable = drawable;
+ }
+
+ /**
+ * Sets the drawable to use as a divider between the tab indicators.
+ * @param resId the resource identifier of the drawable to use as a
+ * divider.
+ */
+ public void setDividerDrawable(int resId) {
+ mDividerDrawable = mContext.getResources().getDrawable(resId);
+ }
+
+ /**
+ * Controls whether the bottom strips on the tab indicators are drawn or
+ * not. The default is to draw them. If the user specifies a custom
+ * view for the tab indicators, then the TabHost class calls this method
+ * to disable drawing of the bottom strips.
+ * @param drawBottomStrips true if the bottom strips should be drawn.
+ */
+ void setDrawBottomStrips(boolean drawBottomStrips) {
+ mDrawBottomStrips = drawBottomStrips;
+ }
+
@Override
public void childDrawableStateChanged(View child) {
- if (child == getChildAt(mSelectedTab)) {
+ if (child == getChildTabViewAt(mSelectedTab)) {
// To make sure that the bottom strip is redrawn
invalidate();
}
@@ -100,7 +161,14 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
- View selectedChild = getChildAt(mSelectedTab);
+ // If the user specified a custom view for the tab indicators, then
+ // do not draw the bottom strips.
+ if (!mDrawBottomStrips) {
+ // Skip drawing the bottom strips.
+ return;
+ }
+
+ View selectedChild = getChildTabViewAt(mSelectedTab);
mBottomLeftStrip.setState(selectedChild.getDrawableState());
mBottomRightStrip.setState(selectedChild.getDrawableState());
@@ -157,13 +225,13 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
* @see #focusCurrentTab
*/
public void setCurrentTab(int index) {
- if (index < 0 || index >= getChildCount()) {
+ if (index < 0 || index >= getTabCount()) {
return;
}
- getChildAt(mSelectedTab).setSelected(false);
+ getChildTabViewAt(mSelectedTab).setSelected(false);
mSelectedTab = index;
- getChildAt(mSelectedTab).setSelected(true);
+ getChildTabViewAt(mSelectedTab).setSelected(true);
mStripMoved = true;
}
@@ -189,17 +257,17 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
// change the focus if applicable.
if (oldTab != index) {
- getChildAt(index).requestFocus();
+ getChildTabViewAt(index).requestFocus();
}
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
- int count = getChildCount();
+ int count = getTabCount();
- for (int i=0; i<count; i++) {
- View child = getChildAt(i);
+ for (int i = 0; i < count; i++) {
+ View child = getChildTabViewAt(i);
child.setEnabled(enabled);
}
}
@@ -218,17 +286,26 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
child.setFocusable(true);
child.setClickable(true);
+ // If we have dividers between the tabs and we already have at least one
+ // tab, then add a divider before adding the next tab.
+ if (mDividerDrawable != null && getTabCount() > 0) {
+ View divider = new View(mContext);
+ final LinearLayout.LayoutParams lp = new LayoutParams(
+ mDividerDrawable.getIntrinsicWidth(),
+ mDividerDrawable.getIntrinsicHeight());
+ lp.setMargins(0, 0, 0, 0);
+ divider.setLayoutParams(lp);
+ divider.setBackgroundDrawable(mDividerDrawable);
+ super.addView(divider);
+ }
super.addView(child);
// TODO: detect this via geometry with a tabwidget listener rather
// than potentially interfere with the view's listener
- child.setOnClickListener(new TabClickListener(getChildCount() - 1));
+ child.setOnClickListener(new TabClickListener(getTabCount() - 1));
child.setOnFocusChangeListener(this);
}
-
-
-
/**
* Provides a way for {@link TabHost} to be notified that the user clicked on a tab indicator.
*/
@@ -238,14 +315,15 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
public void onFocusChange(View v, boolean hasFocus) {
if (v == this && hasFocus) {
- getChildAt(mSelectedTab).requestFocus();
+ getChildTabViewAt(mSelectedTab).requestFocus();
return;
}
if (hasFocus) {
int i = 0;
- while (i < getChildCount()) {
- if (getChildAt(i) == v) {
+ int numTabs = getTabCount();
+ while (i < numTabs) {
+ if (getChildTabViewAt(i) == v) {
setCurrentTab(i);
mSelectionChangedListener.onTabSelectionChanged(i, false);
break;
diff --git a/core/java/android/widget/ViewSwitcher.java b/core/java/android/widget/ViewSwitcher.java
index f4f23a8..0dcaf95 100644
--- a/core/java/android/widget/ViewSwitcher.java
+++ b/core/java/android/widget/ViewSwitcher.java
@@ -16,8 +16,6 @@
package android.widget;
-import java.util.Map;
-
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
diff --git a/core/java/com/android/internal/backup/AdbTransport.java b/core/java/com/android/internal/backup/AdbTransport.java
deleted file mode 100644
index acb3273..0000000
--- a/core/java/com/android/internal/backup/AdbTransport.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.android.internal.backup;
-
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-
-/**
- * Backup transport for full backup over adb. This transport pipes everything to
- * a file in a known location in /cache, which 'adb backup' then pulls to the desktop
- * (deleting it afterwards).
- */
-
-public class AdbTransport extends IBackupTransport.Stub {
-
- public int startSession() throws RemoteException {
- return 0;
- }
-
- public int endSession() throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- public int performBackup(String packageName, ParcelFileDescriptor data)
- throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-}
diff --git a/core/java/com/android/internal/backup/GoogleTransport.java b/core/java/com/android/internal/backup/GoogleTransport.java
index 85ab21e..c089c23 100644
--- a/core/java/com/android/internal/backup/GoogleTransport.java
+++ b/core/java/com/android/internal/backup/GoogleTransport.java
@@ -1,5 +1,7 @@
package com.android.internal.backup;
+import android.backup.RestoreSet;
+import android.content.pm.PackageInfo;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -9,20 +11,40 @@ import android.os.RemoteException;
public class GoogleTransport extends IBackupTransport.Stub {
- public int endSession() throws RemoteException {
+ public long requestBackupTime() throws RemoteException {
+ return 0; // !!! TODO: implement real backoff policy
+ }
+
+ public int startSession() throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
- public int performBackup(String packageName, ParcelFileDescriptor data)
- throws RemoteException {
+ public int endSession() throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
- public int startSession() throws RemoteException {
+ public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data)
+ throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
+ // Restore handling
+ public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
+ // !!! TODO: real implementation
+ return null;
+ }
+
+ public PackageInfo[] getAppSet(int token) throws android.os.RemoteException {
+ // !!! TODO: real implementation
+ return new PackageInfo[0];
+ }
+
+ public int getRestoreData(int token, PackageInfo packageInfo, ParcelFileDescriptor data)
+ throws android.os.RemoteException {
+ // !!! TODO: real implementation
+ return 0;
+ }
}
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 2b44fe7..9daabca 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -16,7 +16,8 @@
package com.android.internal.backup;
-import android.os.Bundle;
+import android.backup.RestoreSet;
+import android.content.pm.PackageInfo;
import android.os.ParcelFileDescriptor;
/** {@hide} */
@@ -26,7 +27,7 @@ interface IBackupTransport {
1. set up the connection to the destination
- set up encryption
- for Google cloud, log in using the user's gaia credential or whatever
- - for sd, spin off the backup transport and establish communication with it
+ - for adb, just set up the all-in-one destination file
2. send each app's backup transaction
- parse the data file for key/value pointers etc
- send key/blobsize set to the Google cloud, get back quota ok/rejected response
@@ -37,9 +38,19 @@ interface IBackupTransport {
- sd target streams raw data into encryption envelope then to sd?
3. shut down connection to destination
- cloud: tear down connection etc
- - sd: close the file and shut down the writer proxy
+ - adb: close the file
*/
/**
+ * Verify that this is a suitable time for a backup pass. This should return zero
+ * if a backup is reasonable right now, false otherwise. This method will be called
+ * outside of the {@link #startSession}/{@link #endSession} pair.
+ *
+ * <p>If this is not a suitable time for a backup, the transport should suggest a
+ * backoff delay, in milliseconds, after which the Backup Manager should try again.
+ */
+ long requestBackupTime();
+
+ /**
* Establish a connection to the back-end data repository, if necessary. If the transport
* needs to initialize state that is not tied to individual applications' backup operations,
* this is where it should be done.
@@ -51,13 +62,45 @@ interface IBackupTransport {
/**
* Send one application's data to the backup destination.
*
- * @param packageName The identity of the application whose data is being backed up.
+ * @param packageInfo The identity of the application whose data is being backed up.
+ * This specifically includes the signature list for the package.
* @param data The data stream that resulted from invoking the application's
- * BackupService.doBackup() method. This may be a pipe rather than a
- * file on persistent media, so it may not be seekable.
+ * BackupService.doBackup() method. This may be a pipe rather than a file on
+ * persistent media, so it may not be seekable.
+ * @return Zero on success; a nonzero error code on failure.
+ */
+ int performBackup(in PackageInfo packageInfo, in ParcelFileDescriptor data);
+
+ /**
+ * Get the set of backups currently available over this transport.
+ *
+ * @return Descriptions of the set of restore images available for this device.
+ **/
+ RestoreSet[] getAvailableRestoreSets();
+
+ /**
+ * Get the set of applications from a given restore image.
+ *
+ * @param token A backup token as returned by {@link #getAvailableRestoreSets}.
+ * @return An array of PackageInfo objects describing all of the applications
+ * available for restore from this restore image. This should include the list
+ * of signatures for each package so that the Backup Manager can filter using that
+ * information.
+ */
+ PackageInfo[] getAppSet(int token);
+
+ /**
+ * Retrieve one application's data from the backing store.
+ *
+ * @param token The backup record from which a restore is being requested.
+ * @param packageInfo The identity of the application whose data is being restored.
+ * This must include the signature list for the package; it is up to the transport
+ * to verify that the requested app's signatures match the saved backup record
+ * because the transport cannot necessarily trust the client device.
+ * @param data An open, writable file into which the backup image should be stored.
* @return Zero on success; a nonzero error code on failure.
*/
- int performBackup(String packageName, in ParcelFileDescriptor data);
+ int getRestoreData(int token, in PackageInfo packageInfo, in ParcelFileDescriptor data);
/**
* Terminate the backup session, closing files, freeing memory, and cleaning up whatever
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
new file mode 100644
index 0000000..f7b89f2
--- /dev/null
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -0,0 +1,182 @@
+package com.android.internal.backup;
+
+import android.backup.BackupDataInput;
+import android.backup.BackupDataOutput;
+import android.backup.RestoreSet;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Backup transport for stashing stuff into a known location on disk, and
+ * later restoring from there. For testing only.
+ */
+
+public class LocalTransport extends IBackupTransport.Stub {
+ private static final String TAG = "LocalTransport";
+ private static final boolean DEBUG = true;
+
+ private Context mContext;
+ private PackageManager mPackageManager;
+ private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
+ private FileFilter mDirFileFilter = new FileFilter() {
+ public boolean accept(File f) {
+ return f.isDirectory();
+ }
+ };
+
+
+ public LocalTransport(Context context) {
+ if (DEBUG) Log.v(TAG, "Transport constructed");
+ mContext = context;
+ mPackageManager = context.getPackageManager();
+ }
+
+ public long requestBackupTime() throws RemoteException {
+ // any time is a good time for local backup
+ return 0;
+ }
+
+ public int startSession() throws RemoteException {
+ if (DEBUG) Log.v(TAG, "session started");
+ mDataDir.mkdirs();
+ return 0;
+ }
+
+ public int endSession() throws RemoteException {
+ if (DEBUG) Log.v(TAG, "session ended");
+ return 0;
+ }
+
+ public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data)
+ throws RemoteException {
+ if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName);
+ int err = 0;
+
+ File packageDir = new File(mDataDir, packageInfo.packageName);
+ packageDir.mkdirs();
+
+ // Each 'record' in the restore set is kept in its own file, named by
+ // the record key. Wind through the data file, extracting individual
+ // record operations and building a set of all the updates to apply
+ // in this update.
+ BackupDataInput changeSet = new BackupDataInput(data.getFileDescriptor());
+ try {
+ int bufSize = 512;
+ byte[] buf = new byte[bufSize];
+ while (changeSet.readNextHeader()) {
+ String key = changeSet.getKey();
+ int dataSize = changeSet.getDataSize();
+ if (DEBUG) Log.v(TAG, "Got change set key=" + key + " size=" + dataSize);
+ if (dataSize > bufSize) {
+ bufSize = dataSize;
+ buf = new byte[bufSize];
+ }
+ changeSet.readEntityData(buf, dataSize);
+ if (DEBUG) Log.v(TAG, " + data size " + dataSize);
+
+ File entityFile = new File(packageDir, key);
+ FileOutputStream entity = new FileOutputStream(entityFile);
+ try {
+ entity.write(buf, 0, dataSize);
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to update key file "
+ + entityFile.getAbsolutePath());
+ err = -1;
+ } finally {
+ entity.close();
+ }
+ }
+ } catch (IOException e) {
+ // oops, something went wrong. abort the operation and return error.
+ Log.v(TAG, "Exception reading backup input:");
+ e.printStackTrace();
+ err = -1;
+ }
+
+ return err;
+ }
+
+ // Restore handling
+ public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
+ // one hardcoded restore set
+ RestoreSet[] set = new RestoreSet[1];
+ set[0].device = "flash";
+ set[0].name = "Local disk image";
+ set[0].token = 0;
+ return set;
+ }
+
+ public PackageInfo[] getAppSet(int token) throws android.os.RemoteException {
+ if (DEBUG) Log.v(TAG, "getting app set " + token);
+ // the available packages are the extant subdirs of mDatadir
+ File[] packageDirs = mDataDir.listFiles(mDirFileFilter);
+ ArrayList<PackageInfo> packages = new ArrayList<PackageInfo>();
+ for (File dir : packageDirs) {
+ try {
+ PackageInfo pkg = mPackageManager.getPackageInfo(dir.getName(),
+ PackageManager.GET_SIGNATURES);
+ if (pkg != null) {
+ packages.add(pkg);
+ }
+ } catch (NameNotFoundException e) {
+ // restore set contains data for a package not installed on the
+ // phone -- just ignore it.
+ }
+ }
+
+ if (DEBUG) {
+ Log.v(TAG, "Built app set of " + packages.size() + " entries:");
+ for (PackageInfo p : packages) {
+ Log.v(TAG, " + " + p.packageName);
+ }
+ }
+
+ PackageInfo[] result = new PackageInfo[packages.size()];
+ return packages.toArray(result);
+ }
+
+ public int getRestoreData(int token, PackageInfo packageInfo, ParcelFileDescriptor outFd)
+ throws android.os.RemoteException {
+ if (DEBUG) Log.v(TAG, "getting restore data " + token + " : " + packageInfo.packageName);
+ // we only support one hardcoded restore set
+ if (token != 0) return -1;
+
+ // the data for a given package is at a known location
+ File packageDir = new File(mDataDir, packageInfo.packageName);
+
+ // The restore set is the concatenation of the individual record blobs,
+ // each of which is a file in the package's directory
+ File[] blobs = packageDir.listFiles();
+ int err = 0;
+ if (blobs != null && blobs.length > 0) {
+ BackupDataOutput out = new BackupDataOutput(mContext, outFd.getFileDescriptor());
+ try {
+ for (File f : blobs) {
+ FileInputStream in = new FileInputStream(f);
+ int size = (int) f.length();
+ byte[] buf = new byte[size];
+ in.read(buf);
+ out.writeEntityHeader(f.getName(), size);
+ out.writeEntityData(buf, size);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to read backup records");
+ err = -1;
+ }
+ }
+ return err;
+ }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 99a381c..16a3bad 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -30,9 +30,11 @@ import android.util.PrintWriterPrinter;
import android.util.Printer;
import android.util.SparseArray;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -53,7 +55,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 38;
+ private static final int VERSION = 39;
private final File mFile;
private final File mBackupFile;
@@ -94,7 +96,7 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mScreenOn;
StopwatchTimer mScreenOnTimer;
-
+
int mScreenBrightnessBin = -1;
final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
@@ -137,10 +139,10 @@ public final class BatteryStatsImpl extends BatteryStats {
long mTrackBatteryUptimeStart;
long mTrackBatteryPastRealtime;
long mTrackBatteryRealtimeStart;
-
+
long mUnpluggedBatteryUptime;
long mUnpluggedBatteryRealtime;
-
+
/*
* These keep track of battery levels (1-100) at the last plug event and the last unplug event.
*/
@@ -149,6 +151,15 @@ public final class BatteryStatsImpl extends BatteryStats {
long mLastWriteTime = 0; // Milliseconds
+ // Mobile data transferred while on battery
+ private long[] mMobileDataTx = new long[4];
+ private long[] mMobileDataRx = new long[4];
+ private long[] mTotalDataTx = new long[4];
+ private long[] mTotalDataRx = new long[4];
+
+ private long mRadioDataUptime;
+ private long mRadioDataStart;
+
/*
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
*/
@@ -893,7 +904,40 @@ public final class BatteryStatsImpl extends BatteryStats {
}
return kwlt;
}
-
+
+ private void doDataPlug(long[] dataTransfer, long currentBytes) {
+ dataTransfer[STATS_LAST] = dataTransfer[STATS_UNPLUGGED];
+ dataTransfer[STATS_UNPLUGGED] = -1;
+ }
+
+ private void doDataUnplug(long[] dataTransfer, long currentBytes) {
+ dataTransfer[STATS_UNPLUGGED] = currentBytes;
+ }
+
+ private long getCurrentRadioDataUptimeMs() {
+ try {
+ File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
+ if (!awakeTimeFile.exists()) return 0;
+ BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
+ String line = br.readLine();
+ br.close();
+ return Long.parseLong(line);
+ } catch (NumberFormatException nfe) {
+ // Nothing
+ } catch (IOException ioe) {
+ // Nothing
+ }
+ return 0;
+ }
+
+ public long getRadioDataUptimeMs() {
+ if (mRadioDataStart == -1) {
+ return mRadioDataUptime;
+ } else {
+ return getCurrentRadioDataUptimeMs() - mRadioDataStart;
+ }
+ }
+
public void doUnplug(long batteryUptime, long batteryRealtime) {
for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
Uid u = mUidStats.valueAt(iu);
@@ -905,8 +949,16 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
}
+ // Track total mobile data
+ doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
+ doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
+ doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
+ doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
+ // Track radio awake time
+ mRadioDataStart = getCurrentRadioDataUptimeMs();
+ mRadioDataUptime = 0;
}
-
+
public void doPlug(long batteryUptime, long batteryRealtime) {
for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
Uid u = mUidStats.valueAt(iu);
@@ -922,8 +974,15 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
}
+ doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
+ doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
+ doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
+ doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
+ // Track radio awake time
+ mRadioDataUptime = getRadioDataUptimeMs();
+ mRadioDataStart = -1;
}
-
+
public void noteStartGps(int uid) {
mUidStats.get(uid).noteStartGps();
}
@@ -931,7 +990,7 @@ public final class BatteryStatsImpl extends BatteryStats {
public void noteStopGps(int uid) {
mUidStats.get(uid).noteStopGps();
}
-
+
public void noteScreenOnLocked() {
if (!mScreenOn) {
mScreenOn = true;
@@ -1039,6 +1098,7 @@ public final class BatteryStatsImpl extends BatteryStats {
break;
}
}
+ if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
if (mPhoneDataConnectionType != bin) {
if (mPhoneDataConnectionType >= 0) {
mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
@@ -2701,7 +2761,44 @@ public final class BatteryStatsImpl extends BatteryStats {
public long getBatteryRealtime(long curTime) {
return getBatteryRealtimeLocked(curTime);
}
-
+
+ private long getTcpBytes(long current, long[] dataBytes, int which) {
+ if (which == STATS_LAST) {
+ return dataBytes[STATS_LAST];
+ } else {
+ if (which == STATS_UNPLUGGED) {
+ if (dataBytes[STATS_UNPLUGGED] < 0) {
+ return dataBytes[STATS_LAST];
+ } else {
+ return current - dataBytes[STATS_UNPLUGGED];
+ }
+ } else if (which == STATS_TOTAL) {
+ return (current - dataBytes[STATS_CURRENT]) + dataBytes[STATS_TOTAL];
+ }
+ return current - dataBytes[STATS_CURRENT];
+ }
+ }
+
+ /** Only STATS_UNPLUGGED works properly */
+ public long getMobileTcpBytesSent(int which) {
+ return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
+ }
+
+ /** Only STATS_UNPLUGGED works properly */
+ public long getMobileTcpBytesReceived(int which) {
+ return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
+ }
+
+ /** Only STATS_UNPLUGGED works properly */
+ public long getTotalTcpBytesSent(int which) {
+ return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
+ }
+
+ /** Only STATS_UNPLUGGED works properly */
+ public long getTotalTcpBytesReceived(int which) {
+ return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
+ }
+
@Override
public int getDischargeStartLevel() {
synchronized(this) {
@@ -3227,6 +3324,18 @@ public final class BatteryStatsImpl extends BatteryStats {
mDischargeCurrentLevel = in.readInt();
mLastWriteTime = in.readLong();
+ mMobileDataRx[STATS_LAST] = in.readLong();
+ mMobileDataRx[STATS_UNPLUGGED] = -1;
+ mMobileDataTx[STATS_LAST] = in.readLong();
+ mMobileDataTx[STATS_UNPLUGGED] = -1;
+ mTotalDataRx[STATS_LAST] = in.readLong();
+ mTotalDataRx[STATS_UNPLUGGED] = -1;
+ mTotalDataTx[STATS_LAST] = in.readLong();
+ mTotalDataTx[STATS_UNPLUGGED] = -1;
+
+ mRadioDataUptime = in.readLong();
+ mRadioDataStart = -1;
+
mKernelWakelockStats.clear();
int NKW = in.readInt();
for (int ikw = 0; ikw < NKW; ikw++) {
@@ -3301,6 +3410,14 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(mDischargeCurrentLevel);
out.writeLong(mLastWriteTime);
+ out.writeLong(getMobileTcpBytesReceived(STATS_UNPLUGGED));
+ out.writeLong(getMobileTcpBytesSent(STATS_UNPLUGGED));
+ out.writeLong(getTotalTcpBytesReceived(STATS_UNPLUGGED));
+ out.writeLong(getTotalTcpBytesSent(STATS_UNPLUGGED));
+
+ // Write radio uptime for data
+ out.writeLong(getRadioDataUptimeMs());
+
out.writeInt(mKernelWakelockStats.size());
for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
SamplingTimer kwlt = ent.getValue();
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index f08dddd..a37bf6e 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -26,6 +26,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
/**
@@ -118,26 +119,28 @@ public class PowerProfile {
*/
public static final String POWER_VIDEO = "dsp.video";
- static final HashMap<String, Double> sPowerMap = new HashMap<String, Double>();
+ static final HashMap<String, Object> sPowerMap = new HashMap<String, Object>();
private static final String TAG_DEVICE = "device";
private static final String TAG_ITEM = "item";
+ private static final String TAG_ARRAY = "array";
+ private static final String TAG_ARRAYITEM = "value";
private static final String ATTR_NAME = "name";
- public PowerProfile(Context context, CharSequence profile) {
+ public PowerProfile(Context context) {
// Read the XML file for the given profile (normally only one per
// device)
if (sPowerMap.size() == 0) {
- readPowerValuesFromXml(context, profile);
+ readPowerValuesFromXml(context);
}
}
- private void readPowerValuesFromXml(Context context, CharSequence profile) {
- // FIXME
- //int id = context.getResources().getIdentifier(profile.toString(), "xml",
- // "com.android.internal");
- int id = com.android.internal.R.xml.power_profile_default;
+ private void readPowerValuesFromXml(Context context) {
+ int id = com.android.internal.R.xml.power_profile;
XmlResourceParser parser = context.getResources().getXml(id);
+ boolean parsingArray = false;
+ ArrayList<Double> array = new ArrayList<Double>();
+ String arrayName = null;
try {
XmlUtils.beginDocument(parser, TAG_DEVICE);
@@ -145,22 +148,39 @@ public class PowerProfile {
while (true) {
XmlUtils.nextElement(parser);
- String element = parser.getName();
- if (element == null || !(element.equals(TAG_ITEM))) {
- break;
+ String element = parser.getName();
+ if (element == null) break;
+
+ if (parsingArray && !element.equals(TAG_ARRAYITEM)) {
+ // Finish array
+ sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
+ parsingArray = false;
}
-
- String name = parser.getAttributeValue(null, ATTR_NAME);
- if (parser.next() == XmlPullParser.TEXT) {
- String power = parser.getText();
- double value = 0;
- try {
- value = Double.valueOf(power);
- } catch (NumberFormatException nfe) {
+ if (element.equals(TAG_ARRAY)) {
+ parsingArray = true;
+ array.clear();
+ arrayName = parser.getAttributeValue(null, ATTR_NAME);
+ } else if (element.equals(TAG_ITEM) || element.equals(TAG_ARRAYITEM)) {
+ String name = null;
+ if (!parsingArray) name = parser.getAttributeValue(null, ATTR_NAME);
+ if (parser.next() == XmlPullParser.TEXT) {
+ String power = parser.getText();
+ double value = 0;
+ try {
+ value = Double.valueOf(power);
+ } catch (NumberFormatException nfe) {
+ }
+ if (element.equals(TAG_ITEM)) {
+ sPowerMap.put(name, value);
+ } else if (parsingArray) {
+ array.add(value);
+ }
}
- sPowerMap.put(name, value);
}
}
+ if (parsingArray) {
+ sPowerMap.put(arrayName, array.toArray(new Double[array.size()]));
+ }
} catch (XmlPullParserException e) {
throw new RuntimeException(e);
} catch (IOException e) {
@@ -177,7 +197,40 @@ public class PowerProfile {
*/
public double getAveragePower(String type) {
if (sPowerMap.containsKey(type)) {
- return sPowerMap.get(type);
+ Object data = sPowerMap.get(type);
+ if (data instanceof Double[]) {
+ return ((Double[])data)[0];
+ } else {
+ return (Double) sPowerMap.get(type);
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the average current in mA consumed by the subsystem for the given level.
+ * @param type the subsystem type
+ * @param level the level of power at which the subsystem is running. For instance, the
+ * signal strength of the cell network between 0 and 4 (if there are 4 bars max.).
+ * If there is no data for multiple levels, the level is ignored.
+ * @return the average current in milliAmps.
+ */
+ public double getAveragePower(String type, int level) {
+ if (sPowerMap.containsKey(type)) {
+ Object data = sPowerMap.get(type);
+ if (data instanceof double[]) {
+ final double[] values = (double[]) data;
+ if (values.length > level) {
+ return values[level];
+ } else if (values.length < 0) {
+ return values[0];
+ } else {
+ return values[values.length - 1];
+ }
+ } else {
+ return (Double) data;
+ }
} else {
return 0;
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index fa2bb22..989286e 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -525,7 +525,7 @@ public class ZygoteInit {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
- "--capabilities=121715744,121715744",
+ "--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
diff --git a/core/java/com/google/android/util/GoogleWebContentHelper.java b/core/java/com/google/android/util/GoogleWebContentHelper.java
index 3cdf855..8291e29 100644
--- a/core/java/com/google/android/util/GoogleWebContentHelper.java
+++ b/core/java/com/google/android/util/GoogleWebContentHelper.java
@@ -131,6 +131,10 @@ public class GoogleWebContentHelper {
return this;
}
+ /**
+ * Loads data into the webview and also provides a failback url
+ * @return This {@link GoogleWebContentHelper} so methods can be chained.
+ */
public GoogleWebContentHelper loadDataWithFailUrl(String base, String data,
String mimeType, String encoding, String failUrl) {
ensureViews();
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index f6f4c70..9066233 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -117,6 +117,7 @@ LOCAL_SRC_FILES:= \
android_location_GpsLocationProvider.cpp \
com_android_internal_os_ZygoteInit.cpp \
com_android_internal_graphics_NativeUtils.cpp \
+ android_backup_BackupDataInput.cpp \
android_backup_BackupDataOutput.cpp \
android_backup_FileBackupHelper.cpp
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6de37f0..4512fef 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -153,6 +153,7 @@ extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env);
extern int register_android_util_Base64(JNIEnv* env);
extern int register_android_location_GpsLocationProvider(JNIEnv* env);
+extern int register_android_backup_BackupDataInput(JNIEnv *env);
extern int register_android_backup_BackupDataOutput(JNIEnv *env);
extern int register_android_backup_FileBackupHelper(JNIEnv *env);
@@ -1168,6 +1169,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_ddm_DdmHandleNativeHeap),
REG_JNI(register_android_util_Base64),
REG_JNI(register_android_location_GpsLocationProvider),
+ REG_JNI(register_android_backup_BackupDataInput),
REG_JNI(register_android_backup_BackupDataOutput),
REG_JNI(register_android_backup_FileBackupHelper),
};
diff --git a/core/jni/android_backup_BackupDataInput.cpp b/core/jni/android_backup_BackupDataInput.cpp
new file mode 100644
index 0000000..5b2fb73
--- /dev/null
+++ b/core/jni/android_backup_BackupDataInput.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FileBackupHelper_native"
+#include <utils/Log.h>
+
+#include "JNIHelp.h"
+#include <android_runtime/AndroidRuntime.h>
+
+#include <utils/BackupHelpers.h>
+
+namespace android
+{
+
+// java.io.FileDescriptor
+static jfieldID s_descriptorField = 0;
+
+// android.backup.BackupDataInput$EntityHeader
+static jfieldID s_keyField = 0;
+static jfieldID s_dataSizeField = 0;
+
+static int
+ctor_native(JNIEnv* env, jobject clazz, jobject fileDescriptor)
+{
+ int err;
+
+ int fd = env->GetIntField(fileDescriptor, s_descriptorField);
+ if (fd == -1) {
+ return NULL;
+ }
+
+ return (int)new BackupDataReader(fd);
+}
+
+static void
+dtor_native(JNIEnv* env, jobject clazz, int r)
+{
+ delete (BackupDataReader*)r;
+}
+
+static jint
+readNextHeader_native(JNIEnv* env, jobject clazz, int r, jobject entity)
+{
+ int err;
+ BackupDataReader* reader = (BackupDataReader*)r;
+
+ err = reader->Status();
+ if (err != 0) {
+ return err < 0 ? err : -1;
+ }
+
+ int type = 0;
+
+ err = reader->ReadNextHeader(&type);
+ if (err == EIO) {
+ // Clean EOF with no footer block; just claim we're done
+ return 1;
+ }
+
+ if (err != 0) {
+ return err < 0 ? err : -1;
+ }
+
+ switch (type) {
+ case BACKUP_HEADER_APP_V1:
+ {
+ String8 packageName;
+ int cookie;
+ err = reader->ReadAppHeader(&packageName, &cookie);
+ if (err != 0) {
+ LOGD("ReadAppHeader() returned %d; aborting", err);
+ return err < 0 ? err : -1;
+ }
+ break;
+ }
+ case BACKUP_HEADER_ENTITY_V1:
+ {
+ String8 key;
+ size_t dataSize;
+ err = reader->ReadEntityHeader(&key, &dataSize);
+ if (err != 0) {
+ LOGD("ReadEntityHeader(); aborting", err);
+ return err < 0 ? err : -1;
+ }
+ // TODO: Set the fields in the entity object
+ jstring keyStr = env->NewStringUTF(key.string());
+ env->SetObjectField(entity, s_keyField, keyStr);
+ env->SetIntField(entity, s_dataSizeField, dataSize);
+ return 0;
+ }
+ case BACKUP_FOOTER_APP_V1:
+ {
+ break;
+ }
+ default:
+ LOGD("Unknown header type: 0x%08x\n", type);
+ return -1;
+ }
+
+ // done
+ return 1;
+}
+
+static jint
+readEntityData_native(JNIEnv* env, jobject clazz, int r, jbyteArray data, int size)
+{
+ int err;
+ BackupDataReader* reader = (BackupDataReader*)r;
+
+ if (env->GetArrayLength(data) < size) {
+ // size mismatch
+ return -1;
+ }
+
+ jbyte* dataBytes = env->GetByteArrayElements(data, NULL);
+ if (dataBytes == NULL) {
+ return -2;
+ }
+
+ err = reader->ReadEntityData(dataBytes, size);
+
+ env->ReleaseByteArrayElements(data, dataBytes, 0);
+
+ return err;
+}
+
+static const JNINativeMethod g_methods[] = {
+ { "ctor", "(Ljava/io/FileDescriptor;)I", (void*)ctor_native },
+ { "dtor", "(I)V", (void*)dtor_native },
+ { "readNextHeader_native", "(ILandroid/backup/BackupDataInput$EntityHeader;)I",
+ (void*)readNextHeader_native },
+ { "readEntityData_native", "(I[BI)I", (void*)readEntityData_native },
+};
+
+int register_android_backup_BackupDataInput(JNIEnv* env)
+{
+ //LOGD("register_android_backup_BackupDataInput");
+
+ jclass clazz;
+
+ clazz = env->FindClass("java/io/FileDescriptor");
+ LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor");
+ s_descriptorField = env->GetFieldID(clazz, "descriptor", "I");
+ LOG_FATAL_IF(s_descriptorField == NULL,
+ "Unable to find descriptor field in java.io.FileDescriptor");
+
+ clazz = env->FindClass("android/backup/BackupDataInput$EntityHeader");
+ LOG_FATAL_IF(clazz == NULL, "Unable to find class android.backup.BackupDataInput.EntityHeader");
+ s_keyField = env->GetFieldID(clazz, "key", "Ljava/lang/String;");
+ LOG_FATAL_IF(s_keyField == NULL,
+ "Unable to find key field in android.backup.BackupDataInput.EntityHeader");
+ s_dataSizeField = env->GetFieldID(clazz, "dataSize", "I");
+ LOG_FATAL_IF(s_dataSizeField == NULL,
+ "Unable to find dataSize field in android.backup.BackupDataInput.EntityHeader");
+
+ return AndroidRuntime::registerNativeMethods(env, "android/backup/BackupDataInput",
+ g_methods, NELEM(g_methods));
+}
+
+}
diff --git a/core/jni/android_backup_BackupDataOutput.cpp b/core/jni/android_backup_BackupDataOutput.cpp
index aab1233..6362439 100644
--- a/core/jni/android_backup_BackupDataOutput.cpp
+++ b/core/jni/android_backup_BackupDataOutput.cpp
@@ -28,7 +28,7 @@ namespace android
static jfieldID s_descriptorField = 0;
static int
-ctor_native(JNIEnv* env, jobject This, jobject fileDescriptor)
+ctor_native(JNIEnv* env, jobject clazz, jobject fileDescriptor)
{
int err;
@@ -41,19 +41,62 @@ ctor_native(JNIEnv* env, jobject This, jobject fileDescriptor)
}
static void
-dtor_native(JNIEnv* env, jobject This, int fd)
+dtor_native(JNIEnv* env, jobject clazz, int w)
{
- delete (BackupDataWriter*)fd;
+ delete (BackupDataWriter*)w;
+}
+
+static jint
+writeEntityHeader_native(JNIEnv* env, jobject clazz, int w, jstring key, int dataSize)
+{
+ int err;
+ BackupDataWriter* writer = (BackupDataWriter*)w;
+
+ const char* keyUTF = env->GetStringUTFChars(key, NULL);
+ if (keyUTF == NULL) {
+ return -1;
+ }
+
+ err = writer->WriteEntityHeader(String8(keyUTF), dataSize);
+
+ env->ReleaseStringUTFChars(key, keyUTF);
+
+ return err;
+}
+
+static jint
+writeEntityData_native(JNIEnv* env, jobject clazz, int w, jbyteArray data, int size)
+{
+ int err;
+ BackupDataWriter* writer = (BackupDataWriter*)w;
+
+ if (env->GetArrayLength(data) > size) {
+ // size mismatch
+ return -1;
+ }
+
+ jbyte* dataBytes = env->GetByteArrayElements(data, NULL);
+ if (dataBytes == NULL) {
+ return -1;
+ }
+
+ err = writer->WriteEntityData(dataBytes, size);
+
+ env->ReleaseByteArrayElements(data, dataBytes, JNI_ABORT);
+
+ return err;
}
static const JNINativeMethod g_methods[] = {
{ "ctor", "(Ljava/io/FileDescriptor;)I", (void*)ctor_native },
{ "dtor", "(I)V", (void*)dtor_native },
+ { "writeEntityHeader_native", "(ILjava/lang/String;I)I", (void*)writeEntityHeader_native },
+ { "writeEntityData_native", "(I[BI)I", (void*)writeEntityData_native },
};
int register_android_backup_BackupDataOutput(JNIEnv* env)
{
- LOGD("register_android_backup_BackupDataOutput");
+ //LOGD("register_android_backup_BackupDataOutput");
jclass clazz;
diff --git a/core/jni/android_backup_FileBackupHelper.cpp b/core/jni/android_backup_FileBackupHelper.cpp
index a46f37b..418db8a 100644
--- a/core/jni/android_backup_FileBackupHelper.cpp
+++ b/core/jni/android_backup_FileBackupHelper.cpp
@@ -25,49 +25,55 @@
namespace android
{
+// java.io.FileDescriptor
static jfieldID s_descriptorField = 0;
static int
-performBackup_native(JNIEnv* env, jobject clazz, jstring basePath, jobject oldState, int data,
- jobject newState, jobjectArray files)
+performBackup_native(JNIEnv* env, jobject clazz, jobject oldState, int data,
+ jobject newState, jobjectArray files, jobjectArray keys)
{
int err;
// all parameters have already been checked against null
- LOGD("oldState=%p newState=%p data=%p\n", oldState, newState, data);
int oldStateFD = oldState != NULL ? env->GetIntField(oldState, s_descriptorField) : -1;
int newStateFD = env->GetIntField(newState, s_descriptorField);
BackupDataWriter* dataStream = (BackupDataWriter*)data;
- char const* basePathUTF = env->GetStringUTFChars(basePath, NULL);
- LOGD("basePathUTF=\"%s\"\n", basePathUTF);
const int fileCount = env->GetArrayLength(files);
char const** filesUTF = (char const**)malloc(sizeof(char*)*fileCount);
for (int i=0; i<fileCount; i++) {
filesUTF[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(files, i), NULL);
}
- err = back_up_files(oldStateFD, dataStream, newStateFD, basePathUTF, filesUTF, fileCount);
+ const int keyCount = env->GetArrayLength(keys);
+ char const** keysUTF = (char const**)malloc(sizeof(char*)*keyCount);
+ for (int i=0; i<keyCount; i++) {
+ keysUTF[i] = env->GetStringUTFChars((jstring)env->GetObjectArrayElement(keys, i), NULL);
+ }
+
+ err = back_up_files(oldStateFD, dataStream, newStateFD, filesUTF, keysUTF, fileCount);
for (int i=0; i<fileCount; i++) {
env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(files, i), filesUTF[i]);
}
free(filesUTF);
- env->ReleaseStringUTFChars(basePath, basePathUTF);
+
+ for (int i=0; i<keyCount; i++) {
+ env->ReleaseStringUTFChars((jstring)env->GetObjectArrayElement(keys, i), keysUTF[i]);
+ }
+ free(keysUTF);
return err;
}
static const JNINativeMethod g_methods[] = {
{ "performBackup_native",
- "(Ljava/lang/String;Ljava/io/FileDescriptor;ILjava/io/FileDescriptor;[Ljava/lang/String;)I",
- (void*)performBackup_native },
+ "(Ljava/io/FileDescriptor;ILjava/io/FileDescriptor;[Ljava/lang/String;[Ljava/lang/String;)I",
+ (void*)performBackup_native },
};
int register_android_backup_FileBackupHelper(JNIEnv* env)
{
- LOGD("register_android_backup_FileBackupHelper");
-
jclass clazz;
clazz = env->FindClass("java/io/FileDescriptor");
diff --git a/core/jni/android_bluetooth_common.cpp b/core/jni/android_bluetooth_common.cpp
index ee672f7..8361212 100644
--- a/core/jni/android_bluetooth_common.cpp
+++ b/core/jni/android_bluetooth_common.cpp
@@ -36,6 +36,38 @@
namespace android {
#ifdef HAVE_BLUETOOTH
+
+static Properties remote_device_properties[] = {
+ {"Address", DBUS_TYPE_STRING},
+ {"Name", DBUS_TYPE_STRING},
+ {"Icon", DBUS_TYPE_STRING},
+ {"Class", DBUS_TYPE_UINT32},
+ {"UUIDs", DBUS_TYPE_ARRAY},
+ {"Paired", DBUS_TYPE_BOOLEAN},
+ {"Connected", DBUS_TYPE_BOOLEAN},
+ {"Trusted", DBUS_TYPE_BOOLEAN},
+ {"Alias", DBUS_TYPE_STRING},
+ {"Nodes", DBUS_TYPE_ARRAY},
+ {"Adapter", DBUS_TYPE_OBJECT_PATH},
+ {"LegacyPairing", DBUS_TYPE_BOOLEAN},
+ {"RSSI", DBUS_TYPE_INT16},
+ {"TX", DBUS_TYPE_UINT32}
+};
+
+static Properties adapter_properties[] = {
+ {"Address", DBUS_TYPE_STRING},
+ {"Name", DBUS_TYPE_STRING},
+ {"Class", DBUS_TYPE_UINT32},
+ {"Powered", DBUS_TYPE_BOOLEAN},
+ {"Discoverable", DBUS_TYPE_BOOLEAN},
+ {"DiscoverableTimeout", DBUS_TYPE_UINT32},
+ {"Pairable", DBUS_TYPE_BOOLEAN},
+ {"PairableTimeout", DBUS_TYPE_UINT32},
+ {"Discovering", DBUS_TYPE_BOOLEAN},
+ {"Devices", DBUS_TYPE_ARRAY},
+};
+
+
jfieldID get_field(JNIEnv *env, jclass clazz, const char *member,
const char *mtype) {
jfieldID field = env->GetFieldID(clazz, member, mtype);
@@ -332,6 +364,44 @@ jboolean dbus_returns_boolean(JNIEnv *env, DBusMessage *reply) {
return ret;
}
+static void set_object_array_element(JNIEnv *env, jobjectArray strArray,
+ const char *value, int index) {
+ jstring obj;
+ obj = env->NewStringUTF(value);
+ env->SetObjectArrayElement(strArray, index, obj);
+ env->DeleteLocalRef(obj);
+}
+
+jobjectArray dbus_returns_array_of_object_path(JNIEnv *env,
+ DBusMessage *reply) {
+
+ DBusError err;
+ char **list;
+ int i, len;
+ jobjectArray strArray = NULL;
+
+ dbus_error_init(&err);
+ if (dbus_message_get_args (reply,
+ &err,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
+ &list, &len,
+ DBUS_TYPE_INVALID)) {
+ jclass stringClass;
+ jstring classNameStr;
+
+ stringClass = env->FindClass("java/lang/String");
+ strArray = env->NewObjectArray(len, stringClass, NULL);
+
+ for (i = 0; i < len; i++)
+ set_object_array_element(env, strArray, list[i], i);
+ } else {
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
+ }
+
+ dbus_message_unref(reply);
+ return strArray;
+}
+
jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply) {
DBusError err;
@@ -353,11 +423,8 @@ jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply) {
stringClass = env->FindClass("java/lang/String");
strArray = env->NewObjectArray(len, stringClass, NULL);
- for (i = 0; i < len; i++) {
- //LOGV("%s: array[%d] = [%s]", __FUNCTION__, i, list[i]);
- env->SetObjectArrayElement(strArray, i,
- env->NewStringUTF(list[i]));
- }
+ for (i = 0; i < len; i++)
+ set_object_array_element(env, strArray, list[i], i);
} else {
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
}
@@ -390,6 +457,292 @@ jbyteArray dbus_returns_array_of_bytes(JNIEnv *env, DBusMessage *reply) {
return byteArray;
}
+void append_variant(DBusMessageIter *iter, int type, void *val)
+{
+ DBusMessageIter value_iter;
+ char var_type[2] = { type, '\0'};
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, var_type, &value_iter);
+ dbus_message_iter_append_basic(&value_iter, type, val);
+ dbus_message_iter_close_container(iter, &value_iter);
+}
+
+
+//TODO(): Remove code duplication between parse_properties and
+//parse_property_change
+jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
+ const int max_num_properties) {
+ DBusMessageIter dict_entry, dict, prop_val, device_val, array_val_iter;
+ jobjectArray strArray = NULL;
+ char * property;
+ char values[max_num_properties][256];
+ char **uuid_array = NULL;
+ char **device_path = NULL;
+ char **array_elements = NULL;
+ char *string_val;
+ uint32_t int_val, bool_val;
+ int i, j, k, type, array_type, num_array_elements = 0;
+ int ret, num_properties = 0, num_uuids = 0, num_devices = 0;
+
+
+ jclass stringClass = env->FindClass("java/lang/String");
+ DBusError err;
+ dbus_error_init(&err);
+
+ for (i = 0; i < max_num_properties; i++)
+ memset(values[i], '\0', 128 * sizeof(char));
+
+ if(dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ goto failure;
+ dbus_message_iter_recurse(iter, &dict);
+ do {
+ if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY)
+ goto failure;
+ dbus_message_iter_recurse(&dict, &dict_entry);
+ if (dbus_message_iter_get_arg_type(&dict_entry) != DBUS_TYPE_STRING)
+ goto failure;
+ dbus_message_iter_get_basic(&dict_entry, &property);
+ if (!dbus_message_iter_next(&dict_entry))
+ goto failure;
+ if (dbus_message_iter_get_arg_type(&dict_entry) != DBUS_TYPE_VARIANT)
+ goto failure;
+
+ for (i = 0; i < max_num_properties; i++) {
+ if (!strncmp(properties[i].name, property, strlen(property))) {
+ num_properties ++;
+ break;
+ }
+ }
+ if (i == max_num_properties)
+ goto failure;
+
+ type = properties[i].type;
+ dbus_message_iter_recurse(&dict_entry, &prop_val);
+ if(dbus_message_iter_get_arg_type(&prop_val) != type) {
+ LOGE("Property type mismatch in parse_properties: %d, expected:%d",
+ dbus_message_iter_get_arg_type(&prop_val), type);
+ goto failure;
+ }
+
+ switch(type) {
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ dbus_message_iter_get_basic(&prop_val, &string_val);
+ strcpy(values[i], string_val);
+ break;
+ case DBUS_TYPE_UINT32:
+ case DBUS_TYPE_INT16:
+ dbus_message_iter_get_basic(&prop_val, &int_val);
+ sprintf(values[i], "%d", int_val);
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ dbus_message_iter_get_basic(&prop_val, &bool_val);
+ sprintf(values[i], "%s", bool_val ? "true" : "false");
+ break;
+ case DBUS_TYPE_ARRAY:
+ dbus_message_iter_recurse(&prop_val, &array_val_iter);
+ array_type = dbus_message_iter_get_arg_type(&array_val_iter);
+ num_array_elements = 0;
+ if (array_type == DBUS_TYPE_OBJECT_PATH ||
+ array_type == DBUS_TYPE_STRING){
+ do {
+ num_array_elements++;
+ } while(dbus_message_iter_next(&array_val_iter));
+ dbus_message_iter_recurse(&prop_val, &array_val_iter);
+ // Allocate an array
+ array_elements = (char **)malloc(sizeof(char *) *
+ num_array_elements);
+ if (!array_elements)
+ goto failure;
+
+ j = 0;
+ do {
+ dbus_message_iter_get_basic(&array_val_iter, &array_elements[j]);
+ j++;
+ } while(dbus_message_iter_next(&array_val_iter));
+ if (!strncmp(property, "UUIDs", strlen("UUIDs"))) {
+ num_uuids = num_array_elements;
+ uuid_array = array_elements;
+ } else {
+ num_devices = num_array_elements;
+ device_path = array_elements;
+ }
+ }
+ break;
+ default:
+ goto failure;
+ }
+ } while(dbus_message_iter_next(&dict));
+
+ // Convert it to a array of strings.
+ strArray = env->NewObjectArray((num_properties + num_array_elements) * 2,
+ stringClass, NULL);
+
+ j = 0;
+ for (i = 0; i < max_num_properties; i++) {
+ if (properties[i].type == DBUS_TYPE_ARRAY) {
+ if (!strncmp(properties[i].name, "UUIDs", strlen("UUIDs"))) {
+ num_array_elements = num_uuids;
+ array_elements = uuid_array;
+ } else {
+ num_array_elements = num_devices;
+ array_elements = device_path;
+ }
+
+ for (k = 0; k < num_array_elements; k++) {
+ set_object_array_element(env, strArray, properties[i].name, j++);
+ set_object_array_element(env, strArray, array_elements[k], j++);
+ }
+ } else if (values[i][0] != '\0') {
+ set_object_array_element(env, strArray, properties[i].name, j++);
+ set_object_array_element(env, strArray, values[i], j++);
+ }
+ }
+
+ if (uuid_array)
+ free(uuid_array);
+ if (device_path)
+ free(device_path);
+ return strArray;
+
+failure:
+ if (dbus_error_is_set(&err))
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ if (uuid_array)
+ free(uuid_array);
+ if (device_path)
+ free(device_path);
+ return NULL;
+}
+
+jobjectArray create_prop_array(JNIEnv *env, Properties *properties,
+ int prop_index, void *value, int len ) {
+ jclass stringClass= env->FindClass("java/lang/String");
+ char **prop_val = NULL;
+ char buf[32] = {'\0'};
+ int i, j;
+
+ jobjectArray strArray = env->NewObjectArray(1 + len, stringClass, NULL);
+ j = 0;
+ set_object_array_element(env, strArray, properties[prop_index].name, j++);
+
+ if (properties[prop_index].type == DBUS_TYPE_UINT32) {
+ sprintf(buf, "%d", *(int *) value);
+ set_object_array_element(env, strArray, buf, j++);
+ } else if (properties[prop_index].type == DBUS_TYPE_BOOLEAN) {
+ sprintf(buf, "%s", *(int *) value ? "true" : "false");
+ set_object_array_element(env, strArray, buf, j++);
+ } else if (properties[prop_index].type == DBUS_TYPE_ARRAY) {
+ prop_val = (char **) value;
+ for (i = 0; i < len; i++)
+ set_object_array_element(env, strArray, prop_val[i], j++);
+ } else {
+ set_object_array_element(env, strArray, (const char *) value, j++);
+ }
+ if (prop_val)
+ free (prop_val);
+ return strArray;
+}
+
+jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
+ Properties *properties, int max_num_properties) {
+ DBusMessageIter iter, prop_val, array_val_iter;
+ DBusError err;
+ void *value;
+ char *property;
+ uint32_t array_type;
+ int i, j, type, len, prop_index;
+
+ dbus_error_init(&err);
+ if (!dbus_message_iter_init(msg, &iter))
+ goto failure;
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ goto failure;
+ dbus_message_iter_get_basic(&iter, &property);
+ if (!dbus_message_iter_next(&iter))
+ goto failure;
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+ goto failure;
+ for (i = 0; i < max_num_properties; i++) {
+ if (!strncmp(property, properties[i].name, strlen(properties[i].name)))
+ break;
+ }
+ prop_index = i;
+ if (i == max_num_properties)
+ goto failure;
+
+ dbus_message_iter_recurse(&iter, &prop_val);
+ type = properties[prop_index].type;
+ if (dbus_message_iter_get_arg_type(&prop_val) != type) {
+ LOGE("Property type mismatch in parse_properties: %d, expected:%d",
+ dbus_message_iter_get_arg_type(&prop_val), type);
+ goto failure;
+ }
+
+ switch(type) {
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ dbus_message_iter_get_basic(&prop_val, &value);
+ len = 1;
+ break;
+ case DBUS_TYPE_UINT32:
+ case DBUS_TYPE_INT16:
+ case DBUS_TYPE_BOOLEAN:
+ uint32_t int_val;
+ dbus_message_iter_get_basic(&prop_val, &int_val);
+ value = &int_val;
+ len = 1;
+ break;
+ case DBUS_TYPE_ARRAY:
+ dbus_message_iter_recurse(&prop_val, &array_val_iter);
+ array_type = dbus_message_iter_get_arg_type(&array_val_iter);
+ len = 0;
+ if (array_type == DBUS_TYPE_OBJECT_PATH ||
+ array_type == DBUS_TYPE_STRING){
+ do {
+ len ++;
+ } while(dbus_message_iter_next(&array_val_iter));
+ dbus_message_iter_recurse(&prop_val, &array_val_iter);
+ // Allocate an array of char *
+ char **tmp = (char **)malloc(sizeof(char *) * len);
+ if (!tmp)
+ goto failure;
+ j = 0;
+ do {
+ dbus_message_iter_get_basic(&array_val_iter, &tmp[j]);
+ j ++;
+ } while(dbus_message_iter_next(&array_val_iter));
+ value = (char **) tmp;
+ }
+ break;
+ default:
+ goto failure;
+ }
+ return create_prop_array(env, properties, prop_index, value, len);
+failure:
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+ return NULL;
+}
+
+jobjectArray parse_adapter_property_change(JNIEnv *env, DBusMessage *msg) {
+ return parse_property_change(env, msg, (Properties *) &adapter_properties,
+ sizeof(adapter_properties) / sizeof(Properties));
+}
+
+jobjectArray parse_remote_device_property_change(JNIEnv *env, DBusMessage *msg) {
+ return parse_property_change(env, msg, (Properties *) &remote_device_properties,
+ sizeof(remote_device_properties) / sizeof(Properties));
+}
+
+jobjectArray parse_adapter_properties(JNIEnv *env, DBusMessageIter *iter) {
+ return parse_properties(env, iter, (Properties *) &adapter_properties,
+ sizeof(adapter_properties) / sizeof(Properties));
+}
+
+jobjectArray parse_remote_device_properties(JNIEnv *env, DBusMessageIter *iter) {
+ return parse_properties(env, iter, (Properties *) &remote_device_properties,
+ sizeof(remote_device_properties) / sizeof(Properties));
+}
+
int get_bdaddr(const char *str, bdaddr_t *ba) {
char *d = ((char *)ba) + 5, *endp;
int i;
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index e5b8813..ef9b66b 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -68,6 +68,7 @@ jfieldID get_field(JNIEnv *env,
struct event_loop_native_data_t {
DBusConnection *conn;
+ const char *adapter;
/* protects the thread */
pthread_mutex_t thread_mutex;
@@ -89,6 +90,12 @@ struct event_loop_native_data_t {
jobject me;
};
+struct _Properties {
+ char name[32];
+ int type;
+};
+typedef struct _Properties Properties;
+
dbus_bool_t dbus_func_args_async(JNIEnv *env,
DBusConnection *conn,
int timeout_ms,
@@ -142,8 +149,18 @@ jint dbus_returns_uint32(JNIEnv *env, DBusMessage *reply);
jstring dbus_returns_string(JNIEnv *env, DBusMessage *reply);
jboolean dbus_returns_boolean(JNIEnv *env, DBusMessage *reply);
jobjectArray dbus_returns_array_of_strings(JNIEnv *env, DBusMessage *reply);
+jobjectArray dbus_returns_array_of_object_path(JNIEnv *env, DBusMessage *reply);
jbyteArray dbus_returns_array_of_bytes(JNIEnv *env, DBusMessage *reply);
+jobjectArray parse_properties(JNIEnv *env, DBusMessageIter *iter, Properties *properties,
+ const int max_num_properties);
+jobjectArray parse_property_change(JNIEnv *env, DBusMessage *msg,
+ Properties *properties, int max_num_properties);
+jobjectArray parse_adapter_properties(JNIEnv *env, DBusMessageIter *iter);
+jobjectArray parse_remote_device_properties(JNIEnv *env, DBusMessageIter *iter);
+jobjectArray parse_remote_device_property_change(JNIEnv *env, DBusMessage *msg);
+jobjectArray parse_adapter_property_change(JNIEnv *env, DBusMessage *msg);
+void append_variant(DBusMessageIter *iter, int type, void *val);
int get_bdaddr(const char *str, bdaddr_t *ba);
void get_bdaddr_as_string(const bdaddr_t *ba, char *str);
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 31086b8..217e649 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -115,15 +115,13 @@ static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobj
// make sure camera hardware is alive
if (camera->getStatus() != NO_ERROR) {
- jniThrowException(env, "java/io/IOException", "Camera initialization failed");
+ jniThrowException(env, "java/lang/RuntimeException", "Camera initialization failed");
return;
}
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
- LOGE("Can't find android/hardware/Camera");
- // XXX no idea what to throw here, can this even happen?
- jniThrowException(env, "java/lang/Exception", NULL);
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/hardware/Camera");
return;
}
@@ -241,7 +239,7 @@ static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
if (camera == 0) return;
if (camera->startPreview() != NO_ERROR) {
- jniThrowException(env, "java/io/IOException", "startPreview failed");
+ jniThrowException(env, "java/lang/RuntimeException", "startPreview failed");
return;
}
}
@@ -305,7 +303,7 @@ static void android_hardware_Camera_autoFocus(JNIEnv *env, jobject thiz)
c->setAutoFocusCallback(autofocus_callback_impl, context);
if (c->autoFocus() != NO_ERROR) {
- jniThrowException(env, "java/io/IOException", "autoFocus failed");
+ jniThrowException(env, "java/lang/RuntimeException", "autoFocus failed");
}
}
@@ -398,7 +396,7 @@ static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz)
camera->setRawCallback(raw_callback, context);
camera->setJpegCallback(jpeg_callback, context);
if (camera->takePicture() != NO_ERROR) {
- jniThrowException(env, "java/io/IOException", "takePicture failed");
+ jniThrowException(env, "java/lang/RuntimeException", "takePicture failed");
return;
}
@@ -418,7 +416,7 @@ static void android_hardware_Camera_setParameters(JNIEnv *env, jobject thiz, jst
env->ReleaseStringCritical(params, str);
}
if (camera->setParameters(params8) != NO_ERROR) {
- jniThrowException(env, "java/lang/IllegalArgumentException", "setParameters failed");
+ jniThrowException(env, "java/lang/RuntimeException", "setParameters failed");
return;
}
}
diff --git a/core/jni/android_location_GpsLocationProvider.cpp b/core/jni/android_location_GpsLocationProvider.cpp
index 0858741..5c4fb22 100644
--- a/core/jni/android_location_GpsLocationProvider.cpp
+++ b/core/jni/android_location_GpsLocationProvider.cpp
@@ -270,6 +270,12 @@ static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobjec
sGpsInterface->inject_time(time, timeReference, uncertainty);
}
+static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj,
+ jdouble latitude, jdouble longitude, jfloat accuracy)
+{
+ sGpsInterface->inject_location(latitude, longitude, accuracy);
+}
+
static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj)
{
if (!sGpsXtraInterface) {
@@ -353,6 +359,7 @@ static JNINativeMethod sMethods[] = {
{"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event},
{"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status},
{"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time},
+ {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location},
{"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra},
{"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data},
{"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open},
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 9f93e2f..75ae4d9 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -307,14 +307,15 @@ static jboolean android_net_wifi_stopPacketFiltering(JNIEnv* env, jobject clazz)
return result;
}
-static jint android_net_wifi_getRssiCommand(JNIEnv* env, jobject clazz)
+static jint android_net_wifi_getRssiHelper(const char *cmd)
{
char reply[256];
int rssi = -200;
- if (doCommand("DRIVER RSSI", reply, sizeof(reply)) != 0) {
+ if (doCommand(cmd, reply, sizeof(reply)) != 0) {
return (jint)-1;
}
+
// reply comes back in the form "<SSID> rssi XX" where XX is the
// number we're interested in. if we're associating, it returns "OK".
// beware - <SSID> can contain spaces.
@@ -328,6 +329,16 @@ static jint android_net_wifi_getRssiCommand(JNIEnv* env, jobject clazz)
return (jint)rssi;
}
+static jint android_net_wifi_getRssiCommand(JNIEnv* env, jobject clazz)
+{
+ return android_net_wifi_getRssiHelper("DRIVER RSSI");
+}
+
+static jint android_net_wifi_getRssiApproxCommand(JNIEnv* env, jobject clazz)
+{
+ return android_net_wifi_getRssiHelper("DRIVER RSSI-APPROX");
+}
+
static jint android_net_wifi_getLinkSpeedCommand(JNIEnv* env, jobject clazz)
{
char reply[256];
@@ -523,6 +534,8 @@ static JNINativeMethod gWifiMethods[] = {
{ "setBluetoothCoexistenceScanModeCommand", "(Z)Z",
(void*) android_net_wifi_setBluetoothCoexistenceScanModeCommand },
{ "getRssiCommand", "()I", (void*) android_net_wifi_getRssiCommand },
+ { "getRssiApproxCommand", "()I",
+ (void*) android_net_wifi_getRssiApproxCommand},
{ "getLinkSpeedCommand", "()I", (void*) android_net_wifi_getLinkSpeedCommand },
{ "getMacAddressCommand", "()Ljava/lang/String;", (void*) android_net_wifi_getMacAddressCommand },
{ "saveConfigCommand", "()Z", (void*) android_net_wifi_saveConfigCommand },
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index fe94642..153d16e 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -37,12 +37,7 @@
namespace android {
#ifdef HAVE_BLUETOOTH
-static jmethodID method_onHeadsetCreated;
-static jmethodID method_onHeadsetRemoved;
-static jmethodID method_onSinkConnected;
-static jmethodID method_onSinkDisconnected;
-static jmethodID method_onSinkPlaying;
-static jmethodID method_onSinkStopped;
+static jmethodID method_onSinkPropertyChanged;
typedef struct {
JavaVM *vm;
@@ -53,11 +48,11 @@ typedef struct {
static native_data_t *nat = NULL; // global native data
-#endif
-
-#ifdef HAVE_BLUETOOTH
-static void onConnectSinkResult(DBusMessage *msg, void *user, void *nat);
-static void onDisconnectSinkResult(DBusMessage *msg, void *user, void *nat);
+static Properties sink_properties[] = {
+ {"State", DBUS_TYPE_STRING},
+ {"Connected", DBUS_TYPE_BOOLEAN},
+ {"Playing", DBUS_TYPE_BOOLEAN},
+ };
#endif
/* Returns true on success (even if adapter is present but disabled).
@@ -99,91 +94,58 @@ static void cleanupNative(JNIEnv* env, jobject object) {
}
#endif
}
-static jobjectArray listHeadsetsNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, "/org/bluez/audio",
- "org.bluez.audio.Manager", "ListHeadsets",
- DBUS_TYPE_INVALID);
- return reply ? dbus_returns_array_of_strings(env, reply) : NULL;
- }
-#endif
- return NULL;
-}
-static jstring createHeadsetNative(JNIEnv *env, jobject object,
- jstring address) {
+static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
+ jstring path) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- LOGV("... address = %s\n", c_address);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, "/org/bluez/audio",
- "org.bluez.audio.Manager", "CreateHeadset",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return reply ? dbus_returns_string(env, reply) : NULL;
- }
-#endif
- return NULL;
-}
+ DBusMessage *msg, *reply;
+ DBusError err;
+ dbus_error_init(&err);
-static jstring removeHeadsetNative(JNIEnv *env, jobject object, jstring path) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, "/org/bluez/audio",
- "org.bluez.audio.Manager", "RemoveHeadset",
- DBUS_TYPE_STRING, &c_path,
- DBUS_TYPE_INVALID);
+ reply = dbus_func_args_timeout(env,
+ nat->conn, -1, c_path,
+ "org.bluez.AudioSink", "GetProperties",
+ DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(path, c_path);
- return reply ? dbus_returns_string(env, reply) : NULL;
+ if (!reply && dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
+ return NULL;
+ } else if (!reply) {
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+ return NULL;
+ }
+ DBusMessageIter iter;
+ if (dbus_message_iter_init(reply, &iter))
+ return parse_properties(env, &iter, (Properties *)&sink_properties,
+ sizeof(sink_properties) / sizeof(Properties));
}
#endif
return NULL;
}
-static jstring getAddressNative(JNIEnv *env, jobject object, jstring path) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, c_path,
- "org.bluez.audio.Device", "GetAddress",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- return reply ? dbus_returns_string(env, reply) : NULL;
- }
-#endif
- return NULL;
-}
static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
- size_t path_sz = env->GetStringUTFLength(path) + 1;
- char *c_path_copy = (char *)malloc(path_sz); // callback data
- strncpy(c_path_copy, c_path, path_sz);
-
- bool ret =
- dbus_func_args_async(env, nat->conn, -1,
- onConnectSinkResult, (void *)c_path_copy, nat,
- c_path,
- "org.bluez.audio.Sink", "Connect",
- DBUS_TYPE_INVALID);
+ DBusError err;
+ dbus_error_init(&err);
+ DBusMessage *reply =
+ dbus_func_args_timeout(env, nat->conn, -1, c_path,
+ "org.bluez.AudioSink", "Connect",
+ DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(path, c_path);
- if (!ret) {
- free(c_path_copy);
+
+ if (!reply && dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
+ return JNI_FALSE;
+ } else if (!reply) {
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
return JNI_FALSE;
}
return JNI_TRUE;
@@ -198,19 +160,20 @@ static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
LOGV(__FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
- size_t path_sz = env->GetStringUTFLength(path) + 1;
- char *c_path_copy = (char *)malloc(path_sz); // callback data
- strncpy(c_path_copy, c_path, path_sz);
-
- bool ret =
- dbus_func_args_async(env, nat->conn, -1,
- onDisconnectSinkResult, (void *)c_path_copy, nat,
- c_path,
- "org.bluez.audio.Sink", "Disconnect",
- DBUS_TYPE_INVALID);
+ DBusError err;
+ dbus_error_init(&err);
+
+ DBusMessage *reply =
+ dbus_func_args_timeout(env, nat->conn, -1, c_path,
+ "org.bluez.AudioSink", "Disconnect",
+ DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(path, c_path);
- if (!ret) {
- free(c_path_copy);
+
+ if (!reply && dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
+ return JNI_FALSE;
+ } else if (!reply) {
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
return JNI_FALSE;
}
return JNI_TRUE;
@@ -219,93 +182,7 @@ static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
return JNI_FALSE;
}
-static jboolean isSinkConnectedNative(JNIEnv *env, jobject object, jstring path) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- if (nat) {
- const char *c_path = env->GetStringUTFChars(path, NULL);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, c_path,
- "org.bluez.audio.Sink", "IsConnected",
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(path, c_path);
- return reply ? dbus_returns_boolean(env, reply) : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
#ifdef HAVE_BLUETOOTH
-static void onConnectSinkResult(DBusMessage *msg, void *user, void *natData) {
- LOGV(__FUNCTION__);
-
- char *c_path = (char *)user;
- DBusError err;
- JNIEnv *env;
-
- if (nat->vm->GetEnv((void**)&env, nat->envVer) < 0) {
- LOGE("%s: error finding Env for our VM\n", __FUNCTION__);
- return;
- }
-
- dbus_error_init(&err);
-
- LOGV("... path = %s", c_path);
- if (dbus_set_error_from_message(&err, msg)) {
- /* if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) */
- LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- dbus_error_free(&err);
- env->CallVoidMethod(nat->me,
- method_onSinkDisconnected,
- env->NewStringUTF(c_path));
- if (env->ExceptionCheck()) {
- LOGE("VM Exception occurred in native function %s (%s:%d)",
- __FUNCTION__, __FILE__, __LINE__);
- }
- } // else Java callback is triggered by signal in a2dp_event_filter
-
- free(c_path);
-}
-
-static void onDisconnectSinkResult(DBusMessage *msg, void *user, void *natData) {
- LOGV(__FUNCTION__);
-
- char *c_path = (char *)user;
- DBusError err;
- JNIEnv *env;
-
- if (nat->vm->GetEnv((void**)&env, nat->envVer) < 0) {
- LOGE("%s: error finding Env for our VM\n", __FUNCTION__);
- return;
- }
-
- dbus_error_init(&err);
-
- LOGV("... path = %s", c_path);
- if (dbus_set_error_from_message(&err, msg)) {
- /* if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) */
- LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- if (strcmp(err.name, "org.bluez.Error.NotConnected") == 0) {
- // we were already disconnected, so report disconnect
- env->CallVoidMethod(nat->me,
- method_onSinkDisconnected,
- env->NewStringUTF(c_path));
- } else {
- // Assume it is still connected
- env->CallVoidMethod(nat->me,
- method_onSinkConnected,
- env->NewStringUTF(c_path));
- }
- dbus_error_free(&err);
- if (env->ExceptionCheck()) {
- LOGE("VM Exception occurred in native function %s (%s:%d)",
- __FUNCTION__, __FILE__, __LINE__);
- }
- } // else Java callback is triggered by signal in a2dp_event_filter
-
- free(c_path);
-}
-
DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
DBusError err;
@@ -323,71 +200,23 @@ DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- if (dbus_message_is_signal(msg,
- "org.bluez.audio.Manager",
- "HeadsetCreated")) {
- char *c_path;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_path,
- DBUS_TYPE_INVALID)) {
- LOGV("... path = %s", c_path);
- env->CallVoidMethod(nat->me,
- method_onHeadsetCreated,
- env->NewStringUTF(c_path));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- result = DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.audio.Manager",
- "HeadsetRemoved")) {
- char *c_path;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_path,
- DBUS_TYPE_INVALID)) {
- LOGV("... path = %s", c_path);
- env->CallVoidMethod(nat->me,
- method_onHeadsetRemoved,
- env->NewStringUTF(c_path));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- result = DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.audio.Sink",
- "Connected")) {
+ if (dbus_message_is_signal(msg, "org.bluez.AudioSink",
+ "PropertyChanged")) {
+ jobjectArray str_array =
+ parse_property_change(env, msg, (Properties *)&sink_properties,
+ sizeof(sink_properties) / sizeof(Properties));
const char *c_path = dbus_message_get_path(msg);
- LOGV("... path = %s", c_path);
env->CallVoidMethod(nat->me,
- method_onSinkConnected,
- env->NewStringUTF(c_path));
- result = DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.audio.Sink",
- "Disconnected")) {
- const char *c_path = dbus_message_get_path(msg);
- LOGV("... path = %s", c_path);
- env->CallVoidMethod(nat->me,
- method_onSinkDisconnected,
- env->NewStringUTF(c_path));
- result = DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.audio.Sink",
- "Playing")) {
- const char *c_path = dbus_message_get_path(msg);
- LOGV("... path = %s", c_path);
- env->CallVoidMethod(nat->me,
- method_onSinkPlaying,
- env->NewStringUTF(c_path));
- result = DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.audio.Sink",
- "Stopped")) {
- const char *c_path = dbus_message_get_path(msg);
- LOGV("... path = %s", c_path);
- env->CallVoidMethod(nat->me,
- method_onSinkStopped,
- env->NewStringUTF(c_path));
+ method_onSinkPropertyChanged,
+ env->NewStringUTF(c_path),
+ str_array);
+ for (int i = 0; i < env->GetArrayLength(str_array); i++) {
+ env->DeleteLocalRef(env->GetObjectArrayElement(str_array, i));
+ }
+ env->DeleteLocalRef(str_array);
result = DBUS_HANDLER_RESULT_HANDLED;
- }
-
- if (result == DBUS_HANDLER_RESULT_NOT_YET_HANDLED) {
+ return result;
+ } else {
LOGV("... ignored");
}
if (env->ExceptionCheck()) {
@@ -406,14 +235,11 @@ static JNINativeMethod sMethods[] = {
{"initNative", "()Z", (void *)initNative},
{"cleanupNative", "()V", (void *)cleanupNative},
- /* Bluez audio 3.36 API */
- {"listHeadsetsNative", "()[Ljava/lang/String;", (void*)listHeadsetsNative},
- {"createHeadsetNative", "(Ljava/lang/String;)Ljava/lang/String;", (void*)createHeadsetNative},
- {"removeHeadsetNative", "(Ljava/lang/String;)Z", (void*)removeHeadsetNative},
- {"getAddressNative", "(Ljava/lang/String;)Ljava/lang/String;", (void*)getAddressNative},
- {"connectSinkNative", "(Ljava/lang/String;)Z", (void*)connectSinkNative},
- {"disconnectSinkNative", "(Ljava/lang/String;)Z", (void*)disconnectSinkNative},
- {"isSinkConnectedNative", "(Ljava/lang/String;)Z", (void*)isSinkConnectedNative},
+ /* Bluez audio 4.40 API */
+ {"connectSinkNative", "(Ljava/lang/String;)Z", (void *)connectSinkNative},
+ {"disconnectSinkNative", "(Ljava/lang/String;)Z", (void *)disconnectSinkNative},
+ {"getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
+ (void *)getSinkPropertiesNative},
};
int register_android_server_BluetoothA2dpService(JNIEnv *env) {
@@ -424,12 +250,8 @@ int register_android_server_BluetoothA2dpService(JNIEnv *env) {
}
#ifdef HAVE_BLUETOOTH
- method_onHeadsetCreated = env->GetMethodID(clazz, "onHeadsetCreated", "(Ljava/lang/String;)V");
- method_onHeadsetRemoved = env->GetMethodID(clazz, "onHeadsetRemoved", "(Ljava/lang/String;)V");
- method_onSinkConnected = env->GetMethodID(clazz, "onSinkConnected", "(Ljava/lang/String;)V");
- method_onSinkDisconnected = env->GetMethodID(clazz, "onSinkDisconnected", "(Ljava/lang/String;)V");
- method_onSinkPlaying = env->GetMethodID(clazz, "onSinkPlaying", "(Ljava/lang/String;)V");
- method_onSinkStopped = env->GetMethodID(clazz, "onSinkStopped", "(Ljava/lang/String;)V");
+ method_onSinkPropertyChanged = env->GetMethodID(clazz, "onSinkPropertyChanged",
+ "(Ljava/lang/String;[Ljava/lang/String;)V");
#endif
return AndroidRuntime::registerNativeMethods(env,
diff --git a/core/jni/android_server_BluetoothDeviceService.cpp b/core/jni/android_server_BluetoothDeviceService.cpp
index b6e9798..16bfc9c 100644
--- a/core/jni/android_server_BluetoothDeviceService.cpp
+++ b/core/jni/android_server_BluetoothDeviceService.cpp
@@ -14,7 +14,8 @@
** limitations under the License.
*/
-#define DBUS_CLASS_NAME BLUEZ_DBUS_BASE_IFC ".Adapter"
+#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
+#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
#define LOG_TAG "BluetoothDeviceService.cpp"
#include "android_bluetooth_common.h"
@@ -60,8 +61,11 @@ typedef struct {
extern event_loop_native_data_t *get_EventLoop_native_data(JNIEnv *,
jobject);
-void onCreateBondingResult(DBusMessage *msg, void *user, void *nat);
-void onGetRemoteServiceChannelResult(DBusMessage *msg, void *user, void *nat);
+extern DBusHandlerResult agent_event_filter(DBusConnection *conn,
+ DBusMessage *msg,
+ void *data);
+void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
+
/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
* Perform quick sanity check, if there are any problems return NULL
@@ -109,36 +113,71 @@ static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
dbus_error_free(&err);
return false;
}
-
- nat->adapter = BLUEZ_ADAPTER_OBJECT_NAME;
#endif /*HAVE_BLUETOOTH*/
return true;
}
-static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
+static const char *get_adapter_path(JNIEnv* env, jobject object) {
+#ifdef HAVE_BLUETOOTH
+ event_loop_native_data_t *event_nat =
+ get_EventLoop_native_data(env, env->GetObjectField(object,
+ field_mEventLoop));
+ if (event_nat == NULL)
+ return NULL;
+ return event_nat->adapter;
+#else
+ return NULL;
+#endif
+}
+
+// This function is called when the adapter is enabled.
+static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
- if (nat) {
- free(nat);
- nat = NULL;
+ event_loop_native_data_t *event_nat =
+ get_EventLoop_native_data(env, env->GetObjectField(object,
+ field_mEventLoop));
+ // Register agent for remote devices.
+ const char *device_agent_path = "/android/bluetooth/remote_device_agent";
+ static const DBusObjectPathVTable agent_vtable = {
+ NULL, agent_event_filter, NULL, NULL, NULL, NULL };
+
+ if (!dbus_connection_register_object_path(nat->conn, device_agent_path,
+ &agent_vtable, event_nat)) {
+ LOGE("%s: Can't register object path %s for remote device agent!",
+ __FUNCTION__, device_agent_path);
+ return JNI_FALSE;
}
-#endif
+#endif /*HAVE_BLUETOOTH*/
+ return JNI_TRUE;
}
-static jstring getNameNative(JNIEnv *env, jobject object){
+static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
- native_data_t *nat = get_native_data(env, object);
+ native_data_t *nat =
+ (native_data_t *)env->GetIntField(object, field_mNativeData);
+ if (nat != NULL) {
+ const char *device_agent_path =
+ "/android/bluetooth/remote_device_agent";
+ dbus_connection_unregister_object_path (nat->conn, device_agent_path);
+ }
+#endif /*HAVE_BLUETOOTH*/
+ return JNI_TRUE;
+}
+
+static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
+ LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+ native_data_t *nat =
+ (native_data_t *)env->GetIntField(object, field_mNativeData);
if (nat) {
- DBusMessage *reply = dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetName",
- DBUS_TYPE_INVALID);
- return reply ? dbus_returns_string(env, reply) : NULL;
+ free(nat);
+ nat = NULL;
}
#endif
- return NULL;
}
static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
@@ -146,7 +185,7 @@ static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
- return (env->NewStringUTF(nat->adapter));
+ return (env->NewStringUTF(get_adapter_path(env, object)));
}
#endif
return NULL;
@@ -170,28 +209,23 @@ static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
dbus_error_init(&err);
/* Compose the command */
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, nat->adapter,
- DBUS_CLASS_NAME, "DiscoverDevices");
+ msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "StartDiscovery");
if (msg == NULL) {
- LOGE("%s: Could not allocate D-Bus message object!", __FUNCTION__);
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+ }
goto done;
}
/* Send the command. */
reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
if (dbus_error_is_set(&err)) {
- /* We treat the in-progress error code as success. */
- if(strcmp(err.message, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") == 0) {
- LOGW("%s: D-Bus error: %s, treating as startDiscoveryNative success\n",
- __FUNCTION__, err.message);
- ret = JNI_TRUE;
- goto done;
- } else {
- LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- ret = JNI_FALSE;
- goto done;
- }
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+ ret = JNI_FALSE;
+ goto done;
}
ret = JNI_TRUE;
@@ -204,7 +238,7 @@ done:
#endif
}
-static void cancelDiscoveryNative(JNIEnv *env, jobject object) {
+static void stopDiscoveryNative(JNIEnv *env, jobject object) {
LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
@@ -222,18 +256,20 @@ static void cancelDiscoveryNative(JNIEnv *env, jobject object) {
}
/* Compose the command */
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, nat->adapter,
- DBUS_CLASS_NAME, "CancelDiscovery");
-
+ msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "StopDiscovery");
if (msg == NULL) {
- LOGE("%s: Could not allocate D-Bus message object!", __FUNCTION__);
+ if (dbus_error_is_set(&err))
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
goto done;
}
/* Send the command. */
reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
if (dbus_error_is_set(&err)) {
- if(strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized") == 0) {
+ if(strncmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized",
+ strlen(BLUEZ_DBUS_BASE_IFC ".Error.NotAuthorized")) == 0) {
// hcid sends this if there is no active discovery to cancel
LOGV("%s: There was no active discovery to cancel", __FUNCTION__);
dbus_error_free(&err);
@@ -248,232 +284,8 @@ done:
#endif
}
-static jboolean startPeriodicDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- DBusMessage *msg = NULL;
- DBusMessage *reply = NULL;
- DBusError err;
- jboolean ret = JNI_FALSE;
-
- native_data_t *nat = get_native_data(env, object);
- if (nat == NULL) {
- goto done;
- }
-
- dbus_error_init(&err);
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, nat->adapter,
- DBUS_CLASS_NAME, "StartPeriodicDiscovery");
- if (msg == NULL) {
- LOGE("%s: Could not allocate DBUS message object\n", __FUNCTION__);
- goto done;
- }
-
- /* Send the command. */
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
- if (dbus_error_is_set(&err)) {
- /* We treat the in-progress error code as success. */
- if(strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") == 0) {
- LOGW("%s: D-Bus error: %s (%s), treating as "
- "startPeriodicDiscoveryNative success\n",
- __FUNCTION__, err.name, err.message);
- } else {
- LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- ret = JNI_FALSE;
- goto done;
- }
- }
-
- ret = JNI_TRUE;
-done:
- if (reply) dbus_message_unref(reply);
- if (msg) dbus_message_unref(msg);
- return ret;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean stopPeriodicDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
-#ifdef HAVE_BLUETOOTH
- DBusMessage *msg = NULL;
- DBusMessage *reply = NULL;
- DBusError err;
- const char *name;
- jboolean ret = JNI_FALSE;
-
- native_data_t *nat = get_native_data(env, object);
- if (nat == NULL) {
- goto done;
- }
-
- dbus_error_init(&err);
- msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC, nat->adapter,
- DBUS_CLASS_NAME, "StopPeriodicDiscovery");
- if (msg == NULL) {
- LOGE("%s: Could not allocate DBUS message object\n", __FUNCTION__);
- goto done;
- }
-
- /* Send the command. */
- reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
- if (dbus_error_is_set(&err)) {
- /* We treat the in-progress error code as success. */
- if(strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress") == 0) {
- LOGW("%s: D-Bus error: %s (%s), treating as "
- "stopPeriodicDiscoveryNative success\n",
- __FUNCTION__, err.name, err.message);
- } else {
- LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
- ret = JNI_FALSE;
- goto done;
- }
- }
-
- ret = JNI_TRUE;
-done:
- if (reply) dbus_message_unref(reply);
- if (msg) dbus_message_unref(msg);
- return ret;
-#else
- return JNI_FALSE;
-#endif
-}
-
-static jboolean isPeriodicDiscoveryNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "IsPeriodicDiscovery",
- DBUS_TYPE_INVALID);
- return reply ? dbus_returns_boolean(env, reply) : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean setDiscoverableTimeoutNative(JNIEnv *env, jobject object, jint timeout_s) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
-
- if (timeout_s < 0) {
- return JNI_FALSE;
- }
-
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "SetDiscoverableTimeout",
- DBUS_TYPE_UINT32, &timeout_s,
- DBUS_TYPE_INVALID);
- if (reply != NULL) {
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
- }
-#endif
- return JNI_FALSE;
-}
-
-static jint getDiscoverableTimeoutNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetDiscoverableTimeout",
- DBUS_TYPE_INVALID);
- return reply ? dbus_returns_uint32(env, reply) : -1;
- }
-#endif
- return -1;
-}
-
-static jboolean isConnectedNative(JNIEnv *env, jobject object, jstring address) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "IsConnected",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return reply ? dbus_returns_boolean(env, reply) : JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static void disconnectRemoteDeviceNative(JNIEnv *env, jobject object, jstring address) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- // Set a timeout of 5 seconds. Specifying the default timeout is
- // not long enough, as a remote-device disconnect results in
- // signal RemoteDisconnectRequested being sent, followed by a
- // delay of 2 seconds, after which the actual disconnect takes
- // place.
- DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, 60000, nat->adapter,
- DBUS_CLASS_NAME, "DisconnectRemoteDevice",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- if (reply) dbus_message_unref(reply);
- }
-#endif
-}
-
-static jstring getModeNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetMode",
- DBUS_TYPE_INVALID);
- return reply ? dbus_returns_string(env, reply) : NULL;
- }
-#endif
- return NULL;
-}
-
-static jboolean setModeNative(JNIEnv *env, jobject object, jstring mode) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_mode = env->GetStringUTFChars(mode, NULL);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "SetMode",
- DBUS_TYPE_STRING, &c_mode,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(mode, c_mode);
- if (reply) {
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
- return JNI_FALSE;
- }
-#endif
- return JNI_FALSE;
-}
-
-static jboolean createBondingNative(JNIEnv *env, jobject object,
- jstring address, jint timeout_ms) {
+static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
+ jstring address, jint timeout_ms) {
LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -485,14 +297,20 @@ static jboolean createBondingNative(JNIEnv *env, jobject object,
const char *c_address = env->GetStringUTFChars(address, NULL);
LOGV("... address = %s", c_address);
char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
+ const char *capabilities = "DisplayYesNo";
+ const char *agent_path = "/android/bluetooth/remote_device_agent";
+
strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
bool ret = dbus_func_args_async(env, nat->conn, (int)timeout_ms,
- onCreateBondingResult, // callback
+ onCreatePairedDeviceResult, // callback
context_address,
eventLoopNat,
- nat->adapter,
- DBUS_CLASS_NAME, "CreateBonding",
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE,
+ "CreatePairedDevice",
DBUS_TYPE_STRING, &c_address,
+ DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_STRING, &capabilities,
DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(address, c_address);
return ret ? JNI_TRUE : JNI_FALSE;
@@ -502,479 +320,324 @@ static jboolean createBondingNative(JNIEnv *env, jobject object,
return JNI_FALSE;
}
-static jboolean cancelBondingProcessNative(JNIEnv *env, jobject object,
- jstring address) {
+static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
+ jstring path,
+ jstring pattern, jint attr_id) {
+#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
+ native_data_t *nat = get_native_data(env, object);
+ jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+ struct event_loop_native_data_t *eventLoopNat =
+ get_EventLoop_native_data(env, eventLoop);
+ if (nat && eventLoopNat) {
+ const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
+ const char *c_path = env->GetStringUTFChars(path, NULL);
+ LOGV("... pattern = %s", c_pattern);
+ LOGV("... attr_id = %#X", attr_id);
+ DBusMessage *reply =
+ dbus_func_args(env, nat->conn, c_path,
+ DBUS_DEVICE_IFACE, "GetServiceAttributeValue",
+ DBUS_TYPE_STRING, &c_pattern,
+ DBUS_TYPE_UINT16, &attr_id,
+ DBUS_TYPE_INVALID);
+ env->ReleaseStringUTFChars(pattern, c_pattern);
+ env->ReleaseStringUTFChars(path, c_path);
+ return reply ? dbus_returns_int32(env, reply) : -1;
+ }
+#endif
+ return -1;
+}
+
+static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
+ jstring address) {
+ LOGV(__FUNCTION__);
+ jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
const char *c_address = env->GetStringUTFChars(address, NULL);
+ DBusError err;
+ dbus_error_init(&err);
LOGV("... address = %s", c_address);
DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, -1, nat->adapter,
- DBUS_CLASS_NAME, "CancelBondingProcess",
+ dbus_func_args_timeout(env, nat->conn, -1,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "CancelDeviceCreation",
DBUS_TYPE_STRING, &c_address,
DBUS_TYPE_INVALID);
env->ReleaseStringUTFChars(address, c_address);
- if (reply) {
- dbus_message_unref(reply);
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ } else
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+ return JNI_FALSE;
+ } else {
+ result = JNI_TRUE;
}
- return JNI_TRUE;
+ dbus_message_unref(reply);
}
#endif
return JNI_FALSE;
}
-static jboolean removeBondingNative(JNIEnv *env, jobject object, jstring address) {
+static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
LOGV(__FUNCTION__);
jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- LOGV("... address = %s", c_address);
+ const char *c_object_path = env->GetStringUTFChars(object_path, NULL);
DBusError err;
dbus_error_init(&err);
DBusMessage *reply =
- dbus_func_args_error(env, nat->conn, &err, nat->adapter,
- DBUS_CLASS_NAME, "RemoveBonding",
- DBUS_TYPE_STRING, &c_address,
+ dbus_func_args_error(env, nat->conn, &err,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "RemoveDevice",
+ DBUS_TYPE_OBJECT_PATH, &c_object_path,
DBUS_TYPE_INVALID);
- if (dbus_error_is_set(&err)) {
- if (dbus_error_has_name(&err,
- BLUEZ_DBUS_BASE_IFC ".Error.DoesNotExist")) {
- LOGW("%s: Warning: %s (%s)", __FUNCTION__, err.message,
- c_address);
- result = JNI_TRUE;
- } else {
- LOGE("%s: D-Bus error %s (%s)", __FUNCTION__, err.name,
- err.message);
- }
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ } else
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+ result = JNI_FALSE;
} else {
result = JNI_TRUE;
}
-
- env->ReleaseStringUTFChars(address, c_address);
- dbus_error_free(&err);
+ env->ReleaseStringUTFChars(object_path, c_object_path);
if (reply) dbus_message_unref(reply);
}
#endif
return result;
}
-static jobjectArray listBondingsNative(JNIEnv *env, jobject object) {
+static jint enableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "ListBondings",
- DBUS_TYPE_INVALID);
- // return String[]
- return reply ? dbus_returns_array_of_strings(env, reply) : NULL;
- }
+ return bt_enable();
#endif
- return NULL;
+ return -1;
}
-static jobjectArray listConnectionsNative(JNIEnv *env, jobject object) {
+static jint disableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "ListConnections",
- DBUS_TYPE_INVALID);
- // return String[]
- return reply ? dbus_returns_array_of_strings(env, reply) : NULL;
- }
+ return bt_disable();
#endif
- return NULL;
+ return -1;
}
-static jobjectArray listRemoteDevicesNative(JNIEnv *env, jobject object) {
+static jint isEnabledNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "ListRemoteDevices",
- DBUS_TYPE_INVALID);
- return reply ? dbus_returns_array_of_strings(env, reply) : NULL;
- }
+ return bt_is_enabled();
#endif
- return NULL;
+ return -1;
}
-static jstring common_Get(JNIEnv *env, jobject object, const char *func) {
- LOGV("%s:%s", __FUNCTION__, func);
+static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
+ jstring pin, int nativeData) {
#ifdef HAVE_BLUETOOTH
+ LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- DBusError err;
- dbus_error_init(&err);
- DBusMessage *reply =
- dbus_func_args_error(env, nat->conn, &err, nat->adapter,
- DBUS_CLASS_NAME, func,
- DBUS_TYPE_INVALID);
- if (reply) {
- return dbus_returns_string(env, reply);
- } else {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return NULL;
+ DBusMessage *msg = (DBusMessage *)nativeData;
+ DBusMessage *reply = dbus_message_new_method_return(msg);
+ if (!reply) {
+ LOGE("%s: Cannot create message reply to return PIN code to "
+ "D-Bus\n", __FUNCTION__);
+ dbus_message_unref(msg);
+ return JNI_FALSE;
}
- }
-#endif
- return NULL;
-}
-
-static jstring getAddressNative(JNIEnv *env, jobject obj) {
- return common_Get(env, obj, "GetAddress");
-}
-
-static jstring getVersionNative(JNIEnv *env, jobject obj) {
- return common_Get(env, obj, "GetVersion");
-}
-static jstring getRevisionNative(JNIEnv *env, jobject obj) {
- return common_Get(env, obj, "GetRevision");
-}
+ const char *c_pin = env->GetStringUTFChars(pin, NULL);
-static jstring getManufacturerNative(JNIEnv *env, jobject obj) {
- return common_Get(env, obj, "GetManufacturer");
-}
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
+ DBUS_TYPE_INVALID);
-static jstring getCompanyNative(JNIEnv *env, jobject obj) {
- return common_Get(env, obj, "GetCompany");
+ dbus_connection_send(nat->conn, reply, NULL);
+ dbus_message_unref(msg);
+ dbus_message_unref(reply);
+ env->ReleaseStringUTFChars(pin, c_pin);
+ return JNI_TRUE;
+ }
+#endif
+ return JNI_FALSE;
}
-static jboolean setNameNative(JNIEnv *env, jobject obj, jstring name) {
+static jboolean cancelPinNative(JNIEnv *env, jobject object, jstring address,
+ int nativeData) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, obj);
+ native_data_t *nat = get_native_data(env, object);
if (nat) {
- const char *c_name = env->GetStringUTFChars(name, NULL);
- DBusMessage *reply = dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "SetName",
- DBUS_TYPE_STRING, &c_name,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(name, c_name);
- if (reply) {
- dbus_message_unref(reply);
- return JNI_TRUE;
+ DBusMessage *msg = (DBusMessage *)nativeData;
+ DBusMessage *reply = dbus_message_new_error(msg,
+ "org.bluez.Error.Canceled", "PIN Entry was canceled");
+ if (!reply) {
+ LOGE("%s: Cannot create message reply to return PIN cancel to "
+ "D-BUS\n", __FUNCTION__);
+ dbus_message_unref(msg);
+ return JNI_FALSE;
}
+
+ dbus_connection_send(nat->conn, reply, NULL);
+ dbus_message_unref(msg);
+ dbus_message_unref(reply);
+ return JNI_TRUE;
}
#endif
return JNI_FALSE;
}
-static jstring common_getRemote(JNIEnv *env, jobject object, const char *func,
- jstring address) {
- LOGV("%s:%s", __FUNCTION__, func);
+static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
+ jstring path)
+{
#ifdef HAVE_BLUETOOTH
+ LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
+ DBusMessage *msg, *reply;
DBusError err;
dbus_error_init(&err);
- LOGV("... address = %s", c_address);
+ const char *c_path = env->GetStringUTFChars(path, NULL);
+ reply = dbus_func_args_timeout(env,
+ nat->conn, -1, c_path,
+ DBUS_DEVICE_IFACE, "GetProperties",
+ DBUS_TYPE_INVALID);
+ env->ReleaseStringUTFChars(path, c_path);
- DBusMessage *reply =
- dbus_func_args_error(env, nat->conn, &err, nat->adapter,
- DBUS_CLASS_NAME, func,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- if (reply) {
- return dbus_returns_string(env, reply);
- } else if (!strcmp(func, "GetRemoteName") &&
- dbus_error_has_name(&err, "org.bluez.Error.RequestDeferred")) {
- // This error occurs if we request name during device discovery,
- // its fine
- LOGV("... %s: %s", func, err.message);
- dbus_error_free(&err);
- return NULL;
- } else {
- LOG_AND_FREE_DBUS_ERROR(&err);
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ } else
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
return NULL;
}
+ DBusMessageIter iter;
+ jobjectArray str_array = NULL;
+ if (dbus_message_iter_init(reply, &iter))
+ str_array = parse_remote_device_properties(env, &iter);
+ dbus_message_unref(reply);
+ return str_array;
}
#endif
return NULL;
}
-static jstring getRemoteVersionNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "GetRemoteVersion", address);
-}
-
-static jstring getRemoteRevisionNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "GetRemoteRevision", address);
-}
-
-static jstring getRemoteManufacturerNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "GetRemoteManufacturer", address);
-}
-
-static jstring getRemoteCompanyNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "GetRemoteCompany", address);
-}
-
-static jstring getRemoteNameNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "GetRemoteName", address);
-}
-
-static jstring lastSeenNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "LastSeen", address);
-}
-
-static jstring lastUsedNative(JNIEnv *env, jobject obj, jstring address) {
- return common_getRemote(env, obj, "LastUsed", address);
-}
-
-static jint getRemoteClassNative(JNIEnv *env, jobject object, jstring address) {
- jint result = BLUETOOTH_CLASS_ERROR;
+static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
-
- LOGV("... address = %s", c_address);
+ DBusMessage *msg, *reply;
+ DBusError err;
+ dbus_error_init(&err);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetRemoteClass",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- if (reply)
- {
- DBusError err;
- dbus_error_init(&err);
- if (!dbus_message_get_args(reply, &err,
- DBUS_TYPE_UINT32, &result,
- DBUS_TYPE_INVALID)) {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
- dbus_message_unref(reply);
+ reply = dbus_func_args_timeout(env,
+ nat->conn, -1, get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "GetProperties",
+ DBUS_TYPE_INVALID);
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ } else
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+ return NULL;
}
- }
-#endif
- return result;
-}
-
-static jbyteArray getRemoteFeaturesNative(JNIEnv *env, jobject object,
- jstring address) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
-
- LOGV("... address = %s", c_address);
-
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetRemoteFeatures",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- /* array of DBUS_TYPE_BYTE_AS_STRING */
- return reply ? dbus_returns_array_of_bytes(env, reply) : NULL;
+ DBusMessageIter iter;
+ jobjectArray str_array = NULL;
+ if (dbus_message_iter_init(reply, &iter))
+ str_array = parse_adapter_properties(env, &iter);
+ dbus_message_unref(reply);
+ return str_array;
}
#endif
return NULL;
}
-static jintArray getRemoteServiceHandlesNative(JNIEnv *env, jobject object,
- jstring address, jstring match) {
+static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
+ void *value, jint type) {
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
- jintArray intArray = NULL;
- const char *c_address = env->GetStringUTFChars(address, NULL);
- const char *c_match = env->GetStringUTFChars(match, NULL);
-
- LOGV("... address = %s match = %s", c_address, c_match);
+ DBusMessage *reply, *msg;
+ DBusMessageIter iter;
+ DBusError err;
+ const char *c_key = env->GetStringUTFChars(key, NULL);
+ dbus_error_init(&err);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetRemoteServiceHandles",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_STRING, &c_match,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- env->ReleaseStringUTFChars(match, c_match);
- if (reply)
- {
- DBusError err;
- jint *list;
- int i, len;
-
- dbus_error_init(&err);
- if (dbus_message_get_args (reply, &err,
- DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
- &list, &len,
- DBUS_TYPE_INVALID)) {
- if (len) {
- intArray = env->NewIntArray(len);
- if (intArray)
- env->SetIntArrayRegion(intArray, 0, len, list);
- }
- } else {
- LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, reply);
- }
-
- dbus_message_unref(reply);
+ msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "SetProperty");
+ if (!msg) {
+ LOGE("%s: Can't allocate new method call for GetProperties!",
+ __FUNCTION__);
+ return JNI_FALSE;
}
- return intArray;
- }
-#endif
- return NULL;
-}
-
-static jbyteArray getRemoteServiceRecordNative(JNIEnv *env, jobject object,
- jstring address, jint handle) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- LOGV("... address = %s", c_address);
+ dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
+ dbus_message_iter_init_append(msg, &iter);
+ append_variant(&iter, type, value);
- DBusMessage *reply =
- dbus_func_args(env, nat->conn, nat->adapter,
- DBUS_CLASS_NAME, "GetRemoteServiceRecord",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_UINT32, &handle,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return reply ? dbus_returns_array_of_bytes(env, reply) : NULL;
- }
-#endif
- return NULL;
-}
+ reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
+ dbus_message_unref(msg);
-static jboolean getRemoteServiceChannelNative(JNIEnv *env, jobject object,
- jstring address, jshort uuid16) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
- struct event_loop_native_data_t *eventLoopNat =
- get_EventLoop_native_data(env, eventLoop);
- if (nat && eventLoopNat) {
- const char *c_address = env->GetStringUTFChars(address, NULL);
- char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
- strlcpy(context_address, c_address, BTADDR_SIZE);
+ env->ReleaseStringUTFChars(key, c_key);
- LOGV("... address = %s", c_address);
- LOGV("... uuid16 = %#X", uuid16);
-
- bool ret = dbus_func_args_async(env, nat->conn, 20000, // ms
- onGetRemoteServiceChannelResult, context_address,
- eventLoopNat,
- nat->adapter,
- DBUS_CLASS_NAME, "GetRemoteServiceChannel",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_UINT16, &uuid16,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- return ret ? JNI_TRUE : JNI_FALSE;
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ } else
+ LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
}
#endif
return JNI_FALSE;
}
-static jint enableNative(JNIEnv *env, jobject object) {
+static jboolean setAdapterPropertyStringNative(JNIEnv *env, jobject object, jstring key,
+ jstring value) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- return bt_enable();
+ const char *c_value = env->GetStringUTFChars(value, NULL);
+ jboolean ret = setAdapterPropertyNative(env, object, key, (void *)&c_value, DBUS_TYPE_STRING);
+ env->ReleaseStringUTFChars(value, (char *)c_value);
+ return ret;
+#else
+ return JNI_FALSE;
#endif
- return -1;
}
-static jint disableNative(JNIEnv *env, jobject object) {
+static jboolean setAdapterPropertyIntegerNative(JNIEnv *env, jobject object, jstring key,
+ jint value) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- return bt_disable();
-#endif
- return -1;
-}
-
-static jint isEnabledNative(JNIEnv *env, jobject object) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- return bt_is_enabled();
+ return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_UINT32);
+#else
+ return JNI_FALSE;
#endif
- return -1;
}
-static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
- jstring pin, int nativeData) {
+static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jstring key,
+ jint value) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- LOGE("%s: Cannot create message reply to return PIN code to "
- "D-Bus\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- const char *c_pin = env->GetStringUTFChars(pin, NULL);
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &c_pin,
- DBUS_TYPE_INVALID);
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- env->ReleaseStringUTFChars(pin, c_pin);
- return JNI_TRUE;
- }
-#endif
+ return setAdapterPropertyNative(env, object, key, (void *)&value, DBUS_TYPE_BOOLEAN);
+#else
return JNI_FALSE;
-}
-
-static jboolean cancelPinNative(JNIEnv *env, jobject object, jstring address,
- int nativeData) {
-#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
- native_data_t *nat = get_native_data(env, object);
- if (nat) {
- DBusMessage *msg = (DBusMessage *)nativeData;
- DBusMessage *reply = dbus_message_new_error(msg,
- "org.bluez.Error.Canceled", "PIN Entry was canceled");
- if (!reply) {
- LOGE("%s: Cannot create message reply to return PIN cancel to "
- "D-BUS\n", __FUNCTION__);
- dbus_message_unref(msg);
- return JNI_FALSE;
- }
-
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(msg);
- dbus_message_unref(reply);
- return JNI_TRUE;
- }
#endif
- return JNI_FALSE;
}
+
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void*)classInitNative},
{"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
+ {"setupNativeDataNative", "()Z", (void *)setupNativeDataNative},
+ {"tearDownNativeDataNative", "()Z", (void *)tearDownNativeDataNative},
{"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
{"getAdapterPathNative", "()Ljava/lang/String;", (void*)getAdapterPathNative},
@@ -982,46 +645,25 @@ static JNINativeMethod sMethods[] = {
{"enableNative", "()I", (void *)enableNative},
{"disableNative", "()I", (void *)disableNative},
- {"getAddressNative", "()Ljava/lang/String;", (void *)getAddressNative},
- {"getNameNative", "()Ljava/lang/String;", (void*)getNameNative},
- {"setNameNative", "(Ljava/lang/String;)Z", (void *)setNameNative},
- {"getVersionNative", "()Ljava/lang/String;", (void *)getVersionNative},
- {"getRevisionNative", "()Ljava/lang/String;", (void *)getRevisionNative},
- {"getManufacturerNative", "()Ljava/lang/String;", (void *)getManufacturerNative},
- {"getCompanyNative", "()Ljava/lang/String;", (void *)getCompanyNative},
-
- {"getModeNative", "()Ljava/lang/String;", (void *)getModeNative},
- {"setModeNative", "(Ljava/lang/String;)Z", (void *)setModeNative},
-
- {"getDiscoverableTimeoutNative", "()I", (void *)getDiscoverableTimeoutNative},
- {"setDiscoverableTimeoutNative", "(I)Z", (void *)setDiscoverableTimeoutNative},
-
- {"startDiscoveryNative", "(Z)Z", (void*)startDiscoveryNative},
- {"cancelDiscoveryNative", "()Z", (void *)cancelDiscoveryNative},
- {"startPeriodicDiscoveryNative", "()Z", (void *)startPeriodicDiscoveryNative},
- {"stopPeriodicDiscoveryNative", "()Z", (void *)stopPeriodicDiscoveryNative},
- {"isPeriodicDiscoveryNative", "()Z", (void *)isPeriodicDiscoveryNative},
- {"listRemoteDevicesNative", "()[Ljava/lang/String;", (void *)listRemoteDevicesNative},
-
- {"listConnectionsNative", "()[Ljava/lang/String;", (void *)listConnectionsNative},
- {"isConnectedNative", "(Ljava/lang/String;)Z", (void *)isConnectedNative},
- {"disconnectRemoteDeviceNative", "(Ljava/lang/String;)Z", (void *)disconnectRemoteDeviceNative},
-
- {"createBondingNative", "(Ljava/lang/String;I)Z", (void *)createBondingNative},
- {"cancelBondingProcessNative", "(Ljava/lang/String;)Z", (void *)cancelBondingProcessNative},
- {"listBondingsNative", "()[Ljava/lang/String;", (void *)listBondingsNative},
- {"removeBondingNative", "(Ljava/lang/String;)Z", (void *)removeBondingNative},
-
- {"getRemoteNameNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getRemoteNameNative},
- {"getRemoteVersionNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getRemoteVersionNative},
- {"getRemoteRevisionNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getRemoteRevisionNative},
- {"getRemoteClassNative", "(Ljava/lang/String;)I", (void *)getRemoteClassNative},
- {"getRemoteManufacturerNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getRemoteManufacturerNative},
- {"getRemoteCompanyNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)getRemoteCompanyNative},
- {"getRemoteServiceChannelNative", "(Ljava/lang/String;S)Z", (void *)getRemoteServiceChannelNative},
- {"getRemoteFeaturesNative", "(Ljava/lang/String;)[B", (void *)getRemoteFeaturesNative},
- {"lastSeenNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)lastSeenNative},
- {"lastUsedNative", "(Ljava/lang/String;)Ljava/lang/String;", (void *)lastUsedNative},
+ {"getAdapterPropertiesNative", "()[Ljava/lang/Object;", (void *)getAdapterPropertiesNative},
+ {"getDevicePropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
+ (void *)getDevicePropertiesNative},
+ {"setAdapterPropertyStringNative", "(Ljava/lang/String;Ljava/lang/String;)Z",
+ (void *)setAdapterPropertyStringNative},
+ {"setAdapterPropertyBooleanNative", "(Ljava/lang/String;I)Z",
+ (void *)setAdapterPropertyBooleanNative},
+ {"setAdapterPropertyIntegerNative", "(Ljava/lang/String;I)Z",
+ (void *)setAdapterPropertyIntegerNative},
+
+ {"startDiscoveryNative", "()Z", (void*)startDiscoveryNative},
+ {"stopDiscoveryNative", "()Z", (void *)stopDiscoveryNative},
+
+ {"createPairedDeviceNative", "(Ljava/lang/String;I)Z", (void *)createPairedDeviceNative},
+ {"cancelDeviceCreationNative", "(Ljava/lang/String;)Z", (void *)cancelDeviceCreationNative},
+ {"removeDeviceNative", "(Ljava/lang/String;)Z", (void *)removeDeviceNative},
+ {"getDeviceServiceChannelNative", "(Ljava/lang/String;Ljava/lang/String;I)I",
+ (void *)getDeviceServiceChannelNative},
+
{"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
{"cancelPinNative", "(Ljava/lang/String;I)Z", (void *)cancelPinNative},
};
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 7c5da5b..e0ea788 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -39,30 +39,19 @@ namespace android {
#ifdef HAVE_BLUETOOTH
static jfieldID field_mNativeData;
-static jmethodID method_onModeChanged;
-static jmethodID method_onNameChanged;
-static jmethodID method_onDiscoveryStarted;
-static jmethodID method_onDiscoveryCompleted;
-static jmethodID method_onRemoteDeviceFound;
-static jmethodID method_onRemoteDeviceDisappeared;
-static jmethodID method_onRemoteClassUpdated;
-static jmethodID method_onRemoteNameUpdated;
-static jmethodID method_onRemoteNameFailed;
-static jmethodID method_onRemoteDeviceConnected;
-static jmethodID method_onRemoteDeviceDisconnectRequested;
-static jmethodID method_onRemoteDeviceDisconnected;
-static jmethodID method_onBondingCreated;
-static jmethodID method_onBondingRemoved;
-
-static jmethodID method_onCreateBondingResult;
-static jmethodID method_onGetRemoteServiceChannelResult;
-
-static jmethodID method_onPasskeyAgentRequest;
-static jmethodID method_onPasskeyAgentCancel;
-static jmethodID method_onAuthAgentAuthorize;
-static jmethodID method_onAuthAgentCancel;
-
-static jmethodID method_onRestartRequired;
+static jmethodID method_onPropertyChanged;
+static jmethodID method_onDevicePropertyChanged;
+static jmethodID method_onDeviceFound;
+static jmethodID method_onDeviceDisappeared;
+static jmethodID method_onDeviceCreated;
+static jmethodID method_onDeviceRemoved;
+
+static jmethodID method_onCreatePairedDeviceResult;
+static jmethodID method_onGetDeviceServiceChannelResult;
+
+static jmethodID method_onRequestPinCode;
+static jmethodID method_onAgentAuthorize;
+static jmethodID method_onAgentCancel;
typedef event_loop_native_data_t native_data_t;
@@ -80,30 +69,26 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
LOGV(__FUNCTION__);
#ifdef HAVE_BLUETOOTH
- method_onModeChanged = env->GetMethodID(clazz, "onModeChanged", "(Ljava/lang/String;)V");
- method_onNameChanged = env->GetMethodID(clazz, "onNameChanged", "(Ljava/lang/String;)V");
- method_onDiscoveryStarted = env->GetMethodID(clazz, "onDiscoveryStarted", "()V");
- method_onDiscoveryCompleted = env->GetMethodID(clazz, "onDiscoveryCompleted", "()V");
- method_onRemoteDeviceFound = env->GetMethodID(clazz, "onRemoteDeviceFound", "(Ljava/lang/String;IS)V");
- method_onRemoteDeviceDisappeared = env->GetMethodID(clazz, "onRemoteDeviceDisappeared", "(Ljava/lang/String;)V");
- method_onRemoteClassUpdated = env->GetMethodID(clazz, "onRemoteClassUpdated", "(Ljava/lang/String;I)V");
- method_onRemoteNameUpdated = env->GetMethodID(clazz, "onRemoteNameUpdated", "(Ljava/lang/String;Ljava/lang/String;)V");
- method_onRemoteNameFailed = env->GetMethodID(clazz, "onRemoteNameFailed", "(Ljava/lang/String;)V");
- method_onRemoteDeviceConnected = env->GetMethodID(clazz, "onRemoteDeviceConnected", "(Ljava/lang/String;)V");
- method_onRemoteDeviceDisconnectRequested = env->GetMethodID(clazz, "onRemoteDeviceDisconnectRequested", "(Ljava/lang/String;)V");
- method_onRemoteDeviceDisconnected = env->GetMethodID(clazz, "onRemoteDeviceDisconnected", "(Ljava/lang/String;)V");
- method_onBondingCreated = env->GetMethodID(clazz, "onBondingCreated", "(Ljava/lang/String;)V");
- method_onBondingRemoved = env->GetMethodID(clazz, "onBondingRemoved", "(Ljava/lang/String;)V");
-
- method_onCreateBondingResult = env->GetMethodID(clazz, "onCreateBondingResult", "(Ljava/lang/String;I)V");
-
- method_onPasskeyAgentRequest = env->GetMethodID(clazz, "onPasskeyAgentRequest", "(Ljava/lang/String;I)V");
- method_onPasskeyAgentCancel = env->GetMethodID(clazz, "onPasskeyAgentCancel", "(Ljava/lang/String;)V");
- method_onAuthAgentAuthorize = env->GetMethodID(clazz, "onAuthAgentAuthorize", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
- method_onAuthAgentCancel = env->GetMethodID(clazz, "onAuthAgentCancel", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
- method_onGetRemoteServiceChannelResult = env->GetMethodID(clazz, "onGetRemoteServiceChannelResult", "(Ljava/lang/String;I)V");
-
- method_onRestartRequired = env->GetMethodID(clazz, "onRestartRequired", "()V");
+ method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
+ "([Ljava/lang/String;)V");
+ method_onDevicePropertyChanged = env->GetMethodID(clazz,
+ "onDevicePropertyChanged",
+ "(Ljava/lang/String;[Ljava/lang/String;)V");
+ method_onDeviceFound = env->GetMethodID(clazz, "onDeviceFound",
+ "(Ljava/lang/String;[Ljava/lang/String;)V");
+ method_onDeviceDisappeared = env->GetMethodID(clazz, "onDeviceDisappeared",
+ "(Ljava/lang/String;)V");
+ method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V");
+ method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
+
+ method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
+ "(Ljava/lang/String;I)V");
+
+ method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
+ "(Ljava/lang/String;Ljava/lang/String;)Z");
+ method_onAgentCancel = env->GetMethodID(clazz, "onAgentCancel", "()V");
+ method_onRequestPinCode = env->GetMethodID(clazz, "onRequestPinCode",
+ "(Ljava/lang/String;I)V");
field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
#endif
@@ -153,9 +138,11 @@ static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
#ifdef HAVE_BLUETOOTH
static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
void *data);
-static DBusHandlerResult agent_event_filter(DBusConnection *conn,
- DBusMessage *msg,
- void *data);
+DBusHandlerResult agent_event_filter(DBusConnection *conn,
+ DBusMessage *msg,
+ void *data);
+static int register_agent(native_data_t *nat,
+ const char *agent_path, const char *capabilities);
static const DBusObjectPathVTable agent_vtable = {
NULL, agent_event_filter, NULL, NULL, NULL, NULL
@@ -164,11 +151,12 @@ static const DBusObjectPathVTable agent_vtable = {
static jboolean setUpEventLoop(native_data_t *nat) {
LOGV(__FUNCTION__);
- dbus_threads_init_default();
- DBusError err;
- dbus_error_init(&err);
if (nat != NULL && nat->conn != NULL) {
+ dbus_threads_init_default();
+ DBusError err;
+ dbus_error_init(&err);
+
// Add a filter for all incoming messages
if (!dbus_connection_add_filter(nat->conn, event_filter, nat, NULL)){
return JNI_FALSE;
@@ -190,108 +178,143 @@ static jboolean setUpEventLoop(native_data_t *nat) {
return JNI_FALSE;
}
dbus_bus_add_match(nat->conn,
- "type='signal',interface='org.bluez.audio.Manager'",
+ "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Device'",
&err);
if (dbus_error_is_set(&err)) {
LOG_AND_FREE_DBUS_ERROR(&err);
return JNI_FALSE;
}
dbus_bus_add_match(nat->conn,
- "type='signal',interface='org.bluez.audio.Device'",
- &err);
- if (dbus_error_is_set(&err)) {
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
- dbus_bus_add_match(nat->conn,
- "type='signal',interface='org.bluez.audio.Sink'",
+ "type='signal',interface='org.bluez.AudioSink'",
&err);
if (dbus_error_is_set(&err)) {
LOG_AND_FREE_DBUS_ERROR(&err);
return JNI_FALSE;
}
- // Add an object handler for passkey agent method calls
- const char *path = "/android/bluetooth/Agent";
- if (!dbus_connection_register_object_path(nat->conn, path,
- &agent_vtable, nat)) {
- LOGE("%s: Can't register object path %s for agent!",
- __FUNCTION__, path);
+ const char *agent_path = "/android/bluetooth/agent";
+ const char *capabilities = "DisplayYesNo";
+ if (register_agent(nat, agent_path, capabilities) < 0) {
+ dbus_connection_unregister_object_path (nat->conn, agent_path);
return JNI_FALSE;
}
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
- // RegisterDefaultPasskeyAgent() will fail until hcid is up, so keep
- // trying for 10 seconds.
- int attempt;
- for (attempt = 0; attempt < 1000; attempt++) {
- DBusMessage *reply = dbus_func_args_error(NULL, nat->conn, &err,
- BLUEZ_DBUS_BASE_PATH,
- "org.bluez.Security", "RegisterDefaultPasskeyAgent",
- DBUS_TYPE_STRING, &path,
- DBUS_TYPE_INVALID);
- if (reply) {
- // Success
- dbus_message_unref(reply);
- LOGV("Registered agent on attempt %d of 1000\n", attempt);
- break;
- } else if (dbus_error_has_name(&err,
- "org.freedesktop.DBus.Error.ServiceUnknown")) {
- // hcid is still down, retry
- dbus_error_free(&err);
- usleep(10000); // 10 ms
- } else {
- // Some other error we weren't expecting
- LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
- }
+
+const char * get_adapter_path(DBusConnection *conn) {
+ DBusMessage *msg, *reply;
+ DBusError err;
+ const char *device_path = NULL;
+ msg = dbus_message_new_method_call("org.bluez", "/",
+ "org.bluez.Manager", "DefaultAdapter");
+ if (!msg) {
+ LOGE("%s: Can't allocate new method call for GetProperties!",
+ __FUNCTION__);
+ return NULL;
+ }
+ dbus_message_append_args(msg, DBUS_TYPE_INVALID);
+
+ dbus_error_init(&err);
+ reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
}
- if (attempt == 1000) {
- LOGE("Time-out trying to call RegisterDefaultPasskeyAgent(), "
- "is hcid running?");
- return JNI_FALSE;
+ return NULL;
+ }
+ if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
+ &device_path, DBUS_TYPE_INVALID)
+ || !device_path){
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
}
+ return NULL;
+ }
+ return device_path;
+}
- // Now register the Auth agent
- DBusMessage *reply = dbus_func_args_error(NULL, nat->conn, &err,
- BLUEZ_DBUS_BASE_PATH,
- "org.bluez.Security", "RegisterDefaultAuthorizationAgent",
- DBUS_TYPE_STRING, &path,
- DBUS_TYPE_INVALID);
- if (!reply) {
+static int register_agent(native_data_t *nat,
+ const char * agent_path, const char * capabilities)
+{
+ DBusMessage *msg, *reply;
+ DBusError err;
+
+ if (!dbus_connection_register_object_path(nat->conn, agent_path,
+ &agent_vtable, nat)) {
+ LOGE("%s: Can't register object path %s for agent!",
+ __FUNCTION__, agent_path);
+ return -1;
+ }
+
+ nat->adapter = get_adapter_path(nat->conn);
+ msg = dbus_message_new_method_call("org.bluez", nat->adapter,
+ "org.bluez.Adapter", "RegisterAgent");
+ if (!msg) {
+ LOGE("%s: Can't allocate new method call for agent!",
+ __FUNCTION__);
+ return -1;
+ }
+ dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_STRING, &capabilities,
+ DBUS_TYPE_INVALID);
+
+ dbus_error_init(&err);
+ reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
+ dbus_message_unref(msg);
+
+ if (!reply) {
+ LOGE("%s: Can't register agent!", __FUNCTION__);
+ if (dbus_error_is_set(&err)) {
LOG_AND_FREE_DBUS_ERROR(&err);
- return JNI_FALSE;
}
-
- dbus_message_unref(reply);
- return JNI_TRUE;
+ return -1;
}
- return JNI_FALSE;
+ dbus_message_unref(reply);
+ dbus_connection_flush(nat->conn);
+
+ return 0;
}
static void tearDownEventLoop(native_data_t *nat) {
LOGV(__FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
+ DBusMessage *msg, *reply;
DBusError err;
dbus_error_init(&err);
+ const char * agent_path = "/android/bluetooth/agent";
+
+ msg = dbus_message_new_method_call("org.bluez",
+ nat->adapter,
+ "org.bluez.Adapter",
+ "UnregisterAgent");
+ if (msg != NULL) {
+ dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path,
+ DBUS_TYPE_INVALID);
+ reply = dbus_connection_send_with_reply_and_block(nat->conn,
+ msg, -1, &err);
- const char *path = "/android/bluetooth/Agent";
- DBusMessage *reply =
- dbus_func_args(NULL, nat->conn, BLUEZ_DBUS_BASE_PATH,
- "org.bluez.Security", "UnregisterDefaultPasskeyAgent",
- DBUS_TYPE_STRING, &path,
- DBUS_TYPE_INVALID);
- if (reply) dbus_message_unref(reply);
-
- reply =
- dbus_func_args(NULL, nat->conn, BLUEZ_DBUS_BASE_PATH,
- "org.bluez.Security", "UnregisterDefaultAuthorizationAgent",
- DBUS_TYPE_STRING, &path,
- DBUS_TYPE_INVALID);
- if (reply) dbus_message_unref(reply);
+ if (!reply) {
+ if (dbus_error_is_set(&err)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ dbus_error_free(&err);
+ }
+ } else {
+ dbus_message_unref(reply);
+ }
+ dbus_message_unref(msg);
+ } else {
+ LOGE("%s: Can't create new method call!", __FUNCTION__);
+ }
- dbus_connection_unregister_object_path(nat->conn, path);
+ dbus_connection_flush(nat->conn);
+ dbus_connection_unregister_object_path(nat->conn, agent_path);
dbus_bus_remove_match(nat->conn,
"type='signal',interface='org.bluez.audio.Sink'",
@@ -649,267 +672,129 @@ static DBusHandlerResult event_filter(DBusConnection *conn, DBusMessage *msg,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- LOGV("%s: Received signal %s:%s from %s", __FUNCTION__,
- dbus_message_get_interface(msg), dbus_message_get_member(msg),
- dbus_message_get_path(msg));
+ // STOPSHIP: Change to LOGV
+ LOGE("%s: Received signal %s:%s from %s", __FUNCTION__,
+ dbus_message_get_interface(msg), dbus_message_get_member(msg),
+ dbus_message_get_path(msg));
if (dbus_message_is_signal(msg,
"org.bluez.Adapter",
- "RemoteDeviceFound")) {
+ "DeviceFound")) {
char *c_address;
- int n_class;
- short n_rssi;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_UINT32, &n_class,
- DBUS_TYPE_INT16, &n_rssi,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s class = %#X rssi = %hd", c_address, n_class,
- n_rssi);
+ DBusMessageIter iter;
+ jobjectArray str_array = NULL;
+ if (dbus_message_iter_init(msg, &iter)) {
+ dbus_message_iter_get_basic(&iter, &c_address);
+ if (dbus_message_iter_next(&iter))
+ str_array =
+ parse_remote_device_properties(env, &iter);
+ }
+ if (str_array != NULL) {
env->CallVoidMethod(nat->me,
- method_onRemoteDeviceFound,
+ method_onDeviceFound,
env->NewStringUTF(c_address),
- (jint)n_class,
- (jshort)n_rssi);
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "DiscoveryStarted")) {
- LOGI("DiscoveryStarted signal received");
- env->CallVoidMethod(nat->me, method_onDiscoveryStarted);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "DiscoveryCompleted")) {
- LOGI("DiscoveryCompleted signal received");
- env->CallVoidMethod(nat->me, method_onDiscoveryCompleted);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteDeviceDisappeared")) {
- char *c_address;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me, method_onRemoteDeviceDisappeared,
- env->NewStringUTF(c_address));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteClassUpdated")) {
- char *c_address;
- int n_class;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_UINT32, &n_class,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me, method_onRemoteClassUpdated,
- env->NewStringUTF(c_address), (jint)n_class);
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteNameUpdated")) {
- char *c_address;
- char *c_name;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_STRING, &c_name,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s, name = %s", c_address, c_name);
- env->CallVoidMethod(nat->me,
- method_onRemoteNameUpdated,
- env->NewStringUTF(c_address),
- env->NewStringUTF(c_name));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteNameFailed")) {
- char *c_address;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me,
- method_onRemoteNameFailed,
- env->NewStringUTF(c_address));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+ str_array);
+ } else
+ LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteDeviceConnected")) {
+ "org.bluez.Adapter",
+ "DeviceDisappeared")) {
char *c_address;
if (dbus_message_get_args(msg, &err,
DBUS_TYPE_STRING, &c_address,
DBUS_TYPE_INVALID)) {
LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me,
- method_onRemoteDeviceConnected,
+ env->CallVoidMethod(nat->me, method_onDeviceDisappeared,
env->NewStringUTF(c_address));
} else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteDeviceDisconnectRequested")) {
- char *c_address;
+ "org.bluez.Adapter",
+ "DeviceCreated")) {
+ char *c_object_path;
if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
+ DBUS_TYPE_OBJECT_PATH, &c_object_path,
DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
+ LOGV("... address = %s", c_object_path);
env->CallVoidMethod(nat->me,
- method_onRemoteDeviceDisconnectRequested,
- env->NewStringUTF(c_address));
+ method_onDeviceCreated,
+ env->NewStringUTF(c_object_path));
} else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "RemoteDeviceDisconnected")) {
- char *c_address;
+ "org.bluez.Adapter",
+ "DeviceRemoved")) {
+ char *c_object_path;
if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me,
- method_onRemoteDeviceDisconnected,
- env->NewStringUTF(c_address));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "BondingCreated")) {
- char *c_address;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me,
- method_onBondingCreated,
- env->NewStringUTF(c_address));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "BondingRemoved")) {
- char *c_address;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID)) {
- LOGV("... address = %s", c_address);
- env->CallVoidMethod(nat->me,
- method_onBondingRemoved,
- env->NewStringUTF(c_address));
+ DBUS_TYPE_OBJECT_PATH, &c_object_path,
+ DBUS_TYPE_INVALID)) {
+ LOGV("... Object Path = %s", c_object_path);
+ env->CallVoidMethod(nat->me,
+ method_onDeviceRemoved,
+ env->NewStringUTF(c_object_path));
} else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal(msg,
"org.bluez.Adapter",
- "ModeChanged")) {
- char *c_mode;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_mode,
- DBUS_TYPE_INVALID)) {
- LOGV("... mode = %s", c_mode);
+ "PropertyChanged")) {
+ jobjectArray str_array = parse_adapter_property_change(env, msg);
+ if (str_array != NULL) {
+ /* Check if bluetoothd has (re)started, if so update the path. */
+ jstring property =(jstring) env->GetObjectArrayElement(str_array, 0);
+ const char *c_property = env->GetStringUTFChars(property, NULL);
+ if (!strncmp(c_property, "Powered", strlen("Powered"))) {
+ jstring value =
+ (jstring) env->GetObjectArrayElement(str_array, 1);
+ const char *c_value = env->GetStringUTFChars(value, NULL);
+ if (!strncmp(c_value, "true", strlen("true")))
+ nat->adapter = get_adapter_path(nat->conn);
+ env->ReleaseStringUTFChars(value, c_value);
+ }
+ env->ReleaseStringUTFChars(property, c_property);
+
env->CallVoidMethod(nat->me,
- method_onModeChanged,
- env->NewStringUTF(c_mode));
+ method_onPropertyChanged,
+ str_array);
} else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal(msg,
- "org.bluez.Adapter",
- "NameChanged")) {
- char *c_name;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_name,
- DBUS_TYPE_INVALID)) {
- LOGV("... name = %s", c_name);
+ "org.bluez.Device",
+ "PropertyChanged")) {
+ jobjectArray str_array = parse_remote_device_property_change(env, msg);
+ if (str_array != NULL) {
+ const char *remote_device_path = dbus_message_get_path(msg);
env->CallVoidMethod(nat->me,
- method_onNameChanged,
- env->NewStringUTF(c_name));
- } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_signal(msg,
- "org.freedesktop.DBus",
- "NameOwnerChanged")) {
- char *c_name;
- char *c_old_owner;
- char *c_new_owner;
- if (dbus_message_get_args(msg, &err,
- DBUS_TYPE_STRING, &c_name,
- DBUS_TYPE_STRING, &c_old_owner,
- DBUS_TYPE_STRING, &c_new_owner,
- DBUS_TYPE_INVALID)) {
- LOGV("... name = %s", c_name);
- LOGV("... old_owner = %s", c_old_owner);
- LOGV("... new_owner = %s", c_new_owner);
- if (!strcmp(c_name, "org.bluez") && c_new_owner[0] != '\0') {
- // New owner of org.bluez. This can only happen when hcid
- // restarts. Need to restart framework BT services to recover.
- LOGE("Looks like hcid restarted");
- env->CallVoidMethod(nat->me, method_onRestartRequired);
- }
+ method_onDevicePropertyChanged,
+ env->NewStringUTF(remote_device_path),
+ str_array);
} else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
return DBUS_HANDLER_RESULT_HANDLED;
- }
+ }
return a2dp_event_filter(msg, env);
}
// Called by dbus during WaitForAndDispatchEventNative()
-static DBusHandlerResult agent_event_filter(DBusConnection *conn,
- DBusMessage *msg, void *data) {
+DBusHandlerResult agent_event_filter(DBusConnection *conn,
+ DBusMessage *msg, void *data) {
native_data_t *nat = (native_data_t *)data;
JNIEnv *env;
- nat->vm->GetEnv((void**)&env, nat->envVer);
if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
LOGV("%s: not interested (not a method call).", __FUNCTION__);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- LOGV("%s: Received method %s:%s", __FUNCTION__,
+ LOGI("%s: Received method %s:%s", __FUNCTION__,
dbus_message_get_interface(msg), dbus_message_get_member(msg));
- if (dbus_message_is_method_call(msg,
- "org.bluez.PasskeyAgent", "Request")) {
-
- const char *adapter;
- const char *address;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &adapter,
- DBUS_TYPE_STRING, &address,
- DBUS_TYPE_INVALID)) {
- LOGE("%s: Invalid arguments for Request() method", __FUNCTION__);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- LOGV("... address = %s", address);
-
- dbus_message_ref(msg); // increment refcount because we pass to java
+ if (nat == NULL) return DBUS_HANDLER_RESULT_HANDLED;
- env->CallVoidMethod(nat->me, method_onPasskeyAgentRequest,
- env->NewStringUTF(address), (int)msg);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.PasskeyAgent", "Cancel")) {
-
- const char *adapter;
- const char *address;
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &adapter,
- DBUS_TYPE_STRING, &address,
- DBUS_TYPE_INVALID)) {
- LOGE("%s: Invalid arguments for Cancel() method", __FUNCTION__);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- LOGV("... address = %s", address);
+ nat->vm->GetEnv((void**)&env, nat->envVer);
+ if (dbus_message_is_method_call(msg,
+ "org.bluez.Agent", "Cancel")) {
- env->CallVoidMethod(nat->me, method_onPasskeyAgentCancel,
- env->NewStringUTF(address));
+ env->CallVoidMethod(nat->me, method_onAgentCancel);
// reply
DBusMessage *reply = dbus_message_new_method_return(msg);
@@ -922,41 +807,23 @@ static DBusHandlerResult agent_event_filter(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg,
- "org.bluez.PasskeyAgent", "Release")) {
- LOGW("We are no longer the passkey agent!");
-
- // reply
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- LOGE("%s: Cannot create message reply\n", __FUNCTION__);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_HANDLED;
- } else if (dbus_message_is_method_call(msg,
- "org.bluez.AuthorizationAgent", "Authorize")) {
- const char *adapter;
- const char *address;
- const char *service;
+ "org.bluez.Agent", "Authorize")) {
+ char *object_path;
const char *uuid;
if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &adapter,
- DBUS_TYPE_STRING, &address,
- DBUS_TYPE_STRING, &service,
+ DBUS_TYPE_OBJECT_PATH, &object_path,
DBUS_TYPE_STRING, &uuid,
DBUS_TYPE_INVALID)) {
LOGE("%s: Invalid arguments for Authorize() method", __FUNCTION__);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- LOGV("... address = %s", address);
- LOGV("... service = %s", service);
+ LOGV("... object_path = %s", object_path);
LOGV("... uuid = %s", uuid);
- bool auth_granted = env->CallBooleanMethod(nat->me,
- method_onAuthAgentAuthorize, env->NewStringUTF(address),
- env->NewStringUTF(service), env->NewStringUTF(uuid));
+ bool auth_granted =
+ env->CallBooleanMethod(nat->me, method_onAgentAuthorize,
+ env->NewStringUTF(object_path), env->NewStringUTF(uuid));
// reply
if (auth_granted) {
@@ -979,43 +846,22 @@ static DBusHandlerResult agent_event_filter(DBusConnection *conn,
}
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_method_call(msg,
- "org.bluez.AuthorizationAgent", "Cancel")) {
- const char *adapter;
- const char *address;
- const char *service;
- const char *uuid;
+ "org.bluez.Agent", "RequestPinCode")) {
+ char *object_path;
if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &adapter,
- DBUS_TYPE_STRING, &address,
- DBUS_TYPE_STRING, &service,
- DBUS_TYPE_STRING, &uuid,
+ DBUS_TYPE_OBJECT_PATH, &object_path,
DBUS_TYPE_INVALID)) {
- LOGE("%s: Invalid arguments for Cancel() method", __FUNCTION__);
+ LOGE("%s: Invalid arguments for RequestPinCode() method", __FUNCTION__);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- LOGV("... address = %s", address);
- LOGV("... service = %s", service);
- LOGV("... uuid = %s", uuid);
-
- env->CallVoidMethod(nat->me,
- method_onAuthAgentCancel, env->NewStringUTF(address),
- env->NewStringUTF(service), env->NewStringUTF(uuid));
-
- // reply
- DBusMessage *reply = dbus_message_new_method_return(msg);
- if (!reply) {
- LOGE("%s: Cannot create message reply\n", __FUNCTION__);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
- dbus_connection_send(nat->conn, reply, NULL);
- dbus_message_unref(reply);
+ dbus_message_ref(msg); // increment refcount because we pass to java
+ env->CallVoidMethod(nat->me, method_onRequestPinCode,
+ env->NewStringUTF(object_path),
+ int(msg));
return DBUS_HANDLER_RESULT_HANDLED;
-
} else if (dbus_message_is_method_call(msg,
- "org.bluez.AuthorizationAgent", "Release")) {
- LOGW("We are no longer the auth agent!");
-
+ "org.bluez.Agent", "Release")) {
// reply
DBusMessage *reply = dbus_message_new_method_return(msg);
if (!reply) {
@@ -1026,7 +872,7 @@ static DBusHandlerResult agent_event_filter(DBusConnection *conn,
dbus_message_unref(reply);
return DBUS_HANDLER_RESULT_HANDLED;
} else {
- LOGV("... ignored");
+ LOGV("%s:%s is ignored", dbus_message_get_interface(msg), dbus_message_get_member(msg));
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1044,7 +890,7 @@ static DBusHandlerResult agent_event_filter(DBusConnection *conn,
#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
-void onCreateBondingResult(DBusMessage *msg, void *user, void *n) {
+void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
LOGV(__FUNCTION__);
native_data_t *nat = (native_data_t *)n;
@@ -1095,7 +941,7 @@ void onCreateBondingResult(DBusMessage *msg, void *user, void *n) {
}
env->CallVoidMethod(nat->me,
- method_onCreateBondingResult,
+ method_onCreatePairedDeviceResult,
env->NewStringUTF(address),
result);
done:
@@ -1103,7 +949,7 @@ done:
free(user);
}
-void onGetRemoteServiceChannelResult(DBusMessage *msg, void *user, void *n) {
+void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
LOGV(__FUNCTION__);
const char *address = (const char *) user;
@@ -1122,14 +968,13 @@ void onGetRemoteServiceChannelResult(DBusMessage *msg, void *user, void *n) {
!dbus_message_get_args(msg, &err,
DBUS_TYPE_INT32, &channel,
DBUS_TYPE_INVALID)) {
- /* if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationFailed")) */
LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
dbus_error_free(&err);
}
done:
env->CallVoidMethod(nat->me,
- method_onGetRemoteServiceChannelResult,
+ method_onGetDeviceServiceChannelResult,
env->NewStringUTF(address),
channel);
free(user);
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index e8bffa4..1c9ee7d 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -50,8 +50,6 @@ pid_t gettid() { return syscall(__NR_gettid);}
#undef __KERNEL__
#endif
-#define ENABLE_CGROUP_ERR_LOGGING 0
-
/*
* List of cgroup names which map to ANDROID_TGROUP_ values in Thread.h
* and Process.java
@@ -198,31 +196,24 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name)
static int add_pid_to_cgroup(int pid, int grp)
{
- FILE *fp;
+ int fd;
char path[255];
- int rc;
-
- sprintf(path, "/dev/cpuctl/%s/tasks", (cgroup_names[grp] ? cgroup_names[grp] : ""));
+ char text[64];
- if (!(fp = fopen(path, "w"))) {
-#if ENABLE_CGROUP_ERR_LOGGING
- LOGW("Unable to open %s (%s)\n", path, strerror(errno));
-#endif
- return -errno;
- }
+ sprintf(path, "/dev/cpuctl/%s/tasks",
+ (cgroup_names[grp] ? cgroup_names[grp] : ""));
- rc = fprintf(fp, "%d", pid);
- fclose(fp);
+ if ((fd = open(path, O_WRONLY)) < 0)
+ return -1;
- if (rc < 0) {
-#if ENABLE_CGROUP_ERR_LOGGING
- LOGW("Unable to move pid %d to cgroup %s (%s)\n", pid,
- (cgroup_names[grp] ? cgroup_names[grp] : "<default>"),
- strerror(errno));
-#endif
+ sprintf(text, "%d", pid);
+ if (write(fd, text, strlen(text)) < 0) {
+ close(fd);
+ return -1;
}
- return (rc < 0) ? errno : 0;
+ close(fd);
+ return 0;
}
void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
@@ -232,8 +223,11 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint
return;
}
- if (add_pid_to_cgroup(pid, grp))
- signalExceptionForGroupError(env, clazz, errno);
+ if (add_pid_to_cgroup(pid, grp)) {
+ // If the thread exited on us, don't generate an exception
+ if (errno != ESRCH && errno != ENOENT)
+ signalExceptionForGroupError(env, clazz, errno);
+ }
}
void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
@@ -250,17 +244,23 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
sprintf(proc_path, "/proc/%d/task", pid);
if (!(d = opendir(proc_path))) {
- signalExceptionForGroupError(env, clazz, errno);
+ // If the process exited on us, don't generate an exception
+ if (errno != ENOENT)
+ signalExceptionForGroupError(env, clazz, errno);
return;
}
while ((de = readdir(d))) {
if (de->d_name[0] == '.')
continue;
+
if (add_pid_to_cgroup(atoi(de->d_name), grp)) {
- signalExceptionForGroupError(env, clazz, errno);
- closedir(d);
- return;
+ // If the thread exited on us, ignore it and keep going
+ if (errno != ESRCH && errno != ENOENT) {
+ signalExceptionForGroupError(env, clazz, errno);
+ closedir(d);
+ return;
+ }
}
}
closedir(d);
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index 15e3a81..89b1f96 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -45,9 +45,11 @@ static jclass OOMEClass;
static jclass UOEClass;
static jclass IAEClass;
static jclass AIOOBEClass;
+static jclass G11ImplClass;
static jmethodID getBasePointerID;
static jmethodID getBaseArrayID;
static jmethodID getBaseArrayOffsetID;
+static jmethodID allowIndirectBuffersID;
static jfieldID positionID;
static jfieldID limitID;
static jfieldID elementSizeShiftID;
@@ -63,13 +65,17 @@ nativeClassInitBuffer(JNIEnv *_env)
jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
+ jclass g11impClassLocal = _env->FindClass("com/google/android/gles_jni/GLImpl");
+ G11ImplClass = (jclass) _env->NewGlobalRef(g11impClassLocal);
+
getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
"getBasePointer", "(Ljava/nio/Buffer;)J");
getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
"getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
"getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
-
+ allowIndirectBuffersID = _env->GetStaticMethodID(g11impClassLocal,
+ "allowIndirectBuffers", "(Ljava/lang/String;)Z");
positionID = _env->GetFieldID(bufferClass, "position", "I");
limitID = _env->GetFieldID(bufferClass, "limit", "I");
elementSizeShiftID =
@@ -119,6 +125,9 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
*array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
getBaseArrayID, buffer);
+ if (*array == NULL) {
+ return (void*) NULL;
+ }
offset = _env->CallStaticIntMethod(nioAccessClass,
getBaseArrayOffsetID, buffer);
data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
@@ -133,17 +142,43 @@ releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
commit ? 0 : JNI_ABORT);
}
+extern "C" {
+extern char* __progname;
+}
+
+static bool
+allowIndirectBuffers(JNIEnv *_env) {
+ static jint sIndirectBufferCompatability;
+ if (sIndirectBufferCompatability == 0) {
+ jobject appName = _env->NewStringUTF(::__progname);
+ sIndirectBufferCompatability = _env->CallStaticBooleanMethod(G11ImplClass, allowIndirectBuffersID, appName) ? 2 : 1;
+ }
+ return sIndirectBufferCompatability == 2;
+}
+
static void *
getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
- char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (!buffer) {
+ return NULL;
+ }
+ void* buf = _env->GetDirectBufferAddress(buffer);
if (buf) {
jint position = _env->GetIntField(buffer, positionID);
jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
- buf += position << elementSizeShift;
+ buf = ((char*) buf) + (position << elementSizeShift);
} else {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ if (allowIndirectBuffers(_env)) {
+ jarray array = 0;
+ jint remaining;
+ buf = getPointer(_env, buffer, &array, &remaining);
+ if (array) {
+ releasePointer(_env, array, buf, 0);
+ }
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
}
- return (void*) buf;
+ return buf;
}
static int
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0498057..c1017d4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -738,13 +738,6 @@
android:description="@string/permdesc_statusBar"
android:protectionLevel="signatureOrSystem" />
- <!-- Allows an application to force any currently running process to be
- in the foreground. -->
- <permission android:name="android.permission.SET_PROCESS_FOREGROUND"
- android:label="@string/permlab_setProcessForeground"
- android:description="@string/permdesc_setProcessForeground"
- android:protectionLevel="signature" />
-
<!-- Allows an application to force a BACK operation on whatever is the
top activity. -->
<permission android:name="android.permission.FORCE_BACK"
@@ -752,19 +745,6 @@
android:description="@string/permdesc_forceBack"
android:protectionLevel="signature" />
- <!-- Allows an application to publish system-level services. Such services
- can only be published from processes that never go away, so this is
- not something that any normal application can do. -->
- <permission android:name="android.permission.ADD_SYSTEM_SERVICE"
- android:label="@string/permlab_addSystemService"
- android:description="@string/permdesc_addSystemService"
- android:protectionLevel="signature" />
-
- <permission android:name="android.permission.FOTA_UPDATE"
- android:label="@string/permlab_fotaUpdate"
- android:description="@string/permdesc_fotaUpdate"
- android:protectionLevel="signature" />
-
<!-- Allows an application to update device statistics. Not for
use by third party apps. -->
<permission android:name="android.permission.UPDATE_DEVICE_STATS"
diff --git a/tests/sketch/res/layout/overlaydemo.xml b/core/res/res/anim/slide_in_up.xml
index 4d5a657..bf471c3 100644
--- a/tests/sketch/res/layout/overlaydemo.xml
+++ b/core/res/res/anim/slide_in_up.xml
@@ -14,14 +14,10 @@
limitations under the License.
-->
-<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/overlay"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
+<translate
+ xmlns:android="http://schemas.android.com/apk/res/android"
- <ListView
- android:id="@+id/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
+ android:fromYDelta="100%p"
+ android:toYDelta="0"
-</android.gesture.GestureOverlayView>
+ android:duration="@android:integer/config_longAnimTime" />
diff --git a/tests/sketch/res/values/strings.xml b/core/res/res/anim/slide_out_down.xml
index 42f14da..9b8d5b7 100755..100644
--- a/tests/sketch/res/values/strings.xml
+++ b/core/res/res/anim/slide_out_down.xml
@@ -4,26 +4,20 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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>
- <string name="app_name">Gesture Demo</string>
- <string name="overlay_name">Overlay Demo</string>
- <string name="recognition_result">Recognition Result</string>
- <string name="clear">Clear</string>
- <string name="newgesture">Add</string>
- <string name="viewgesture">View</string>
- <string name="newgesture_dialog_ok">OK</string>
- <string name="newgesture_dialog_cancel">Cancel</string>
- <string name="newgesture_text_entry">Gesture Name</string>
- <string name="previous">Previous</string>
- <string name="remove">Remove</string>
- <string name="next">Next</string>
-</resources>
+
+<translate
+ xmlns:android="http://schemas.android.com/apk/res/android"
+
+ android:fromYDelta="0"
+ android:toYDelta="100%p"
+
+ android:duration="@android:integer/config_longAnimTime" />
diff --git a/core/res/res/raw/latin_lowercase b/core/res/res/raw/latin_lowercase
deleted file mode 100644
index 443d5f8..0000000
--- a/core/res/res/raw/latin_lowercase
+++ /dev/null
Binary files differ
diff --git a/core/res/res/values-ar-rEG/donottranslate-cldr.xml b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
index 1bbbdca..4826a41 100644
--- a/core/res/res/values-ar-rEG/donottranslate-cldr.xml
+++ b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">اليوم</string>
<string name="tomorrow">غدًا</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e‏/%-m‏/%Y</string>
<string name="numeric_date_format">d‏/M‏/yyyy</string>
+ <string name="numeric_date_template">"%s‏/%s‏/%s"</string>
<string name="month_day_year">%-e %B، %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
<string name="date_and_time">%-l:%M:%S %p %d‏/%m‏/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d‏/%m‏/%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s‏/%2$s - %8$s‏/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s، %3$s/‏%2$s - %6$s، %8$s/‏%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s‏/%2$s‏/%4$s - %8$s‏/%7$s‏/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s، %3$s‏/%2$s‏/%4$s - %6$s، %8$s‏/%7$s‏/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s، %3$s/‏%2$s/‏%4$s – %10$s %6$s، %8$s/‏%7$s/‏%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/‏%2$s – %10$s %8$s/‏%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s، %3$s-%2$s – %10$s %6$s، %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s‏/%2$s‏/%4$s – %10$s %8$s‏/%7$s‏/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s، %4$s – %10$s %8$s %7$s، %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s، %4$s – %10$s %8$s %7$s، %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s، %3$s %2$s %4$s – %10$s %6$s، %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s، %3$s %2$s %4$s – %10$s %6$s، %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s، %3$s %2$s %4$s – %6$s، %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s، %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s، %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s، %3$s %2$s - %6$s، %8$s %7$s، %9$s</string>
</resources>
diff --git a/core/res/res/values-bg-rBG/donottranslate-cldr.xml b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
index 608b3a7..010b974 100644
--- a/core/res/res/values-bg-rBG/donottranslate-cldr.xml
+++ b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
@@ -91,18 +91,56 @@
<string name="today">Днес</string>
<string name="tomorrow">Утре</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%d %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
<string name="month_year">%Y %B</string>
- <string name="abbrev_month_day">%b %-e</string>
+ <string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%3$s.%2$s, %1$s - %8$s.%7$s, %6$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%3$s.%2$s.%4$s, %1$s - %8$s.%7$s.%9$s, %6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s - %10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s, %1$s - %6$s %5$s, %4$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s, %1$s - %5$s, %4$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s, %2$s</string>
+ <string name="wday_date">%3$s, %2$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%3$s %2$s, %1$s - %8$s %7$s, %6$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s, %1$s - %10$s %8$s %7$s, %6$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s, %1$s - %10$s %8$s %7$s, %6$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%3$s %2$s, %1$s - %8$s %7$s, %6$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s %9$s, %1$s - %8$s %7$s y, %6$s</string>
</resources>
diff --git a/core/res/res/values-ca-rES/donottranslate-cldr.xml b/core/res/res/values-ca-rES/donottranslate-cldr.xml
index 6ed2a88..4eabba7 100644
--- a/core/res/res/values-ca-rES/donottranslate-cldr.xml
+++ b/core/res/res/values-ca-rES/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">avui</string>
<string name="tomorrow">demà</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e de %B de %Y</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %d/%m/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%m/%Y</string>
<string name="month_day">%-e de %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s/%2$s/%4$s - %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s - %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s - %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s de %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s de %2$s - %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s de %2$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s de %2$s - %6$s %8$s de %7$s de %9$s</string>
</resources>
diff --git a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
index f477d56..0670080 100644
--- a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
+++ b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Dnes</string>
<string name="tomorrow">Zítra</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %-e.%-m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e.%-m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-cs/donottranslate-cldr.xml b/core/res/res/values-cs/donottranslate-cldr.xml
index f477d56..0670080 100644
--- a/core/res/res/values-cs/donottranslate-cldr.xml
+++ b/core/res/res/values-cs/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Dnes</string>
<string name="tomorrow">Zítra</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %-e.%-m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e.%-m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c3860d4..7dbeaeb 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Umožňuje aplikaci změnit aktuální konfiguraci, např. národní prostředí či obecnou velikost písma."</string>
<string name="permlab_restartPackages">"restartování ostatních aplikací"</string>
<string name="permdesc_restartPackages">"Umožňuje aplikaci vynutit restartování jiných aplikací."</string>
- <string name="permlab_setProcessForeground">"zamezení zastavení aplikace"</string>
- <string name="permdesc_setProcessForeground">"Umožňuje aplikaci spustit jakýkoli proces v popředí tak, že ho nelze ukončit. Běžné aplikace by toto nastavení nikdy neměly používat."</string>
<string name="permlab_forceBack">"vynucení zavření aplikace"</string>
<string name="permdesc_forceBack">"Umožňuje aplikaci vynutit zavření a přesunutí libovolné činnosti v popředí na pozadí. Běžné aplikace by toto nastavení neměly nikdy využívat."</string>
<string name="permlab_dump">"načtení interního stavu systému"</string>
<string name="permdesc_dump">"Umožňuje aplikaci načíst interní stav systému. Škodlivé aplikace mohou načíst řádu soukromých a zabezpečených informací, které by nikdy neměly potřebovat."</string>
- <string name="permlab_addSystemService">"zveřejnění nízkoúrovňových služeb"</string>
- <string name="permdesc_addSystemService">"Umožňuje aplikaci zveřejnit své vlastní nízkoúrovňové systémové služby. Škodlivé aplikace mohou převzít kontrolu nad systémem a získat či poškodit jakákoli data v něm obsažená."</string>
<string name="permlab_runSetActivityWatcher">"sledování a řízení spouštění všech aplikací"</string>
<string name="permdesc_runSetActivityWatcher">"Umožňuje aplikaci sledovat a řídit spouštění činností systémem. Škodlivé aplikace mohou zcela ovládnout systém. Toto oprávnění je zapotřebí pouze pro účely vývoje, nikdy pro běžné použití telefonu."</string>
<string name="permlab_broadcastPackageRemoved">"odeslání vysílání o odstranění balíčku"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Umožňuje aplikaci řídit maximální počet spuštěných procesů. Běžné aplikace toto nastavení nikdy nevyužívají."</string>
<string name="permlab_setAlwaysFinish">"zavření všech aplikací na pozadí"</string>
<string name="permdesc_setAlwaysFinish">"Umožňuje aplikaci ovládat, zda jsou činnosti vždy dokončeny po přesunutí do pozadí. Běžné aplikace toto nastavení nikdy nevyužívají."</string>
- <string name="permlab_fotaUpdate">"automatická instalace aktualizací systému"</string>
- <string name="permdesc_fotaUpdate">"Umožňuje aplikaci přijímat oznámení o čekajících aktualizacích systému a spouštět jejich instalaci. Škodlivé aplikace mohou díky tomuto nastavení poškodit systém pomocí neoprávněných aktualizací nebo celkově narušovat proces aktualizace."</string>
<string name="permlab_batteryStats">"změna statistických údajů o baterii"</string>
<string name="permdesc_batteryStats">"Umožňuje změnu shromážděných statistických údajů o baterii. Není určeno pro běžné aplikace."</string>
<string name="permlab_internalSystemWindow">"zobrazení nepovolených oken"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Omlouváme se, ale toto video nelze přenášet datovým proudem do tohoto zařízení."</string>
<string name="VideoView_error_text_unknown">"Toto video bohužel nelze přehrát."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"poledne"</string>
<string name="Noon">"Poledne"</string>
<string name="midnight">"půlnoc"</string>
<string name="Midnight">"Půlnoc"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>."</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>. <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>. <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>., <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>., <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-da-rDK/donottranslate-cldr.xml b/core/res/res/values-da-rDK/donottranslate-cldr.xml
index 38097bd..4a2a656 100644
--- a/core/res/res/values-da-rDK/donottranslate-cldr.xml
+++ b/core/res/res/values-da-rDK/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">i dag</string>
<string name="tomorrow">i morgen</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H.%M</string>
+ <string name="hour_minute_ampm">%-l.%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l.%M %^p</string>
+ <string name="twelve_hour_time_format">h.mm a</string>
+ <string name="twenty_four_hour_time_format">HH.mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e. %b %Y</string>
<string name="time_of_day">%H.%M.%S</string>
<string name="date_and_time">%H.%M.%S %d/%m/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%m/%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%b</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s. %3$s-%2$s-%4$s - %10$s %6$s. %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s. %3$s-%2$s - %10$s %6$s. %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s den %2$s - %6$s %4$s den %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s den %2$s - %4$s den %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s den %3$s</string>
+ <string name="wday_date">%2$s den %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s. %3$s. %2$s %4$s - %10$s %6$s. %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s. %3$s. %2$s %4$s - %10$s %6$s. %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s. %3$s. %2$s %4$s - %6$s. %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s den %3$s. %2$s - %6$s den %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-de-rAT/donottranslate-cldr.xml b/core/res/res/values-de-rAT/donottranslate-cldr.xml
index ad35fee..e6112ba 100644
--- a/core/res/res/values-de-rAT/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rAT/donottranslate-cldr.xml
@@ -58,13 +58,19 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%d. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -72,4 +78,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-de-rCH/donottranslate-cldr.xml b/core/res/res/values-de-rCH/donottranslate-cldr.xml
index c8e0de8..b611c08 100644
--- a/core/res/res/values-de-rCH/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rCH/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-de-rDE/donottranslate-cldr.xml b/core/res/res/values-de-rDE/donottranslate-cldr.xml
index c8e0de8..b611c08 100644
--- a/core/res/res/values-de-rDE/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rDE/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-de-rLI/donottranslate-cldr.xml b/core/res/res/values-de-rLI/donottranslate-cldr.xml
index c8e0de8..b611c08 100644
--- a/core/res/res/values-de-rLI/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rLI/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml
index c8e0de8..b611c08 100644
--- a/core/res/res/values-de/donottranslate-cldr.xml
+++ b/core/res/res/values-de/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d121801..dfb4549 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Ermöglicht einer Anwendung, die aktuelle Konfiguration zu ändern, etwa das Gebietsschema oder die Schriftgröße."</string>
<string name="permlab_restartPackages">"Andere Anwendungen neu starten"</string>
<string name="permdesc_restartPackages">"Ermöglicht einer Anwendung, den Neustart anderer Anwendungen zu erzwingen."</string>
- <string name="permlab_setProcessForeground">"Beenden nicht zulassen"</string>
- <string name="permdesc_setProcessForeground">"Ermöglicht einer Anwendung, beliebige Prozesse im Vordergrund auszuführen, damit diese nicht beendet werden können. Sollte nicht für normale Anwendungen benötigt werden."</string>
<string name="permlab_forceBack">"Schließen von Anwendung erzwingen"</string>
<string name="permdesc_forceBack">"Ermöglicht einer Anwendung, alle Aktivitäten, die im Vordergrund ablaufen, zu beenden und in den Hintergrund zu schieben. Sollte nicht für normale Anwendungen benötigt werden."</string>
<string name="permlab_dump">"Systeminternen Status abrufen"</string>
<string name="permdesc_dump">"Ermöglicht einer Anwendung, den internen Status des Systems abzurufen. Schädliche Anwendungen rufen hierbei möglicherweise eine Vielzahl an privaten und geschützten Daten ab, die Sie in der Regel nicht benötigen würden."</string>
- <string name="permlab_addSystemService">"systemnahe Dienste veröffentlichen"</string>
- <string name="permdesc_addSystemService">"Ermöglicht der Anwendung, ihre eigenen systemnahen Dienste anzubieten. Schädliche Anwendungen könnten in das System eindringen und darin befindliche Daten stehlen oder manipulieren."</string>
<string name="permlab_runSetActivityWatcher">"Start von Anwendungen überwachen und steuern"</string>
<string name="permdesc_runSetActivityWatcher">"Ermöglicht der Anwendung, den Start von Systemaktivitäten zu überwachen und zu steuern. Schädliche Anwendungen können so das gesamte System beeinträchtigen. Diese Berechtigung wird nur zu Entwicklungszwecken und nie für die normale Telefonnutzung benötigt."</string>
<string name="permlab_broadcastPackageRemoved">"Broadcast ohne Paket senden"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Ermöglicht einer Anwendung, die maximale Anzahl an laufenden Prozessen zu steuern. Wird nicht für normale Anwendungen benötigt."</string>
<string name="permlab_setAlwaysFinish">"alle Anwendungen im Hintergrund schließen"</string>
<string name="permdesc_setAlwaysFinish">"Überlässt einer Anwendung die Entscheidung, ob Aktivitäten beendet werden, sobald Sie in den Hintergrund rücken. Wird nicht für normale Anwendungen benötigt."</string>
- <string name="permlab_fotaUpdate">"System-Updates automatisch installieren"</string>
- <string name="permdesc_fotaUpdate">"Ermöglicht einer Anwendung, Benachrichtigungen zu ausstehenden System-Updates zu erhalten und deren Installation einzuleiten. Schädliche Anwendungen können so das System durch nicht autorisierte Updates beschädigen oder in den Update-Prozess eingreifen."</string>
<string name="permlab_batteryStats">"Akku-Daten ändern"</string>
<string name="permdesc_batteryStats">"Ermöglicht die Änderung von gesammelten Akku-Daten. Nicht für normale Anwendungen vorgesehen."</string>
<string name="permlab_internalSystemWindow">"nicht autorisierte Fenster anzeigen"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Leider ist dieses Video nicht für Streaming auf diesem Gerät gültig."</string>
<string name="VideoView_error_text_unknown">"Dieses Video kann leider nicht abgespielt werden."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"Mittag"</string>
<string name="Noon">"Mittag"</string>
<string name="midnight">"Mitternacht"</string>
<string name="Midnight">"Mitternacht"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-el-rGR/donottranslate-cldr.xml b/core/res/res/values-el-rGR/donottranslate-cldr.xml
index 9d2a0aa..f76281a 100644
--- a/core/res/res/values-el-rGR/donottranslate-cldr.xml
+++ b/core/res/res/values-el-rGR/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Σήμερα</string>
<string name="tomorrow">Αύριο</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%d %B %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
<string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s/%2$s/%4$s - %10$s %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s/%2$s - %10$s %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s %2$s - %6$s, %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s - %10$s %6$s, %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s - %10$s %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s %2$s - %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rAU/donottranslate-cldr.xml b/core/res/res/values-en-rAU/donottranslate-cldr.xml
index 7ed029c..223a22b 100644
--- a/core/res/res/values-en-rAU/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rAU/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-e/%m/%Y</string>
<string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %d/%m/%Y</string>
+ <string name="date_and_time">%d/%m/%Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%d/%m/%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s - %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s - %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s - %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%3$s/%2$s/%4$s, %5$s - %8$s/%7$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index d482222..3de378b 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -314,10 +314,6 @@
<skip />
<!-- no translation found for permdesc_setAlwaysFinish (2437195869854312148) -->
<skip />
- <!-- no translation found for permlab_fotaUpdate (1813039882829307079) -->
- <skip />
- <!-- no translation found for permdesc_fotaUpdate (2544137712607584763) -->
- <skip />
<!-- no translation found for permlab_batteryStats (1598947993704535568) -->
<skip />
<!-- no translation found for permdesc_batteryStats (6247598531831307989) -->
@@ -864,23 +860,15 @@
<skip />
<!-- no translation found for numeric_date (5120078478872821100) -->
<!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) -->
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for numeric_date (5537215108967329745) -->
<skip />
<!-- no translation found for date1_time1_date2_time2 (3645498975775629615) -->
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for date1_date2 (377057563556488062) -->
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for time1_time2 (3173474242109288305) -->
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
<!-- no translation found for time_wday_date (8928955562064570313) -->
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for wday_date (8794741400546136975) -->
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_date (1922644512833014496) -->
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_wday (1422050241301754712) -->
<skip />
<!-- no translation found for full_date_month_first (6011143962222283357) -->
@@ -911,54 +899,30 @@
<!-- no translation found for date_and_time (9197690194373107109) -->
<skip />
<!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for date_and_time (353898423108629694) -->
<!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) -->
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) -->
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) -->
- <string name="same_year_md1_time1_md2_time2">" <xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) -->
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) -->
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) -->
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_md2 (8908376522875100300) -->
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) -->
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) -->
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) -->
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) -->
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) -->
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) -->
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) -->
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_md2 (2393563617438036111) -->
- <string name="same_month_md1_md2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) -->
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) -->
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g> <xliff:g id="YEAR2" example="2007">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) -->
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) -->
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) -->
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) -->
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
<!-- no translation found for abbrev_month_year (8058929633673942490) -->
<skip />
diff --git a/core/res/res/values-en-rCA/donottranslate-cldr.xml b/core/res/res/values-en-rCA/donottranslate-cldr.xml
index 2fb3ef6..32fa2b0 100644
--- a/core/res/res/values-en-rCA/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rCA/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%B %-e, %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %Y-%m-%d</string>
+ <string name="date_and_time">%Y-%m-%d, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%Y-%m-%d</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s - %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s - %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s - %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s - %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s - %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s - %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s - %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%4$s-%2$s-%3$s, %5$s - %9$s-%7$s-%8$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s - %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%2$s %3$s, %5$s - %7$s %8$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%2$s %3$s, %5$s - %7$s %8$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s - %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s - %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%2$s %3$s-%8$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%2$s %3$s - %7$s %8$s, %9$s</string>
+ <string name="same_month_mdy1_mdy2">%2$s %3$s-%8$s, %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s - %6$s, %7$s %8$s, %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rGB/donottranslate-cldr.xml b/core/res/res/values-en-rGB/donottranslate-cldr.xml
index 0c544af..b90112f 100644
--- a/core/res/res/values-en-rGB/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rGB/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
- <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_and_time">%-e %b %Y, %H:%M:%S</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s/%2$s/%4$s, %5$s - %6$s, %8$s/%7$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%3$s/%2$s, %5$s - %8$s/%7$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s/%2$s, %5$s - %6$s, %8$s/%7$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%3$s/%2$s/%4$s, %5$s - %8$s/%7$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s %3$s %2$s, %5$s - %6$s %8$s %7$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s %3$s %2$s, %5$s - %6$s %8$s %7$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rIE/donottranslate-cldr.xml b/core/res/res/values-en-rIE/donottranslate-cldr.xml
index 0c544af..4143da5 100644
--- a/core/res/res/values-en-rIE/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rIE/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
- <string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_and_time">%-e %b %Y, %H:%M:%S</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s/%2$s/%4$s, %5$s - %6$s, %8$s/%7$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%3$s/%2$s, %5$s - %8$s/%7$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s/%2$s, %5$s - %6$s, %8$s/%7$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%3$s/%2$s/%4$s, %5$s - %8$s/%7$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rIN/donottranslate-cldr.xml b/core/res/res/values-en-rIN/donottranslate-cldr.xml
index 823c3c1..6522d67 100644
--- a/core/res/res/values-en-rIN/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rIN/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %d-%b-%Y</string>
+ <string name="date_and_time">%d-%b-%Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%d-%b-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s - %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s - %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s - %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%3$s/%2$s/%4$s, %5$s - %8$s/%7$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rNZ/donottranslate-cldr.xml b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
index bcd976c..d29455a 100644
--- a/core/res/res/values-en-rNZ/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-e/%m/%Y</string>
<string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %-e/%m/%Y</string>
+ <string name="date_and_time">%-e/%m/%Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%-e/%m/%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s - %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%3$s/%2$s, %5$s - %8$s/%7$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s - %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%3$s/%2$s/%4$s, %5$s - %8$s/%7$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%3$s %2$s, %5$s - %8$s %7$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rSG/donottranslate-cldr.xml b/core/res/res/values-en-rSG/donottranslate-cldr.xml
index f305948..56c58e2 100644
--- a/core/res/res/values-en-rSG/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rSG/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-m/%-e/%Y</string>
<string name="numeric_date_format">M/d/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%B %-e, %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="date_and_time">%b %-e, %Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%b %-e, %Y</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s – %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s/%3$s – %6$s, %7$s/%8$s</string>
+ <string name="numeric_mdy1_mdy2">%2$s/%3$s/%4$s – %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %2$s/%3$s/%4$s – %6$s, %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s – %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s – %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s – %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%2$s/%3$s/%4$s, %5$s – %7$s/%8$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s – %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s – %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s – %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s – %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%2$s %3$s, %5$s – %7$s %8$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%2$s %3$s, %5$s – %7$s %8$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s – %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s – %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s – %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s – %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s – %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s – %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s – %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%2$s %3$s – %8$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s – %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%2$s %3$s – %7$s %8$s, %9$s</string>
+ <string name="same_month_mdy1_mdy2">%2$s %3$s – %8$s, %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s – %6$s, %7$s %8$s, %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rSG/strings.xml b/core/res/res/values-en-rSG/strings.xml
index 1c6eda2..2ec6b0b 100644
--- a/core/res/res/values-en-rSG/strings.xml
+++ b/core/res/res/values-en-rSG/strings.xml
@@ -314,10 +314,6 @@
<skip />
<!-- no translation found for permdesc_setAlwaysFinish (2437195869854312148) -->
<skip />
- <!-- no translation found for permlab_fotaUpdate (1813039882829307079) -->
- <skip />
- <!-- no translation found for permdesc_fotaUpdate (2544137712607584763) -->
- <skip />
<!-- no translation found for permlab_batteryStats (1598947993704535568) -->
<skip />
<!-- no translation found for permdesc_batteryStats (6247598531831307989) -->
@@ -862,24 +858,15 @@
<skip />
<!-- copied from values-de/strings.xml with the crazyness of the . removed-->
<!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) -->
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for numeric_date (5537215108967329745) -->
<!-- no translation found for date1_time1_date2_time2 (3645498975775629615) -->
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for date1_date2 (377057563556488062) -->
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for time1_time2 (3173474242109288305) -->
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
<!-- no translation found for time_wday_date (8928955562064570313) -->
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for wday_date (8794741400546136975) -->
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_date (1922644512833014496) -->
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_wday (1422050241301754712) -->
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<!-- no translation found for full_date_month_first (6011143962222283357) -->
<skip />
<!-- no translation found for full_date_day_first (8621594762705478189) -->
@@ -907,53 +894,30 @@
<!-- no translation found for time_of_day (8375993139317154157) -->
<!-- no translation found for date_and_time (9197690194373107109) -->
<!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) -->
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) -->
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) -->
<skip />
<!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) -->
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) -->
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) -->
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_md2 (8908376522875100300) -->
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) -->
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) -->
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) -->
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) -->
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) -->
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) -->
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) -->
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_md2 (2393563617438036111) -->
- <string name="same_month_md1_md2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) -->
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) -->
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g> <xliff:g id="YEAR2" example="2007">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) -->
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) -->
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) -->
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) -->
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
<!-- no translation found for abbrev_month_year (8058929633673942490) -->
<skip />
diff --git a/core/res/res/values-en-rUS/donottranslate-cldr.xml b/core/res/res/values-en-rUS/donottranslate-cldr.xml
index f305948..56c58e2 100644
--- a/core/res/res/values-en-rUS/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rUS/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-m/%-e/%Y</string>
<string name="numeric_date_format">M/d/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%B %-e, %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="date_and_time">%b %-e, %Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%b %-e, %Y</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s – %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s/%3$s – %6$s, %7$s/%8$s</string>
+ <string name="numeric_mdy1_mdy2">%2$s/%3$s/%4$s – %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %2$s/%3$s/%4$s – %6$s, %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s – %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s – %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s – %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%2$s/%3$s/%4$s, %5$s – %7$s/%8$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s – %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s – %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s – %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s – %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%2$s %3$s, %5$s – %7$s %8$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%2$s %3$s, %5$s – %7$s %8$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s – %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s – %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s – %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s – %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s – %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s – %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s – %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%2$s %3$s – %8$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s – %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%2$s %3$s – %7$s %8$s, %9$s</string>
+ <string name="same_month_mdy1_mdy2">%2$s %3$s – %8$s, %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s – %6$s, %7$s %8$s, %9$s</string>
</resources>
diff --git a/core/res/res/values-en-rUS/strings.xml b/core/res/res/values-en-rUS/strings.xml
index b9df983..05f30fc 100644
--- a/core/res/res/values-en-rUS/strings.xml
+++ b/core/res/res/values-en-rUS/strings.xml
@@ -314,10 +314,6 @@
<skip />
<!-- no translation found for permdesc_setAlwaysFinish (2437195869854312148) -->
<skip />
- <!-- no translation found for permlab_fotaUpdate (1813039882829307079) -->
- <skip />
- <!-- no translation found for permdesc_fotaUpdate (2544137712607584763) -->
- <skip />
<!-- no translation found for permlab_batteryStats (1598947993704535568) -->
<skip />
<!-- no translation found for permdesc_batteryStats (6247598531831307989) -->
diff --git a/core/res/res/values-en-rZA/donottranslate-cldr.xml b/core/res/res/values-en-rZA/donottranslate-cldr.xml
index 633c761..e1aac04 100644
--- a/core/res/res/values-en-rZA/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rZA/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%Y/%m/%d</string>
<string name="numeric_date_format">yyyy/MM/dd</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%d %B %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
+ <string name="date_and_time">%d %b %Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%d %b %Y</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s - %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %2$s/%3$s - %6$s %7$s/%8$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s/%2$s/%3$s - %9$s/%7$s/%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %4$s/%2$s/%3$s - %6$s %9$s/%7$s/%8$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s - %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s - %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s - %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%4$s/%2$s/%3$s, %5$s - %9$s/%7$s/%8$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s - %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s - %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s - %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%2$s %3$s, %5$s - %7$s %8$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%2$s %3$s, %5$s - %7$s %8$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s - %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%3$s %2$s %4$s, %5$s - %8$s %7$s %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s - %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s - %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s - %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-es-rES/donottranslate-cldr.xml b/core/res/res/values-es-rES/donottranslate-cldr.xml
index 967a639..b516291 100644
--- a/core/res/res/values-es-rES/donottranslate-cldr.xml
+++ b/core/res/res/values-es-rES/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">hoy</string>
<string name="tomorrow">mañana</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e de %B de %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%m/%Y</string>
<string name="month_day">%-e de %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s – %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s – %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s – %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s – %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s/%2$s/%4$s – %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s-%2$s – %10$s %6$s, %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s – %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s – %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s – %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s – %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s – %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-es-rUS/donottranslate-cldr.xml b/core/res/res/values-es-rUS/donottranslate-cldr.xml
index 8668fda..587a615 100644
--- a/core/res/res/values-es-rUS/donottranslate-cldr.xml
+++ b/core/res/res/values-es-rUS/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">hoy</string>
<string name="tomorrow">mañana</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
<string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-m/%-e/%Y</string>
<string name="numeric_date_format">M/d/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e de %B de %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
<string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%b %-e, %Y</string>
<string name="month_day">%-e de %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s a el %2$s</string>
+ <string name="date1_date2">%2$s a el %5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s - %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %2$s/%3$s - %6$s %7$s/%8$s</string>
+ <string name="numeric_mdy1_mdy2">%2$s/%3$s/%4$s - %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %2$s/%3$s/%4$s - %6$s %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s/%2$s/%4$s a el %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s/%3$s a el %10$s %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s-%2$s a el %10$s %6$s, %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %2$s/%3$s/%4$s a el %10$s %7$s/%8$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s a el %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s a el %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s a el %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s a el %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s a el %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s a el %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s a el %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s a el %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s a el %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s a el %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s a el %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s a el %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s a el %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s a el %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s de %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s a el %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s de %2$s al %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s de %2$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s de %2$s al %6$s %8$s de %7$s de %9$s</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6032321..84435aa 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -178,14 +178,10 @@
<string name="permdesc_changeConfiguration">"Admite una aplicación para cambiar la configuración actual, como el tamaño de fuente local o general."</string>
<string name="permlab_restartPackages">"reiniciar otras aplicaciones"</string>
<string name="permdesc_restartPackages">"Admite una aplicación que reinicia otras aplicaciones por la fuerza."</string>
- <string name="permlab_setProcessForeground">"impedir la detención"</string>
- <string name="permdesc_setProcessForeground">"Admite una aplicación que ejecuta cualquier tipo de proceso en primer plano, de manera que no se pueda suprimir. Se debe evitar utilizarlo en aplicaciones normales."</string>
<string name="permlab_forceBack">"provocar que la aplicación se acerque"</string>
<string name="permdesc_forceBack">"Admite una aplicación que provoca que cualquier actividad del fondo se acerque y vuelva a alejarse. Se debe evitar utilizarlo en aplicaciones normales."</string>
<string name="permlab_dump">"recuperar el estado interno del sistema"</string>
<string name="permdesc_dump">"Admite que la aplicación recupere el estado interno del sistema. Las aplicaciones maliciosas pueden recuperar una gran variedad de información privada y segura que normalmente nunca necesitaría."</string>
- <string name="permlab_addSystemService">"publicar servicios de bajo nivel"</string>
- <string name="permdesc_addSystemService">"Admite que la aplicación publique sus propios servicios del sistema de bajo nivel. Las aplicaciones maliciosas pueden apropiarse del sistema y robar o corromper cualquiera de sus datos."</string>
<string name="permlab_runSetActivityWatcher">"verificar y controlar todos los lanzamientos de actividades"</string>
<string name="permdesc_runSetActivityWatcher">"Admite una aplicación que verifica y controla el lanzamiento de actividades por parte del sistema. Las aplicaciones maliciosas pueden comprometer totalmente al sistema. Este permiso sólo es necesario para el desarrollo, nunca para el uso normal del teléfono."</string>
<string name="permlab_broadcastPackageRemoved">"enviar emisión de paquete eliminado"</string>
@@ -198,8 +194,6 @@
<string name="permdesc_setProcessLimit">"Admite una aplicación que controla la cantidad máxima de procesos que se ejecutarán. No se utiliza nunca en aplicaciones normales."</string>
<string name="permlab_setAlwaysFinish">"cerrar todas las aplicaciones del fondo"</string>
<string name="permdesc_setAlwaysFinish">"Admite una aplicación que controla si las actividades siempre finalizan cuando van al fondo. No se utiliza nunca en aplicaciones normales."</string>
- <string name="permlab_fotaUpdate">"instalar automáticamente las actualizaciones del sistema"</string>
- <string name="permdesc_fotaUpdate">"Admite una aplicación que recibe notificaciones sobre las actualizaciones pendientes del sistema y activa su instalación. Las aplicaciones maliciosas pueden utilizarlo para corromper el sistema con actualizaciones no autorizadas o, en general, para interferir en el proceso de actualización."</string>
<string name="permlab_batteryStats">"modificar la estadística de la batería"</string>
<string name="permdesc_batteryStats">"Admite la modificación de estadísticas recopiladas sobre la batería. Las aplicaciones normales no deben utilizarlo."</string>
<string name="permlab_internalSystemWindow">"mostrar ventanas no autorizadas"</string>
@@ -557,47 +551,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Lo sentimos, este video no es válido para las transmisiones a este dispositivo."</string>
<string name="VideoView_error_text_unknown">"Lo sentimos, no se puede reproducir este video."</string>
<string name="VideoView_error_button">"Aceptar"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"mediodía"</string>
<string name="Noon">"Mediodía"</string>
<string name="midnight">"medianoche"</string>
<string name="Midnight">"Medianoche"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-es/donottranslate-cldr.xml b/core/res/res/values-es/donottranslate-cldr.xml
index 967a639..b516291 100644
--- a/core/res/res/values-es/donottranslate-cldr.xml
+++ b/core/res/res/values-es/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">hoy</string>
<string name="tomorrow">mañana</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e de %B de %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%m/%Y</string>
<string name="month_day">%-e de %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s – %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s – %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s – %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s – %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s/%2$s/%4$s – %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s-%2$s – %10$s %6$s, %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s – %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s – %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s – %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s – %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s – %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index c55e0ed..920ac3e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Permite que una aplicación cambie la configuración actual como, por ejemplo, la configuración local o el tamaño de fuente general."</string>
<string name="permlab_restartPackages">"reiniciar otras aplicaciones"</string>
<string name="permdesc_restartPackages">"Permite que una aplicación reinicie de forma forzosa otras aplicaciones."</string>
- <string name="permlab_setProcessForeground">"impedir su interrupción"</string>
- <string name="permdesc_setProcessForeground">"Permite que una aplicación ejecute cualquier proceso en segundo plano, de forma que no se pueda interrumpir. No debería ser necesario nunca para las aplicaciones normales."</string>
<string name="permlab_forceBack">"forzar el cierre de la aplicación"</string>
<string name="permdesc_forceBack">"Permite que una aplicación fuerce a cualquier actividad en segundo plano a cerrarse y volver a la pantalla anterior. No debería ser necesario nunca para las aplicaciones normales."</string>
<string name="permlab_dump">"recuperar estado interno del sistema"</string>
<string name="permdesc_dump">"Permite que la aplicación recupere el estado interno del sistema. Las aplicaciones malintencionadas pueden recuperar una amplia variedad de información protegida y privada que normalmente no deberían necesitar."</string>
- <string name="permlab_addSystemService">"publicar servicios de nivel inferior"</string>
- <string name="permdesc_addSystemService">"Permite que la aplicación publique sus propios servicios de sistema de nivel inferior. Las aplicaciones malintencionadas pueden hacerse con el control del sistema, y robar o dañar los datos contenidos en él."</string>
<string name="permlab_runSetActivityWatcher">"supervisar y controlar la ejecución de todas las aplicaciones"</string>
<string name="permdesc_runSetActivityWatcher">"Permite que una aplicación supervise y controle la ejecución de las actividades por parte del sistema. Las aplicaciones malintencionadas pueden vulnerar la seguridad del sistema. Este permiso sólo es necesario para tareas de desarrollo, nunca para el uso habitual del teléfono."</string>
<string name="permlab_broadcastPackageRemoved">"enviar emisión eliminada de paquete"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Permite que una aplicación controle el número máximo de procesos que se ejecutarán. No es necesario nunca para las aplicaciones normales."</string>
<string name="permlab_setAlwaysFinish">"hacer que se cierren todas las aplicaciones en segundo plano"</string>
<string name="permdesc_setAlwaysFinish">"Permite que una aplicación controle si las actividades finalizan siempre en cuanto pasan a segundo plano. No es necesario nunca para las aplicaciones normales."</string>
- <string name="permlab_fotaUpdate">"instalar actualizaciones del sistema de forma automática"</string>
- <string name="permdesc_fotaUpdate">"Permite que una aplicación reciba notificaciones sobre actualizaciones pendientes del sistema e inicie su instalación. Las aplicaciones malintencionadas pueden utilizar este permiso para provocar daños en el sistema con actualizaciones no autorizadas o interferir de forma general en el proceso de actualización."</string>
<string name="permlab_batteryStats">"modificar estadísticas de la batería"</string>
<string name="permdesc_batteryStats">"Permite la modificación de estadísticas recopiladas sobre la batería. No está destinado al uso por parte de aplicaciones normales."</string>
<string name="permlab_internalSystemWindow">"mostrar ventanas no autorizadas"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Este vídeo no se puede transmitir al dispositivo."</string>
<string name="VideoView_error_text_unknown">"Este vídeo no se puede reproducir."</string>
<string name="VideoView_error_button">"Aceptar"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"mediodía"</string>
<string name="Noon">"Mediodía"</string>
<string name="midnight">"medianoche"</string>
<string name="Midnight">"Medianoche"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> de <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> de <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> de <xliff:g id="MONTH1">%2$s</xliff:g> de <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> de <xliff:g id="MONTH2">%7$s</xliff:g> de <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> de <xliff:g id="MONTH1">%2$s</xliff:g> de <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> de <xliff:g id="MONTH2">%7$s</xliff:g> de <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-fi-rFI/donottranslate-cldr.xml b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
index ae28635..40cda53 100644
--- a/core/res/res/values-fi-rFI/donottranslate-cldr.xml
+++ b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">tänään</string>
<string name="tomorrow">huomenna</string>
- <string name="hour_minute_ampm">%-k.%M</string>
- <string name="hour_minute_cap_ampm">%-k.%M</string>
+ <string name="hour_minute_24">%-k.%M</string>
+ <string name="hour_minute_ampm">%-l.%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l.%M %^p</string>
+ <string name="twelve_hour_time_format">h.mm a</string>
+ <string name="twenty_four_hour_time_format">H.mm</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%-k.%M.%S</string>
<string name="date_and_time">%-k.%M.%S %-e.%-m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e.%-m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%-b %Y</string>
+ <string name="time1_time2">%1$s–%2$s</string>
+ <string name="date1_date2">%2$s–%5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s.–%8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s.%2$s. – %6$s %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s–%8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s.%2$s.%4$s – %6$s %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s.%2$s.%4$s–%10$s %6$s %8$s.%7$s.%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s.–%10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s.%2$s.–%10$s %6$s %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s–%10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s–%6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s–%4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s–%6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s–%8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s–%6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s–%10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s–%10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s–%10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s–%10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s–%10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s–%10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s. %2$s %4$s–%10$s %6$s %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s. %2$s %4$s–%10$s %6$s %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s %4$s–%6$s %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.–%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s–%6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s – %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.–%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s – %6$s %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-fr-rBE/donottranslate-cldr.xml b/core/res/res/values-fr-rBE/donottranslate-cldr.xml
index b540336..0795cc5 100644
--- a/core/res/res/values-fr-rBE/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rBE/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e/%m/%Y</string>
<string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">du %1$s au %2$s</string>
+ <string name="date1_date2">du %2$s au %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">du %5$s %1$s %3$s/%2$s/%4$s au %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">du %5$s %3$s/%2$s au %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">du %5$s %1$s %3$s/%2$s au %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">du %5$s %3$s/%2$s/%4$s au %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">du %3$s %1$s %2$s au %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">du %1$s %2$s au %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">du %3$s %2$s au %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">du %3$s %2$s au %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">du %1$s %3$s %2$s au %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">du %5$s %3$s %2$s au %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">du %5$s %3$s %2$s au %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">du %5$s %1$s %3$s %2$s au %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">du %5$s %1$s %3$s %2$s au %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">du %5$s %3$s %2$s %4$s au %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">du %5$s %3$s %2$s %4$s au %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">du %5$s %1$s %3$s %2$s %4$s au %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">du %5$s %1$s %3$s %2$s %4$s au %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">du %1$s %3$s %2$s %4$s au %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">du %1$s %3$s %2$s au %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s au %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s au %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/donottranslate-cldr.xml b/core/res/res/values-fr-rCA/donottranslate-cldr.xml
index 5fa5d54..7802ee0 100644
--- a/core/res/res/values-fr-rCA/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rCA/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %Y-%m-%d</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y-%m-%d</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %2$s-%3$s – %6$s %7$s-%8$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">du %1$s %4$s-%2$s-%3$s au %6$s %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %4$s-%2$s-%3$s – %10$s %6$s %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s – %10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s-%3$s – %10$s %6$s %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s – %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">du %3$s %2$s au %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">du %1$s %3$s %2$s au %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-fr-rCH/donottranslate-cldr.xml b/core/res/res/values-fr-rCH/donottranslate-cldr.xml
index 589c801..bbda44a 100644
--- a/core/res/res/values-fr-rCH/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rCH/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">du %1$s au %2$s</string>
+ <string name="date1_date2">du %2$s au %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">du %5$s %1$s %3$s/%2$s/%4$s au %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">du %5$s %3$s/%2$s au %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">du %5$s %1$s %3$s/%2$s au %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">du %5$s %3$s.%2$s.%4$s au %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">du %3$s %1$s %2$s au %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">du %1$s %2$s au %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">du %3$s %2$s au %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">du %3$s %2$s au %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">du %1$s %3$s %2$s au %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">du %5$s %3$s %2$s au %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">du %5$s %3$s %2$s au %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">du %5$s %1$s %3$s %2$s au %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">du %5$s %1$s %3$s %2$s au %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">du %5$s %3$s %2$s %4$s au %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">du %5$s %3$s %2$s %4$s au %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">du %5$s %1$s %3$s %2$s %4$s au %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">du %5$s %1$s %3$s %2$s %4$s au %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">du %1$s %3$s %2$s %4$s au %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">du %1$s %3$s %2$s au %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s au %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s au %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-fr-rFR/donottranslate-cldr.xml b/core/res/res/values-fr-rFR/donottranslate-cldr.xml
index 1213ed8..76d4141 100644
--- a/core/res/res/values-fr-rFR/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rFR/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s – %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s – %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s/%2$s/%4$s – %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s – %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s – %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s – %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-fr/donottranslate-cldr.xml b/core/res/res/values-fr/donottranslate-cldr.xml
index 1213ed8..76d4141 100644
--- a/core/res/res/values-fr/donottranslate-cldr.xml
+++ b/core/res/res/values-fr/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s – %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s – %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s/%2$s/%4$s – %10$s %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s – %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s – %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s – %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 736caf7..ce650c1 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -21,6 +21,7 @@
<string name="gigabyteShort">"Go"</string>
<string name="terabyteShort">"To"</string>
<string name="petabyteShort">"Po"</string>
+ <string name="fileSizeSuffix"><xliff:g id="number" example="123">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g></string>
<string name="untitled">"&lt;sans titre&gt;"</string>
<string name="ellipsis">"…"</string>
<string name="emptyPhoneNumber">"(Aucun numéro de téléphone)"</string>
@@ -161,14 +162,10 @@
<string name="permdesc_changeConfiguration">"Permet à une application de modifier la configuration actuelle (par ex. : la taille de la police générale ou des paramètres régionaux)."</string>
<string name="permlab_restartPackages">"Démarrage d\'autres applications"</string>
<string name="permdesc_restartPackages">"Permet à une application de forcer le lancement d\'autres applications."</string>
- <string name="permlab_setProcessForeground">"Non-possibilité d\'interruption"</string>
- <string name="permdesc_setProcessForeground">"Permet à une application d\'exécuter tout processus au premier plan afin qu\'il ne puisse pas être interrompu. Les applications normales ne devraient jamais nécessiter cette fonctionnalité."</string>
<string name="permlab_forceBack">"Fermeture forcée de l\'application"</string>
<string name="permdesc_forceBack">"Permet à une application de forcer une autre application exécutée au premier plan à se fermer et à passer en arrière-plan. Les applications normales ne devraient jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_dump">"Vérification de l\'état interne du système"</string>
<string name="permdesc_dump">"Permet à l\'application de récupérer l\'état interne du système. Des applications malveillantes peuvent obtenir de nombreuses informations personnelles et sécurisées auxquelles elles ne devraient pas avoir accès."</string>
- <string name="permlab_addSystemService">"Éditer des services à faible niveau"</string>
- <string name="permdesc_addSystemService">"Permet à l\'application de publier ses propres services de système de niveau inférieur. Des applications malveillantes peuvent prendre le contrôle du système et subtiliser ou endommager ses données."</string>
<string name="permlab_runSetActivityWatcher">"Contrôle du lancement des applications"</string>
<string name="permdesc_runSetActivityWatcher">"Permet à une application de suivre et de contrôler la façon dont le système lance des activités. Des applications malveillantes peuvent entièrement déstabiliser le système. Cette autorisation est uniquement nécessaire au développement et non pour l\'utilisation normale du téléphone."</string>
<string name="permlab_broadcastPackageRemoved">"Envoyer une diffusion sans paquet"</string>
@@ -181,8 +178,6 @@
<string name="permdesc_setProcessLimit">"Permet à une application de contrôler le nombre de processus maximal exécutés en même temps. Les applications normales n\'ont jamais recours à cette fonctionnalité."</string>
<string name="permlab_setAlwaysFinish">"Fermeture de toutes les applications en tâche de fond"</string>
<string name="permdesc_setAlwaysFinish">"Permet à une application de vérifier si des activités sont systématiquement interrompues lorsqu\'elles sont placées en tâche de fond. Cette fonctionnalité n\'est jamais utilisée par les applications normales."</string>
- <string name="permlab_fotaUpdate">"Installation des mises à jour du système"</string>
- <string name="permdesc_fotaUpdate">"Permet à une application de recevoir des notifications sur des mises à jour système en cours et de lancer leur installation. Des applications malveillantes peuvent utiliser cette fonctionnalité pour endommager le système avec des mises à jour non autorisées ou interférer avec le processus de mise à jour."</string>
<string name="permlab_batteryStats">"Modification des statistiques de la batterie"</string>
<string name="permdesc_batteryStats">"Autoriser la modification des statistiques de la batterie. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
<string name="permlab_internalSystemWindow">"Affichage de fenêtres non autorisées"</string>
@@ -539,47 +534,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Désolé, cette vidéo ne peut être lue sur cet appareil."</string>
<string name="VideoView_error_text_unknown">"Désolé, impossible de lire cette vidéo."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"midi"</string>
<string name="Noon">"Midi"</string>
<string name="midnight">"minuit"</string>
<string name="Midnight">"Minuit"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-he-rIL/donottranslate-cldr.xml b/core/res/res/values-he-rIL/donottranslate-cldr.xml
index 1b1aafa..1c8a6f7 100644
--- a/core/res/res/values-he-rIL/donottranslate-cldr.xml
+++ b/core/res/res/values-he-rIL/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">היום</string>
<string name="tomorrow">מחר</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e ב%B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e.%-m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e.%-m.%Y</string>
<string name="month_day">%-e ב%B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s.%2$s.%4$s – %10$s %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s ב%2$s – %8$s ב%7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s ב%2$s – %10$s %8$s ב%7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s ב%2$s – %10$s %8$s ב%7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s – %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-hi-rIN/donottranslate-cldr.xml b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
index 8c6a34f7..ba4ded7 100644
--- a/core/res/res/values-hi-rIN/donottranslate-cldr.xml
+++ b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
<string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e-%-m-%Y</string>
<string name="numeric_date_format">d-M-yyyy</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
<string name="date_and_time">%-l:%M:%S %p %d-%m-%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d-%m-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s/%2$s – %10$s %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s-%2$s-%4$s – %10$s %8$s-%7$s-%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s – %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s – %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s %2$s – %6$s, %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s – %10$s %6$s, %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s – %10$s %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s – %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%2$s-%3$s – %8$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s %2$s – %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s-%2$s-%3$s – %7$s-%8$s</string>
+ <string name="same_month_mdy1_mdy2">%9$s-%2$s-%3$s – %8$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string>
</resources>
diff --git a/core/res/res/values-hu-rHU/donottranslate-cldr.xml b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
index 6085c6f..8dcb426 100644
--- a/core/res/res/values-hu-rHU/donottranslate-cldr.xml
+++ b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">ma</string>
<string name="tomorrow">holnap</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%Y.%m.%d.</string>
<string name="numeric_date_format">yyyy.MM.dd.</string>
+ <string name="numeric_date_template">"%s.%s.%s."</string>
<string name="month_day_year">%Y. %B %-e.</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %Y.%m.%d.</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y.%m.%d.</string>
<string name="month_day">%B %-e.</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e.</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%2$s.%3$s. - %7$s.%8$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s.%3$s., %1$s - %7$s.%8$s., %6$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s.%2$s.%3$s. - %9$s.%7$s.%8$s.</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s.%2$s.%3$s., %1$s - %9$s.%7$s.%8$s., %6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s. %3$s. - %10$s %7$s. %8$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s. %3$s., %1$s - %10$s %7$s. %8$s., %6$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s.%2$s.%3$s. - %10$s %9$s.%7$s.%8$s.</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s, %1$s - %6$s %5$s, %4$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s, %1$s - %5$s, %4$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s, %2$s</string>
+ <string name="wday_date">%3$s, %2$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s. - %7$s %8$s.</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s. - %10$s %7$s %8$s.</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s. - %10$s %7$s %8$s.</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s. %2$s %3$s. - %10$s %9$s. %7$s %8$s.</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s. %2$s %3$s. - %10$s %9$s. %7$s %8$s.</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%2$s %3$s-%8$s.</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s. %2$s %3$s. - %7$s %8$s.</string>
+ <string name="same_month_mdy1_mdy2">%9$s. %2$s %3$s-%8$s.</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s. %2$s %3$s., %1$s - %7$s %8$s., %6$s</string>
</resources>
diff --git a/core/res/res/values-id-rID/donottranslate-cldr.xml b/core/res/res/values-id-rID/donottranslate-cldr.xml
index 0a15fed..feac981 100644
--- a/core/res/res/values-id-rID/donottranslate-cldr.xml
+++ b/core/res/res/values-id-rID/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s – %10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s – %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%2$s-%3$s – %8$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s-%2$s-%3$s – %7$s-%8$s</string>
+ <string name="same_month_mdy1_mdy2">%9$s-%2$s-%3$s – %8$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string>
</resources>
diff --git a/core/res/res/values-it-rCH/donottranslate-cldr.xml b/core/res/res/values-it-rCH/donottranslate-cldr.xml
index 4129d6c..6b76f8e 100644
--- a/core/res/res/values-it-rCH/donottranslate-cldr.xml
+++ b/core/res/res/values-it-rCH/donottranslate-cldr.xml
@@ -86,13 +86,19 @@
<string name="today">oggi</string>
<string name="tomorrow">domani</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H.%M.%S</string>
<string name="date_and_time">%H.%M.%S %-e-%b-%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e-%b-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -100,4 +106,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s-%2$s-%4$s - %10$s %6$s, %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s - %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-it-rIT/donottranslate-cldr.xml b/core/res/res/values-it-rIT/donottranslate-cldr.xml
index e3dd747..929f899 100644
--- a/core/res/res/values-it-rIT/donottranslate-cldr.xml
+++ b/core/res/res/values-it-rIT/donottranslate-cldr.xml
@@ -86,13 +86,19 @@
<string name="today">oggi</string>
<string name="tomorrow">domani</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%d %B %Y</string>
<string name="time_of_day">%H.%M.%S</string>
<string name="date_and_time">%H.%M.%S %d/%b/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%b/%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -100,4 +106,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s-%2$s-%4$s - %10$s %6$s, %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s - %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-it/donottranslate-cldr.xml b/core/res/res/values-it/donottranslate-cldr.xml
index e3dd747..929f899 100644
--- a/core/res/res/values-it/donottranslate-cldr.xml
+++ b/core/res/res/values-it/donottranslate-cldr.xml
@@ -86,13 +86,19 @@
<string name="today">oggi</string>
<string name="tomorrow">domani</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%d %B %Y</string>
<string name="time_of_day">%H.%M.%S</string>
<string name="date_and_time">%H.%M.%S %d/%b/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%b/%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -100,4 +106,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s-%2$s-%4$s - %10$s %6$s, %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s - %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index cb040f2..5bfbc49 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Consente a un\'applicazione di modificare la configurazione corrente, come le dimensioni dei caratteri locali o complessive."</string>
<string name="permlab_restartPackages">"riavvio altre applicazioni"</string>
<string name="permdesc_restartPackages">"Consente a un\'applicazione di riavviare forzatamente altre applicazioni."</string>
- <string name="permlab_setProcessForeground">"impedire l\'interruzione"</string>
- <string name="permdesc_setProcessForeground">"Consente a un\'applicazione di eseguire i processi in primo piano in modo che non possano essere interrotti. Non dovrebbe essere mai necessario per le normali applicazioni."</string>
<string name="permlab_forceBack">"chiusura forzata dell\'applicazione"</string>
<string name="permdesc_forceBack">"Consente a un\'applicazione di forzare la chiusura di attività in primo piano. Non dovrebbe essere mai necessario per le normali applicazioni."</string>
<string name="permlab_dump">"recupero stato interno del sistema"</string>
<string name="permdesc_dump">"Consente all\'applicazione di recuperare lo stato interno del sistema. Le applicazioni dannose potrebbero recuperare molte informazioni riservate e protette di cui non dovrebbero avere mai bisogno."</string>
- <string name="permlab_addSystemService">"pubblicaz. servizi di basso livello"</string>
- <string name="permdesc_addSystemService">"Consente a un\'applicazione di pubblicare i suoi servizi di sistema di basso livello. Le applicazioni dannose potrebbero assumere il controllo del sistema e impossessarsi di dati o danneggiarli."</string>
<string name="permlab_runSetActivityWatcher">"monitoraggio e controllo avvio applicazioni"</string>
<string name="permdesc_runSetActivityWatcher">"Consente a un\'applicazione di monitorare e controllare la modalità di avvio delle attività nel sistema. Le applicazioni dannose potrebbero compromettere totalmente il sistema. Questa autorizzazione è necessaria soltanto per lo sviluppo, mai per il normale utilizzo del telefono."</string>
<string name="permlab_broadcastPackageRemoved">"invio broadcast rimossi dal pacchetto"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Consente a un\'applicazione di stabilire il numero massimo di processi in esecuzione. Mai necessario per le normali applicazioni."</string>
<string name="permlab_setAlwaysFinish">"chiusura applicazioni in background"</string>
<string name="permdesc_setAlwaysFinish">"Consente a un\'applicazione di controllare se le attività sono sempre completate quando vengono messe in secondo piano. Mai necessario per le normali applicazioni."</string>
- <string name="permlab_fotaUpdate">"installazione autom. aggiornamenti di sistema"</string>
- <string name="permdesc_fotaUpdate">"Consente a un\'applicazione di ricevere notifiche sugli aggiornamenti del sistema in sospeso e di attivarne l\'installazione. Le applicazioni dannose possono sfruttare questa possibilità per danneggiare il sistema con aggiornamenti non autorizzati, o interferire con il processo di aggiornamento."</string>
<string name="permlab_batteryStats">"modifica statistiche batteria"</string>
<string name="permdesc_batteryStats">"Consente la modifica delle statistiche sulla batteria raccolte. Da non usare per normali applicazioni."</string>
<string name="permlab_internalSystemWindow">"visualizzazione finestre non autorizzate"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Spiacenti, questo video non è valido per lo streaming su questo dispositivo."</string>
<string name="VideoView_error_text_unknown">"Spiacenti. Impossibile riprodurre il video."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"mezzogiorno"</string>
<string name="Noon">"Mezzogiorno"</string>
<string name="midnight">"mezzanotte"</string>
<string name="Midnight">"Mezzanotte"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-ja-rJP/donottranslate-cldr.xml b/core/res/res/values-ja-rJP/donottranslate-cldr.xml
index b8e94fc..ae07433 100644
--- a/core/res/res/values-ja-rJP/donottranslate-cldr.xml
+++ b/core/res/res/values-ja-rJP/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">今日</string>
<string name="tomorrow">明日</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
+ <string name="twelve_hour_time_format">ah:mm</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y/%m/%d</string>
<string name="numeric_date_format">yyyy/MM/dd</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %Y/%m/%d</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y/%m/%d</string>
<string name="month_day">%-m月%-e日</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-m月%-e日</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y年%-m月</string>
+ <string name="time1_time2">%1$s~%2$s</string>
+ <string name="date1_date2">%2$s~%5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s~%7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s/%3$s(%1$s)~%7$s/%8$s(%6$s)</string>
+ <string name="numeric_mdy1_mdy2">%4$s/%2$s/%3$s~%9$s/%7$s/%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s/%2$s/%3$s(%1$s)~%9$s/%7$s/%8$s(%6$s)</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s/%2$s/%3$s(%1$s)~%10$s %9$s/%7$s/%8$s(%6$s)</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s/%3$s~%10$s %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s/%3$s(%1$s)~%10$s %7$s/%8$s(%6$s)</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s/%2$s/%3$s~%10$s %9$s/%7$s/%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s(%1$s)~%6$s %5$s(%4$s)</string>
+ <string name="wday1_date1_wday2_date2">%2$s(%1$s)~%5$s(%4$s)</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s~%6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s(%2$s)</string>
+ <string name="wday_date">%3$s(%2$s)</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s%3$s日~%7$s%8$s日</string>
+ <string name="same_year_wday1_md1_wday2_md2">%2$s%3$s日(%1$s)~%7$s%8$s日(%6$s)</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s%3$s日~%10$s %7$s%8$s日</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s%3$s日~%10$s %7$s%8$s日</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日(%1$s)~%10$s %7$s%8$s日(%6$s)</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日(%1$s)~%10$s %7$s%8$s日(%6$s)</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日~%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日~%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日(%1$s)~%10$s %9$s年%7$s%8$s日(%6$s)</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日(%1$s)~%10$s %9$s年%7$s%8$s日(%6$s)</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%4$s年%2$s%3$s日(%1$s)~%9$s年%7$s%8$s日(%6$s)</string>
+ <string name="same_month_md1_md2">%2$s月%3$s日~%8$s日</string>
+ <string name="same_month_wday1_md1_wday2_md2">%2$s%3$s日(%1$s)~%7$s%8$s日(%6$s)</string>
+ <string name="same_year_mdy1_mdy2">%9$s年%2$s%3$s日~%7$s月%8$s日</string>
+ <string name="same_month_mdy1_mdy2">%9$s年%2$s%3$s日~%8$s日</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s年%2$s%3$s日(%1$s)~%7$s月%8$s日(%6$s)</string>
</resources>
diff --git a/core/res/res/values-ja/donottranslate-cldr.xml b/core/res/res/values-ja/donottranslate-cldr.xml
index b8e94fc..ae07433 100644
--- a/core/res/res/values-ja/donottranslate-cldr.xml
+++ b/core/res/res/values-ja/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">今日</string>
<string name="tomorrow">明日</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
+ <string name="twelve_hour_time_format">ah:mm</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y/%m/%d</string>
<string name="numeric_date_format">yyyy/MM/dd</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %Y/%m/%d</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y/%m/%d</string>
<string name="month_day">%-m月%-e日</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-m月%-e日</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y年%-m月</string>
+ <string name="time1_time2">%1$s~%2$s</string>
+ <string name="date1_date2">%2$s~%5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s~%7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s/%3$s(%1$s)~%7$s/%8$s(%6$s)</string>
+ <string name="numeric_mdy1_mdy2">%4$s/%2$s/%3$s~%9$s/%7$s/%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s/%2$s/%3$s(%1$s)~%9$s/%7$s/%8$s(%6$s)</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s/%2$s/%3$s(%1$s)~%10$s %9$s/%7$s/%8$s(%6$s)</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s/%3$s~%10$s %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s/%3$s(%1$s)~%10$s %7$s/%8$s(%6$s)</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s/%2$s/%3$s~%10$s %9$s/%7$s/%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s(%1$s)~%6$s %5$s(%4$s)</string>
+ <string name="wday1_date1_wday2_date2">%2$s(%1$s)~%5$s(%4$s)</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s~%6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s(%2$s)</string>
+ <string name="wday_date">%3$s(%2$s)</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s%3$s日~%7$s%8$s日</string>
+ <string name="same_year_wday1_md1_wday2_md2">%2$s%3$s日(%1$s)~%7$s%8$s日(%6$s)</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s%3$s日~%10$s %7$s%8$s日</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s%3$s日~%10$s %7$s%8$s日</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日(%1$s)~%10$s %7$s%8$s日(%6$s)</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日(%1$s)~%10$s %7$s%8$s日(%6$s)</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日~%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日~%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日(%1$s)~%10$s %9$s年%7$s%8$s日(%6$s)</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日(%1$s)~%10$s %9$s年%7$s%8$s日(%6$s)</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%4$s年%2$s%3$s日(%1$s)~%9$s年%7$s%8$s日(%6$s)</string>
+ <string name="same_month_md1_md2">%2$s月%3$s日~%8$s日</string>
+ <string name="same_month_wday1_md1_wday2_md2">%2$s%3$s日(%1$s)~%7$s%8$s日(%6$s)</string>
+ <string name="same_year_mdy1_mdy2">%9$s年%2$s%3$s日~%7$s月%8$s日</string>
+ <string name="same_month_mdy1_mdy2">%9$s年%2$s%3$s日~%8$s日</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s年%2$s%3$s日(%1$s)~%7$s月%8$s日(%6$s)</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 877ecbd..a2e3e51 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"地域/言語やフォントのサイズなど、現在の設定の変更をアプリケーションに許可します。"</string>
<string name="permlab_restartPackages">"他のアプリケーションの再起動"</string>
<string name="permdesc_restartPackages">"他のアプリケーションの強制的な再起動をアプリケーションに許可します。"</string>
- <string name="permlab_setProcessForeground">"停止の阻止"</string>
- <string name="permdesc_setProcessForeground">"フォアグラウンドでプロセスを実行して、強制終了できないようにすることをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_forceBack">"アプリケーションの強制終了"</string>
<string name="permdesc_forceBack">"フォアグラウンドで実行されている操作を強制終了して戻ることをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_dump">"システムの内部状態の取得"</string>
<string name="permdesc_dump">"システムの内部状態の取得をアプリケーションに許可します。悪意のあるアプリケーションが、通常は必要としない広範囲にわたる非公開の機密情報を取得する恐れがあります。"</string>
- <string name="permlab_addSystemService">"低レベルサービスの公開"</string>
- <string name="permdesc_addSystemService">"独自の低レベルのシステムサービスを公開することをアプリケーションに許可します。悪意のあるアプリケーションがシステムを乗っ取って、データの盗用や破壊をする恐れがあります。"</string>
<string name="permlab_runSetActivityWatcher">"起動中のすべてのアプリケーションの監視と制御"</string>
<string name="permdesc_runSetActivityWatcher">"システムが起動する操作の監視と制御をアプリケーションに許可します。悪意のあるアプリケーションがシステムを完全に破壊する恐れがあります。この許可は開発にのみ必要で、携帯電話の通常の使用にはまったく必要ありません。"</string>
<string name="permlab_broadcastPackageRemoved">"パッケージ削除ブロードキャストの送信"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"実行するプロセス数の上限の制御をアプリケーションに許可します。通常のアプリケーションにはまったく必要ありません。"</string>
<string name="permlab_setAlwaysFinish">"バックグラウンドアプリケーションをすべて終了する"</string>
<string name="permdesc_setAlwaysFinish">"バックグラウンドになり次第必ず操作を終了させるかどうかの制御をアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
- <string name="permlab_fotaUpdate">"システムアップデートの自動インストール"</string>
- <string name="permdesc_fotaUpdate">"保留中のシステムアップデートに関する通知の受信とインストールの開始をアプリケーションに許可します。悪意のあるアプリケーションが許可なく更新を行ってシステムを破壊したり、更新処理を妨害する恐れがあります。"</string>
<string name="permlab_batteryStats">"電池統計情報の変国"</string>
<string name="permdesc_batteryStats">"収集した電池統計情報の変更を許可します。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_internalSystemWindow">"未許可のウィンドウの表示"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"この動画はご使用の端末でストリーミングできません。"</string>
<string name="VideoView_error_text_unknown">"この動画は再生できません。"</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g><xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> - <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g><xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="noon">"正午"</string>
<string name="Noon">"正午"</string>
<string name="midnight">"午前0時"</string>
<string name="Midnight">"午前0時"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> - <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-ko-rKR/donottranslate-cldr.xml b/core/res/res/values-ko-rKR/donottranslate-cldr.xml
index 17d9432..4ec1ba4 100644
--- a/core/res/res/values-ko-rKR/donottranslate-cldr.xml
+++ b/core/res/res/values-ko-rKR/donottranslate-cldr.xml
@@ -79,13 +79,19 @@
<string name="today">오늘</string>
<string name="tomorrow">내일</string>
- <string name="hour_minute_ampm">%p %-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p %-l:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y. %-m. %-e.</string>
<string name="numeric_date_format">yyyy. M. d.</string>
+ <string name="numeric_date_template">"%s. %s. %s."</string>
<string name="month_day_year">%Y년 %-m월 %-e일</string>
<string name="time_of_day">%p %-l:%M:%S</string>
<string name="date_and_time">%p %-l:%M:%S %Y. %-m. %-e.</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y. %-m. %-e.</string>
<string name="month_day">%B %-e일</string>
<string name="month">%-B</string>
@@ -93,4 +99,36 @@
<string name="abbrev_month_day">%b %-e일</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y년 %b</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s. %3$s ~ %7$s. %8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s. %3$s %1$s ~ %7$s. %8$s %6$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s. %2$s. %3$s. ~ %9$s. %7$s. %8$s.</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s. %2$s. %3$s. %1$s ~ %9$s. %7$s. %8$s. %6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s. %2$s. %3$s. %1$s – %10$s %9$s. %7$s. %8$s. %6$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s. %3$s. – %10$s %7$s. %8$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s. %3$s. (%1$s) – %10$s %7$s. %8$s. (%6$s)</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s. %2$s. %3$s. – %10$s %9$s. %7$s. %8$s.</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s (%1$s) – %6$s %5$s (%4$s)</string>
+ <string name="wday1_date1_wday2_date2">%2$s (%1$s) – %5$s (%4$s)</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s (%2$s)</string>
+ <string name="wday_date">%3$s (%2$s)</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s일 – %7$s %8$s일</string>
+ <string name="same_year_wday1_md1_wday2_md2">%2$s %3$s일 (%1$s) – %7$s %8$s일 (%6$s)</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s일 – %10$s %7$s %8$s일</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s일 – %10$s %7$s %8$s일</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s %3$s일 (%1$s) – %10$s %7$s %8$s일 (%6$s)</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s %3$s일 (%1$s) – %10$s %7$s %8$s일 (%6$s)</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s년 %2$s %3$s일 – %10$s %9$s년 %7$s %8$s일</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s년 %2$s %3$s일 – %10$s %9$s년 %7$s %8$s일</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s년 %2$s %3$s일 %1$s – %10$s %9$s년 %7$s %8$s일 %6$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s년 %2$s %3$s일 %1$s – %10$s %9$s년 %7$s %8$s일 %6$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%4$s년 %2$s %3$s일 %1$s – %9$s년 %7$s %8$s일 %6$s</string>
+ <string name="same_month_md1_md2">%2$s월 %3$s일 ~ %8$s일</string>
+ <string name="same_month_wday1_md1_wday2_md2">%2$s %3$s일 (%1$s) – %7$s %8$s일 (%6$s)</string>
+ <string name="same_year_mdy1_mdy2">%9$s년 %2$s %3$s일 ~ %7$s월 %8$s일</string>
+ <string name="same_month_mdy1_mdy2">%9$s년 %2$s %3$s일~%8$s일</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s년 %2$s %3$s일 %1$s ~ %7$s월 %8$s일 %6$s</string>
</resources>
diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml
index 17d9432..4ec1ba4 100644
--- a/core/res/res/values-ko/donottranslate-cldr.xml
+++ b/core/res/res/values-ko/donottranslate-cldr.xml
@@ -79,13 +79,19 @@
<string name="today">오늘</string>
<string name="tomorrow">내일</string>
- <string name="hour_minute_ampm">%p %-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p %-l:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y. %-m. %-e.</string>
<string name="numeric_date_format">yyyy. M. d.</string>
+ <string name="numeric_date_template">"%s. %s. %s."</string>
<string name="month_day_year">%Y년 %-m월 %-e일</string>
<string name="time_of_day">%p %-l:%M:%S</string>
<string name="date_and_time">%p %-l:%M:%S %Y. %-m. %-e.</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y. %-m. %-e.</string>
<string name="month_day">%B %-e일</string>
<string name="month">%-B</string>
@@ -93,4 +99,36 @@
<string name="abbrev_month_day">%b %-e일</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y년 %b</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s. %3$s ~ %7$s. %8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s. %3$s %1$s ~ %7$s. %8$s %6$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s. %2$s. %3$s. ~ %9$s. %7$s. %8$s.</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s. %2$s. %3$s. %1$s ~ %9$s. %7$s. %8$s. %6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s. %2$s. %3$s. %1$s – %10$s %9$s. %7$s. %8$s. %6$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s. %3$s. – %10$s %7$s. %8$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s. %3$s. (%1$s) – %10$s %7$s. %8$s. (%6$s)</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s. %2$s. %3$s. – %10$s %9$s. %7$s. %8$s.</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s (%1$s) – %6$s %5$s (%4$s)</string>
+ <string name="wday1_date1_wday2_date2">%2$s (%1$s) – %5$s (%4$s)</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s (%2$s)</string>
+ <string name="wday_date">%3$s (%2$s)</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s일 – %7$s %8$s일</string>
+ <string name="same_year_wday1_md1_wday2_md2">%2$s %3$s일 (%1$s) – %7$s %8$s일 (%6$s)</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s일 – %10$s %7$s %8$s일</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s일 – %10$s %7$s %8$s일</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s %3$s일 (%1$s) – %10$s %7$s %8$s일 (%6$s)</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s %3$s일 (%1$s) – %10$s %7$s %8$s일 (%6$s)</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s년 %2$s %3$s일 – %10$s %9$s년 %7$s %8$s일</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s년 %2$s %3$s일 – %10$s %9$s년 %7$s %8$s일</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s년 %2$s %3$s일 %1$s – %10$s %9$s년 %7$s %8$s일 %6$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s년 %2$s %3$s일 %1$s – %10$s %9$s년 %7$s %8$s일 %6$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%4$s년 %2$s %3$s일 %1$s – %9$s년 %7$s %8$s일 %6$s</string>
+ <string name="same_month_md1_md2">%2$s월 %3$s일 ~ %8$s일</string>
+ <string name="same_month_wday1_md1_wday2_md2">%2$s %3$s일 (%1$s) – %7$s %8$s일 (%6$s)</string>
+ <string name="same_year_mdy1_mdy2">%9$s년 %2$s %3$s일 ~ %7$s월 %8$s일</string>
+ <string name="same_month_mdy1_mdy2">%9$s년 %2$s %3$s일~%8$s일</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s년 %2$s %3$s일 %1$s ~ %7$s월 %8$s일 %6$s</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 06b85e8..e2c6e57 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"응용프로그램이 로케일 또는 전체 글꼴 크기 같은 현재 구성을 변경할 수 있습니다."</string>
<string name="permlab_restartPackages">"다른 응용프로그램 다시 시작"</string>
<string name="permdesc_restartPackages">"응용프로그램이 다른 응용프로그램을 강제로 다시 시작할 수 있습니다."</string>
- <string name="permlab_setProcessForeground">"중지되지 않도록 하기"</string>
- <string name="permdesc_setProcessForeground">"응용프로그램이 프로세스를 포그라운드에서 실행되도록 하여 프로세스를 중지할 수 있습니다. 일반 응용프로그램에는 필요하지 않습니다."</string>
<string name="permlab_forceBack">"강제로 응용프로그램 닫기"</string>
<string name="permdesc_forceBack">"응용프로그램이 포그라운드에 있는 활동을 강제로 닫을 수 있습니다. 일반 응용프로그램에는 필요하지 않습니다."</string>
<string name="permlab_dump">"시스템 내부 상태 검색"</string>
<string name="permdesc_dump">"응용프로그램이 시스템의 내부 상태를 검색할 수 있습니다. 악성 응용프로그램은 이 기능을 이용하여 일반적으로 필요하지 않은 다양한 개인 정보와 보안 정보를 검색할 수 있습니다."</string>
- <string name="permlab_addSystemService">"하위 수준 서비스 게시"</string>
- <string name="permdesc_addSystemService">"응용프로그램이 자체 하위 수준 시스템 서비스를 게시할 수 있습니다. 악성 응용프로그램은 이 기능을 이용하여 시스템을 하이재킹하거나 시스템의 데이터를 도용 또는 손상시킬 수 있습니다."</string>
<string name="permlab_runSetActivityWatcher">"실행 중인 모든 응용프로그램 모니터링 및 제어"</string>
<string name="permdesc_runSetActivityWatcher">"응용프로그램이 시스템에서 활동이 시작되는 방식을 모니터링하고 제어할 수 있습니다. 악성 응용프로그램은 이 기능을 이용하여 시스템을 완전히 손상시킬 수 있습니다. 이 권한은 개발 과정에만 필요하며 일반 전화기 사용 시에는 필요하지 않습니다."</string>
<string name="permlab_broadcastPackageRemoved">"패키지 제거 브로드캐스트 보내기"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"응용프로그램이 실행할 최대 프로세스 수를 제어할 수 있습니다. 일반 응용프로그램에는 필요하지 않습니다."</string>
<string name="permlab_setAlwaysFinish">"모든 백그라운드 응용프로그램이 닫히도록 하기"</string>
<string name="permdesc_setAlwaysFinish">"응용프로그램이 백그라운드로 이동한 활동을 항상 바로 마칠지 여부를 제어할 수 있습니다. 일반 응용프로그램에는 필요하지 않습니다."</string>
- <string name="permlab_fotaUpdate">"시스템 업데이트 자동으로 설치"</string>
- <string name="permdesc_fotaUpdate">"응용프로그램이 대기 중인 시스템 업데이트에 대한 알림을 받고 설치를 트리거할 수 있습니다. 악성 응용프로그램은 이 기능을 이용하여 인증되지 않은 업데이트로 시스템을 손상시키거나 업데이트 절차를 방해할 수 있습니다."</string>
<string name="permlab_batteryStats">"배터리 통계 수정"</string>
<string name="permdesc_batteryStats">"수집된 배터리 통계를 수정할 수 있습니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
<string name="permlab_internalSystemWindow">"인증되지 않은 창 표시"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"죄송합니다. 이 기기로의 스트리밍에 적합하지 않은 동영상입니다."</string>
<string name="VideoView_error_text_unknown">"죄송합니다. 동영상을 재생할 수 없습니다."</string>
<string name="VideoView_error_button">"확인"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="noon">"정오"</string>
<string name="Noon">"정오"</string>
<string name="midnight">"자정"</string>
<string name="Midnight">"자정"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-lt-rLT/donottranslate-cldr.xml b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
index 629937b..17f228d 100644
--- a/core/res/res/values-lt-rLT/donottranslate-cldr.xml
+++ b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">šiandien</string>
<string name="tomorrow">rytoj</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%Y m. %B %-e d.</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %Y.%m.%d</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y.%m.%d</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s - %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s-%3$s%1$s - %7$s-%8$s%6$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s - %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s-%2$s-%3$s%1$s - %9$s-%7$s-%8$s%6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s - %10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s - %10$s %9$s-%7$s-%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s - %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s - %10$s %7$s %8$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s - %10$s %7$s %8$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s m. %2$s %3$s d. - %10$s %9$s m. %7$s %8$s d.</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s m. %2$s %3$s d. - %10$s %9$s m. %7$s %8$s d.</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%2$s %3$s d.-%8$s d.</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s m. %2$s %3$s d. - %7$s %8$s d.</string>
+ <string name="same_month_mdy1_mdy2">%9$s m. %2$s %3$s d.-%8$s d.</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s m. %2$s %3$s d.,%1$s - %7$s %8$s d.,%6$s</string>
</resources>
diff --git a/core/res/res/values-lv-rLV/donottranslate-cldr.xml b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
index d47a18f..e6c3b79 100644
--- a/core/res/res/values-lv-rLV/donottranslate-cldr.xml
+++ b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">šodien</string>
<string name="tomorrow">rīt</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%Y. gada %-e. %B</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %Y. gada %-e. %b</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y. gada %-e. %b</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y. g. %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s–%8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s.–%8$s.%7$s.%9$s.</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s. – %6$s, %8$s.%7$s.%9$s.</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s.%2$s.%4$s. - %10$s %6$s, %8$s.%7$s.%9$s.</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s. gada %3$s. %2$s - %10$s %9$s. gada %8$s. %7$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s. gada %3$s. %2$s - %10$s %9$s. gada %8$s. %7$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s. g. %3$s. %2$s - %10$s %6$s, %9$s. g. %8$s. %7$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s. g. %3$s. %2$s - %10$s %6$s, %9$s. g. %8$s. %7$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s. g. %3$s. %2$s - %6$s, %9$s. g. %8$s. %7$s</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s. gada %3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_month_mdy1_mdy2">%9$s. gada %3$s.-%8$s. %2$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s. gada %3$s. %2$s - %6$s, y. gada %8$s. %7$s</string>
</resources>
diff --git a/core/res/res/values-mcc204-pt/strings.xml b/core/res/res/values-mcc204-pt/strings.xml
new file mode 100644
index 0000000..7d96230
--- /dev/null
+++ b/core/res/res/values-mcc204-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"nl_nl"</string>
+</resources>
diff --git a/core/res/res/values-mcc230-pt/strings.xml b/core/res/res/values-mcc230-pt/strings.xml
new file mode 100644
index 0000000..d3ecdbb
--- /dev/null
+++ b/core/res/res/values-mcc230-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"cs_cz"</string>
+</resources>
diff --git a/core/res/res/values-mcc232-pt/strings.xml b/core/res/res/values-mcc232-pt/strings.xml
new file mode 100644
index 0000000..4773838
--- /dev/null
+++ b/core/res/res/values-mcc232-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"de_at"</string>
+</resources>
diff --git a/core/res/res/values-mcc234-pt/strings.xml b/core/res/res/values-mcc234-pt/strings.xml
new file mode 100644
index 0000000..2538b73
--- /dev/null
+++ b/core/res/res/values-mcc234-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"en_gb"</string>
+</resources>
diff --git a/core/res/res/values-mcc260-pt/strings.xml b/core/res/res/values-mcc260-pt/strings.xml
new file mode 100644
index 0000000..1161f9a
--- /dev/null
+++ b/core/res/res/values-mcc260-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"pl_pl"</string>
+</resources>
diff --git a/core/res/res/values-mcc262-pt/strings.xml b/core/res/res/values-mcc262-pt/strings.xml
new file mode 100644
index 0000000..9505cf4
--- /dev/null
+++ b/core/res/res/values-mcc262-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"de_de"</string>
+</resources>
diff --git a/core/res/res/values-nb/donottranslate-cldr.xml b/core/res/res/values-nb/donottranslate-cldr.xml
index f89e819..17c9b24 100644
--- a/core/res/res/values-nb/donottranslate-cldr.xml
+++ b/core/res/res/values-nb/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">i dag</string>
<string name="tomorrow">i morgen</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H.%M</string>
+ <string name="hour_minute_ampm">%-l.%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l.%M %^p</string>
+ <string name="twelve_hour_time_format">h.mm a</string>
+ <string name="twenty_four_hour_time_format">HH.mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%H.%M.%S</string>
<string name="date_and_time">%H.%M.%S %-e. %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e. %b %Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s–%2$s</string>
+ <string name="date1_date2">%2$s–%5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s.–%8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s.%2$s.–%6$s %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s–%8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s.%2$s.%4$s–%6$s %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s.%2$s.%4$s–%10$s %6$s %8$s.%7$s.%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s.–%10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s.%2$s–%10$s %6$s %8$s.%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s–%10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s–%6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s–%4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s–%6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s–%8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s–%6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s–%10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s–%10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s–%10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s–%10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s–%10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s–%10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s. %2$s %4$s–%10$s %6$s %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s. %2$s %4$s–%10$s %6$s %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s %4$s–%6$s %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s.–%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s–%6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s–%8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.–%8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s–%6$s %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a28b12c..33d0159 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -166,14 +166,10 @@
<string name="permdesc_changeConfiguration">"Tillater applikasjonen å endre gjeldende innstillinger, slik som språk eller skriftstørrelse."</string>
<string name="permlab_restartPackages">"omstarte andre applikasjoner"</string>
<string name="permdesc_restartPackages">"Lar applikasjonen tvinge andre applikasjoner til å starte på nytt."</string>
- <string name="permlab_setProcessForeground">"unngå å bli stoppet"</string>
- <string name="permdesc_setProcessForeground">"Lar applikasjonen sette en vilkårlig prosess i forgrunnen, så den ikke kan bli drept. Vanlige applikasjoner bør aldri trenge dette."</string>
<string name="permlab_forceBack">"tvinge applikasjoner til å lukkes"</string>
<string name="permdesc_forceBack">"Lar applikasjonen tvinge enhver aktivitet som er i forgrunnen til å lukkes og gå tilbake. Vanlige applikasjoner bør aldri trenge dette."</string>
<string name="permlab_dump">"hente intern systemtilstand"</string>
<string name="permdesc_dump">"Lar applikasjonen hente intern tilstand fra systemet. Onsdinnede applikasjoner kan hente et bredt spekter av privat og sikker informasjon som de vanligvis aldri burde ha behov for."</string>
- <string name="permlab_addSystemService">"publisere lavnivåtjenester"</string>
- <string name="permdesc_addSystemService">"Lar applikasjonen publisere sine egne lavnivås systemtjenester. Ondsinnede applikasjoner kan kapre systemet, og stjele eller ødelegge alle data på det."</string>
<string name="permlab_runSetActivityWatcher">"overvåke og kontrollere all applikasjonsoppstart"</string>
<string name="permdesc_runSetActivityWatcher">"Lar applikasjonen overvåke og kontrollere hvordan systemet starter applikasjoner. Ondsinnede applikasjoner kan ta over systemet helt. Denne rettigheten behøves bare for utvikling, aldri for vanlig bruk av telefonen."</string>
<string name="permlab_broadcastPackageRemoved">"kringkaste melding om fjernet pakke"</string>
@@ -186,8 +182,6 @@
<string name="permdesc_setProcessLimit">"Lar applikasjonen kontrollere maksimalt antall kjørende prosesser. Behøves aldri for vanlige applikasjoner."</string>
<string name="permlab_setAlwaysFinish">"få alle bakgrunnsapplikasjoner til å lukkes"</string>
<string name="permdesc_setAlwaysFinish">"Lar applikasjonen kontrollere om aktiviteter alltid avsluttes når de sendes til bakgrunnen. Behøves aldri for vanlige applikasjoner."</string>
- <string name="permlab_fotaUpdate">"installere systemoppdateringer automatisk"</string>
- <string name="permdesc_fotaUpdate">"Lar applikasjonen motta meldinger om pågående systemoppdateringer, og starte installeringen av dem. Ondsinnede applikasjoner kan bruke dette for å skade systemet med uautoriserte oppdateringer, eller generelt forstyrre oppdateringsprosessen."</string>
<string name="permlab_batteryStats">"endre batteristatistikk"</string>
<string name="permdesc_batteryStats">"Lar applikasjonen endre på innsamlet batteristatistikk. Ikke ment for vanlige applikasjoner."</string>
<string name="permlab_internalSystemWindow">"vis uautoriserte vinduer"</string>
@@ -545,17 +539,7 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Beklager, denne videoen er ikke gyldig for streaming til denne enheten."</string>
<string name="VideoView_error_text_unknown">"Beklager, kan ikke spille denne videoen."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="DATE">%3$s</xliff:g>PLACEHOLDERplaceholder"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"middag"</string>
<string name="Noon">"Middag"</string>
<string name="midnight">"midnatt"</string>
@@ -564,30 +548,6 @@
<skip />
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>."</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>."</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>.<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>.<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>.<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>.<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>. <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>. <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>. <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>.<xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>.<xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>.<xliff:g id="MONTH1">%2$s</xliff:g>.<xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>.<xliff:g id="MONTH2">%7$s</xliff:g>.<xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>.–<xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>.–<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day (3156047263406783231) -->
<skip />
<!-- no translation found for abbrev_month (3131032032850777433) -->
diff --git a/core/res/res/values-nl-rBE/donottranslate-cldr.xml b/core/res/res/values-nl-rBE/donottranslate-cldr.xml
index c3050c6..72a4694 100644
--- a/core/res/res/values-nl-rBE/donottranslate-cldr.xml
+++ b/core/res/res/values-nl-rBE/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Vandaag</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-e/%m/%Y</string>
<string name="numeric_date_format">d/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e-%b-%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e-%b-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e-%b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s - %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s - %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s-%2$s-%4$s - %10$s %6$s %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s-%2$s - %10$s %8$s-%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s-%2$s - %10$s %6$s %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-nl-rNL/donottranslate-cldr.xml b/core/res/res/values-nl-rNL/donottranslate-cldr.xml
index b9e0407..549d816 100644
--- a/core/res/res/values-nl-rNL/donottranslate-cldr.xml
+++ b/core/res/res/values-nl-rNL/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Vandaag</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e-%b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s-%2$s - %8$s-%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s-%2$s - %6$s %8$s-%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s-%2$s-%4$s - %8$s-%7$s-%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s-%2$s-%4$s - %6$s %8$s-%7$s-%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s-%2$s-%4$s - %10$s %6$s %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s-%2$s - %10$s %8$s-%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s-%2$s - %10$s %6$s %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s-%2$s-%4$s - %10$s %8$s-%7$s-%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-nl/donottranslate-cldr.xml b/core/res/res/values-nl/donottranslate-cldr.xml
index b9e0407..549d816 100644
--- a/core/res/res/values-nl/donottranslate-cldr.xml
+++ b/core/res/res/values-nl/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Vandaag</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e-%b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s-%2$s - %8$s-%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s-%2$s - %6$s %8$s-%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s-%2$s-%4$s - %8$s-%7$s-%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s-%2$s-%4$s - %6$s %8$s-%7$s-%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s-%2$s-%4$s - %10$s %6$s %8$s-%7$s-%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s-%2$s - %10$s %8$s-%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s-%2$s - %10$s %6$s %8$s-%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s-%2$s-%4$s - %10$s %8$s-%7$s-%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s - %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s - %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s - %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 4437f29..a418d72 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Hiermee kan een toepassing de huidige configuratie, zoals de landinstelling of de algemene lettergrootte, wijzigen."</string>
<string name="permlab_restartPackages">"andere toepassingen opnieuw starten"</string>
<string name="permdesc_restartPackages">"Hiermee kan een toepassing andere toepassingen opnieuw starten."</string>
- <string name="permlab_setProcessForeground">"stoppen voorkomen"</string>
- <string name="permdesc_setProcessForeground">"Hiermee kan een toepassing ervoor zorgen dat elk willekeurig proces op de voorgrond wordt uitgevoerd en dus niet kan worden afgesloten. Nooit vereist voor normale toepassingen."</string>
<string name="permlab_forceBack">"toepassing nu sluiten"</string>
<string name="permdesc_forceBack">"Hiermee kan een toepassing elke willekeurige activiteit die op de voorgrond wordt uitgevoerd, sluiten en naar de achtergrond verplaatsen. Nooit vereist voor normale toepassingen."</string>
<string name="permlab_dump">"interne systeemstatus ophalen"</string>
<string name="permdesc_dump">"Hiermee kan een toepassing de interne status van het systeem ophalen. Schadelijke toepassingen kunnen privé- of veiligheidsgegevens ophalen die ze normaal niet nodig hebben."</string>
- <string name="permlab_addSystemService">"services op laag niveau publiceren"</string>
- <string name="permdesc_addSystemService">"Hiermee kunnen toepassingen hun eigen systeemservices op laag niveau publiceren. Schadelijke toepassingen kunnen het systeem mogelijk kapen en willekeurige gegevens van het systeem stelen of beschadigen."</string>
<string name="permlab_runSetActivityWatcher">"alle startende toepassingen bijhouden en beheren"</string>
<string name="permdesc_runSetActivityWatcher">"Hiermee kan een toepassing de manier waarop het systeem activiteiten start, bijhouden en beheren. Schadelijke toepassingen kunnen het systeem volledig in gevaar brengen. Deze machtiging is alleen voor ontwikkeling vereist, nooit voor normaal telefoongebruik."</string>
<string name="permlab_broadcastPackageRemoved">"melding verzenden dat pakket is verwijderd"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Hiermee kan een toepassing het maximum aantal processen bepalen dat wordt uitgevoerd. Nooit vereist voor normale toepassingen."</string>
<string name="permlab_setAlwaysFinish">"alle achtergrondtoepassingen sluiten"</string>
<string name="permdesc_setAlwaysFinish">"Hiermee kan een toepassing bepalen of activiteiten altijd worden afgesloten zodra deze naar de achtergrond gaan. Nooit nodig voor normale toepassingen."</string>
- <string name="permlab_fotaUpdate">"systeemupdates automatisch installeren"</string>
- <string name="permdesc_fotaUpdate">"Hiermee ontvangt een toepassing meldingen over beschikbare systeemupdates en kan hun installatie starten. Schadelijke toepassingen kunnen hiervan gebruik maken om het systeem met ongeautoriseerde updates te beschadigen of het updateproces in het algemeen te verstoren."</string>
<string name="permlab_batteryStats">"accustatistieken aanpassen"</string>
<string name="permdesc_batteryStats">"Hiermee kunnen verzamelde accustatistieken worden gewijzigd. Niet voor gebruik door normale toepassingen."</string>
<string name="permlab_internalSystemWindow">"niet-geautoriseerde vensters weergeven"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Deze video kan helaas niet worden gestreamd naar dit apparaat."</string>
<string name="VideoView_error_text_unknown">"Deze video kan niet worden afgespeeld."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"twaalf uur \'s middags"</string>
<string name="Noon">"Twaalf uur \'s middags"</string>
<string name="midnight">"middernacht"</string>
<string name="Midnight">"Middernacht"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g>-<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>-<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g>-<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>-<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g>-<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>-<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>-<xliff:g id="MONTH1">%2$s</xliff:g>-<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>-<xliff:g id="MONTH2">%7$s</xliff:g>-<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-pl-rPL/donottranslate-cldr.xml b/core/res/res/values-pl-rPL/donottranslate-cldr.xml
index 0ae8b48..c4bed0d 100644
--- a/core/res/res/values-pl-rPL/donottranslate-cldr.xml
+++ b/core/res/res/values-pl-rPL/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Dzisiaj</string>
<string name="tomorrow">Jutro</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d-%m-%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d-%m-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s-%8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s-%8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s-%2$s-%4$s-%6$s, %8$s-%7$s-%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s.%2$s.%4$s - %10$s %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s-%2$s-%4$s - %10$s %8$s-%7$s-%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%3$s %2$s %1$s - %8$s %7$s %6$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s %1$s - %10$s %8$s %7$s %6$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s %1$s - %10$s %8$s %7$s %6$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%3$s %2$s %1$s - %8$s %7$s %6$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-pl/donottranslate-cldr.xml b/core/res/res/values-pl/donottranslate-cldr.xml
index 0ae8b48..c4bed0d 100644
--- a/core/res/res/values-pl/donottranslate-cldr.xml
+++ b/core/res/res/values-pl/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Dzisiaj</string>
<string name="tomorrow">Jutro</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d-%m-%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d-%m-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s-%8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s-%8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s-%2$s-%4$s-%6$s, %8$s-%7$s-%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s.%2$s.%4$s - %10$s %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s-%2$s-%4$s - %10$s %8$s-%7$s-%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%3$s %2$s %1$s - %8$s %7$s %6$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s %1$s - %10$s %8$s %7$s %6$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s %1$s - %10$s %8$s %7$s %6$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%3$s %2$s %1$s - %8$s %7$s %6$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2cd4841..c6c9bd0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Pozwala aplikacji zmieniać bieżącą konfigurację, na przykład lokalny lub globalny rozmiar czcionki."</string>
<string name="permlab_restartPackages">"resetowanie innych aplikacji"</string>
<string name="permdesc_restartPackages">"Pozwala aplikacji na wymuszenie ponownego uruchomienia innych aplikacji."</string>
- <string name="permlab_setProcessForeground">"zapobieganie zatrzymaniu"</string>
- <string name="permdesc_setProcessForeground">"Pozwala aplikacji na uruchamianie dowolnego procesu na pierwszym planie tak, że nie można go wyłączyć. Nigdy nie powinno być potrzebne normalnym aplikacjom."</string>
<string name="permlab_forceBack">"wymuszanie zamknięcia aplikacji"</string>
<string name="permdesc_forceBack">"Pozwala aplikacji na wymuszenie zamknięcia i cofnięcia dowolnej operacji działającej na pierwszym planie. Nigdy nie powinno być potrzebne normalnym aplikacjom."</string>
<string name="permlab_dump">"pobieranie informacji o wewnętrznym stanie systemu"</string>
<string name="permdesc_dump">"Pozwala aplikacjom na pobieranie informacji o wewnętrznym stanie systemu. Szkodliwe aplikacje mogą pobrać szeroką gamę osobistych i zabezpieczonych informacji, które normalnie nie powinny im być nigdy potrzebne."</string>
- <string name="permlab_addSystemService">"publikowanie usług niskiego poziomu"</string>
- <string name="permdesc_addSystemService">"Pozwala aplikacji na publikowanie własnych usług systemowych niskiego poziomu. Szkodliwe aplikacje mogą przejąć kontrolę nad systemem oraz wykraść lub uszkodzić znajdujące się w nim dane."</string>
<string name="permlab_runSetActivityWatcher">"monitorowanie i kontrolowanie wszystkich uruchamianych aplikacji"</string>
<string name="permdesc_runSetActivityWatcher">"Pozwala aplikacji na monitorowanie i kontrolowanie sposobu, w jaki w systemie uruchamiane są różne działania. Szkodliwe aplikacje mogą całkowicie przejąć system. Te uprawnienia potrzebne są tylko programistom, nigdy w przypadku normalnego wykorzystywania telefonu."</string>
<string name="permlab_broadcastPackageRemoved">"wysyłanie transmisji informującej o usuniętym pakiecie"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Pozwala aplikacji na kontrolowanie maksymalnej liczby uruchamianych procesów. Nigdy nie wykorzystywane przez normalne aplikacje."</string>
<string name="permlab_setAlwaysFinish">"zamykanie wszystkich aplikacji działających w tle"</string>
<string name="permdesc_setAlwaysFinish">"Pozwala aplikacji na kontrolowanie, czy czynności są zawsze kończone, kiedy zaczynają działać w tle. Nigdy nie jest potrzebne normalnym aplikacjom."</string>
- <string name="permlab_fotaUpdate">"automatyczne instalowanie aktualizacji systemu"</string>
- <string name="permdesc_fotaUpdate">"Pozwala aplikacji na otrzymywanie powiadomień o oczekujących aktualizacjach systemu i uruchamianie ich instalacji. Szkodliwe aplikacje mogą to wykorzystać do uszkodzenia systemu za pomocą nieuwierzytelnionych aktualizacji lub ogólnie wpłynąć na proces aktualizowania."</string>
<string name="permlab_batteryStats">"zmienianie statystyk dotyczących baterii"</string>
<string name="permdesc_batteryStats">"Pozwala na zmianę zebranych statystyk dotyczących baterii. Nie do wykorzystania przez normalne aplikacje."</string>
<string name="permlab_internalSystemWindow">"wyświetlanie nieuwierzytelnionych okien"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"Przepraszamy, ten film wideo nie nadaje się do przesyłania strumieniowego do tego urządzenia."</string>
<string name="VideoView_error_text_unknown">"Niestety, nie można odtworzyć tego filmu wideo."</string>
<string name="VideoView_error_button">"OK"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"południe"</string>
<string name="Noon">"Południe"</string>
<string name="midnight">"północ"</string>
<string name="Midnight">"Północ"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-pt-rBR/donottranslate-cldr.xml b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
index cf0c29e..7b3304c 100644
--- a/core/res/res/values-pt-rBR/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Hoje</string>
<string name="tomorrow">Amanhã</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-kh%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H'h'mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e de %B de %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d/%m/%Y</string>
<string name="month_day">%-e de %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e de %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b de %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s/%2$s/%4$s - %10$s %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s/%2$s - %10$s %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s - %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s de %2$s - %10$s %6$s, %8$s de %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s de %2$s - %10$s %6$s, %8$s de %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s de %2$s de %4$s - %10$s %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s de %2$s de %4$s - %10$s %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s de %4$s - %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s de %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s de %2$s - %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s de %2$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s de %9$s</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/donottranslate-cldr.xml b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
index d42dc8f..b14dbcb 100644
--- a/core/res/res/values-pt-rPT/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Hoje</string>
<string name="tomorrow">Amanhã</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-kh%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H'h'mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e de %B de %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e de %b de %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e de %b de %Y</string>
<string name="month_day">%-e de %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e de %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b de %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s/%2$s/%4$s - %10$s %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s/%2$s - %10$s %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s - %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s de %2$s - %10$s %6$s, %8$s de %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s de %2$s - %10$s %6$s, %8$s de %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s de %2$s de %4$s - %10$s %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s de %2$s de %4$s - %10$s %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s de %4$s - %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s de %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s de %2$s - %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s de %2$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s de %9$s</string>
</resources>
diff --git a/core/res/res/values-pt/donottranslate-cldr.xml b/core/res/res/values-pt/donottranslate-cldr.xml
new file mode 100644
index 0000000..7b3304c
--- /dev/null
+++ b/core/res/res/values-pt/donottranslate-cldr.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="month_long_standalone_january">janeiro</string>
+ <string name="month_long_standalone_february">fevereiro</string>
+ <string name="month_long_standalone_march">março</string>
+ <string name="month_long_standalone_april">abril</string>
+ <string name="month_long_standalone_may">maio</string>
+ <string name="month_long_standalone_june">junho</string>
+ <string name="month_long_standalone_july">julho</string>
+ <string name="month_long_standalone_august">agosto</string>
+ <string name="month_long_standalone_september">setembro</string>
+ <string name="month_long_standalone_october">outubro</string>
+ <string name="month_long_standalone_november">novembro</string>
+ <string name="month_long_standalone_december">dezembro</string>
+
+ <string name="month_long_january">janeiro</string>
+ <string name="month_long_february">fevereiro</string>
+ <string name="month_long_march">março</string>
+ <string name="month_long_april">abril</string>
+ <string name="month_long_may">maio</string>
+ <string name="month_long_june">junho</string>
+ <string name="month_long_july">julho</string>
+ <string name="month_long_august">agosto</string>
+ <string name="month_long_september">setembro</string>
+ <string name="month_long_october">outubro</string>
+ <string name="month_long_november">novembro</string>
+ <string name="month_long_december">dezembro</string>
+
+ <string name="month_medium_january">jan</string>
+ <string name="month_medium_february">fev</string>
+ <string name="month_medium_march">mar</string>
+ <string name="month_medium_april">abr</string>
+ <string name="month_medium_may">mai</string>
+ <string name="month_medium_june">jun</string>
+ <string name="month_medium_july">jul</string>
+ <string name="month_medium_august">ago</string>
+ <string name="month_medium_september">set</string>
+ <string name="month_medium_october">out</string>
+ <string name="month_medium_november">nov</string>
+ <string name="month_medium_december">dez</string>
+
+ <string name="month_shortest_january">J</string>
+ <string name="month_shortest_february">F</string>
+ <string name="month_shortest_march">M</string>
+ <string name="month_shortest_april">A</string>
+ <string name="month_shortest_may">M</string>
+ <string name="month_shortest_june">J</string>
+ <string name="month_shortest_july">J</string>
+ <string name="month_shortest_august">A</string>
+ <string name="month_shortest_september">S</string>
+ <string name="month_shortest_october">O</string>
+ <string name="month_shortest_november">N</string>
+ <string name="month_shortest_december">D</string>
+
+ <string name="day_of_week_long_sunday">domingo</string>
+ <string name="day_of_week_long_monday">segunda-feira</string>
+ <string name="day_of_week_long_tuesday">terça-feira</string>
+ <string name="day_of_week_long_wednesday">quarta-feira</string>
+ <string name="day_of_week_long_thursday">quinta-feira</string>
+ <string name="day_of_week_long_friday">sexta-feira</string>
+ <string name="day_of_week_long_saturday">sábado</string>
+
+ <string name="day_of_week_medium_sunday">dom</string>
+ <string name="day_of_week_medium_monday">seg</string>
+ <string name="day_of_week_medium_tuesday">ter</string>
+ <string name="day_of_week_medium_wednesday">qua</string>
+ <string name="day_of_week_medium_thursday">qui</string>
+ <string name="day_of_week_medium_friday">sex</string>
+ <string name="day_of_week_medium_saturday">sáb</string>
+
+ <string name="day_of_week_short_sunday">dom</string>
+ <string name="day_of_week_short_monday">seg</string>
+ <string name="day_of_week_short_tuesday">ter</string>
+ <string name="day_of_week_short_wednesday">qua</string>
+ <string name="day_of_week_short_thursday">qui</string>
+ <string name="day_of_week_short_friday">sex</string>
+ <string name="day_of_week_short_saturday">sáb</string>
+
+ <string name="day_of_week_shortest_sunday">D</string>
+ <string name="day_of_week_shortest_monday">S</string>
+ <string name="day_of_week_shortest_tuesday">T</string>
+ <string name="day_of_week_shortest_wednesday">Q</string>
+ <string name="day_of_week_shortest_thursday">Q</string>
+ <string name="day_of_week_shortest_friday">S</string>
+ <string name="day_of_week_shortest_saturday">S</string>
+
+ <string name="am">AM</string>
+ <string name="pm">PM</string>
+ <string name="yesterday">Ontem</string>
+ <string name="today">Hoje</string>
+ <string name="tomorrow">Amanhã</string>
+
+ <string name="hour_minute_24">%-kh%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H'h'mm</string>
+ <string name="numeric_date">%d/%m/%Y</string>
+ <string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
+ <string name="month_day_year">%-e de %B de %Y</string>
+ <string name="time_of_day">%H:%M:%S</string>
+ <string name="date_and_time">%H:%M:%S %d/%m/%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
+ <string name="abbrev_month_day_year">%d/%m/%Y</string>
+ <string name="month_day">%-e de %B</string>
+ <string name="month">%-B</string>
+ <string name="month_year">%B de %Y</string>
+ <string name="abbrev_month_day">%-e de %b</string>
+ <string name="abbrev_month">%-b</string>
+ <string name="abbrev_month_year">%b de %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s/%2$s/%4$s - %10$s %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s/%2$s - %10$s %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s de %2$s - %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s de %2$s - %10$s %8$s de %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s de %2$s - %10$s %6$s, %8$s de %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s de %2$s - %10$s %6$s, %8$s de %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s de %2$s de %4$s - %10$s %8$s de %7$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s de %2$s de %4$s - %10$s %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s de %2$s de %4$s - %10$s %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s de %4$s - %6$s, %8$s de %7$s de %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s de %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s de %2$s - %8$s de %7$s de %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s de %2$s de %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s de %9$s</string>
+</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
new file mode 100644
index 0000000..c5c5bbb
--- /dev/null
+++ b/core/res/res/values-pt/strings.xml
@@ -0,0 +1,793 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="byteShort">"B"</string>
+ <string name="kilobyteShort">"KB"</string>
+ <string name="megabyteShort">"MB"</string>
+ <string name="gigabyteShort">"GB"</string>
+ <string name="terabyteShort">"TB"</string>
+ <string name="petabyteShort">"PB"</string>
+ <string name="untitled">"&lt;sem título&gt;"</string>
+ <string name="ellipsis">"…"</string>
+ <string name="emptyPhoneNumber">"(Nenhum número de telefone)"</string>
+ <string name="unknownName">"(Desconhecido)"</string>
+ <string name="defaultVoiceMailAlphaTag">"Correio de voz"</string>
+ <string name="defaultMsisdnAlphaTag">"MSISDN1"</string>
+ <string name="mmiError">"Problema de conexão ou código MMI inválido."</string>
+ <string name="serviceEnabled">"O serviço foi ativado."</string>
+ <string name="serviceEnabledFor">"O serviço foi ativado para:"</string>
+ <string name="serviceDisabled">"O serviço foi desativado."</string>
+ <string name="serviceRegistered">"O registro foi bem-sucedido."</string>
+ <string name="serviceErased">"Exclusão bem-sucedida."</string>
+ <string name="passwordIncorrect">"Senha incorreta"</string>
+ <string name="mmiComplete">"MMI completo."</string>
+ <string name="badPin">"O PIN antigo digitado não está correto."</string>
+ <string name="badPuk">"O PUK digitado não está correto."</string>
+ <string name="mismatchPin">"Os PINs digitados não correspondem."</string>
+ <string name="invalidPin">"Digite um PIN com 4 a 8 números."</string>
+ <string name="needPuk">"Seu cartão SIM está bloqueado pelo código PUK. Digite o PUK para desbloqueá-lo."</string>
+ <string name="needPuk2">"Digite PUK2 para desbloquear cartão SIM."</string>
+ <string name="ClipMmi">"ID do chamador"</string>
+ <string name="ClirMmi">"ID de quem realiza a chamada"</string>
+ <string name="CfMmi">"Transferência de chamada"</string>
+ <string name="CwMmi">"Chamada em espera"</string>
+ <string name="BaMmi">"Bloqueio de chamada"</string>
+ <string name="PwdMmi">"Alteração da senha"</string>
+ <string name="PinMmi">"Alteração de PIN"</string>
+ <!-- no translation found for CnipMmi (3110534680557857162) -->
+ <skip />
+ <!-- no translation found for CnirMmi (3062102121430548731) -->
+ <skip />
+ <!-- no translation found for ThreeWCMmi (9051047170321190368) -->
+ <skip />
+ <!-- no translation found for RuacMmi (7827887459138308886) -->
+ <skip />
+ <!-- no translation found for CndMmi (3116446237081575808) -->
+ <skip />
+ <!-- no translation found for DndMmi (1265478932418334331) -->
+ <skip />
+ <string name="CLIRDefaultOnNextCallOn">"ID do chamador assume o padrão de restrito. Próxima chamada: restrita"</string>
+ <string name="CLIRDefaultOnNextCallOff">"ID do chamador assume o padrão de restrito. Próxima chamada: não restrita"</string>
+ <string name="CLIRDefaultOffNextCallOn">"ID do chamador assume o padrão de não restrito. Próxima chamada: restrita"</string>
+ <string name="CLIRDefaultOffNextCallOff">"ID do chamador assume o padrão de não restrito. Próxima chamada: não restrita"</string>
+ <string name="serviceNotProvisioned">"Serviço não fornecido"</string>
+ <string name="CLIRPermanent">"A configuração da ID do chamador não pode ser alterada."</string>
+ <!-- no translation found for RestrictedChangedTitle (5592189398956187498) -->
+ <skip />
+ <!-- no translation found for RestrictedOnData (8653794784690065540) -->
+ <skip />
+ <!-- no translation found for RestrictedOnEmergency (6581163779072833665) -->
+ <skip />
+ <!-- no translation found for RestrictedOnNormal (2045364908281990708) -->
+ <skip />
+ <!-- no translation found for RestrictedOnAll (4923139582141626159) -->
+ <skip />
+ <string name="serviceClassVoice">"Voz"</string>
+ <string name="serviceClassData">"Dados"</string>
+ <string name="serviceClassFAX">"FAX"</string>
+ <string name="serviceClassSMS">"SMS"</string>
+ <string name="serviceClassDataAsync">"Assíncrono"</string>
+ <string name="serviceClassDataSync">"Sincronizar"</string>
+ <string name="serviceClassPacket">"Pacote"</string>
+ <string name="serviceClassPAD">"PAD"</string>
+ <!-- no translation found for roamingText0 (7170335472198694945) -->
+ <skip />
+ <!-- no translation found for roamingText1 (5314861519752538922) -->
+ <skip />
+ <!-- no translation found for roamingText2 (8969929049081268115) -->
+ <skip />
+ <!-- no translation found for roamingText3 (5148255027043943317) -->
+ <skip />
+ <!-- no translation found for roamingText4 (8808456682550796530) -->
+ <skip />
+ <!-- no translation found for roamingText5 (7604063252850354350) -->
+ <skip />
+ <!-- no translation found for roamingText6 (2059440825782871513) -->
+ <skip />
+ <!-- no translation found for roamingText7 (7112078724097233605) -->
+ <skip />
+ <!-- no translation found for roamingText8 (5989569778604089291) -->
+ <skip />
+ <!-- no translation found for roamingText9 (7969296811355152491) -->
+ <skip />
+ <!-- no translation found for roamingText10 (3992906999815316417) -->
+ <skip />
+ <!-- no translation found for roamingText11 (4154476854426920970) -->
+ <skip />
+ <!-- no translation found for roamingText12 (1189071119992726320) -->
+ <skip />
+ <!-- no translation found for roamingTextSearching (8360141885972279963) -->
+ <skip />
+ <string name="cfTemplateNotForwarded">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não transferido"</string>
+ <string name="cfTemplateForwarded">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+ <string name="cfTemplateForwardedTime">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> após <xliff:g id="TIME_DELAY">{2}</xliff:g> segundos"</string>
+ <string name="cfTemplateRegistered">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não transferido"</string>
+ <string name="cfTemplateRegisteredTime">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não transferido"</string>
+ <!-- no translation found for fcComplete (3118848230966886575) -->
+ <skip />
+ <!-- no translation found for fcError (3327560126588500777) -->
+ <skip />
+ <string name="httpErrorOk">"OK"</string>
+ <string name="httpError">"A página da web contém um erro."</string>
+ <string name="httpErrorLookup">"Não foi possível encontrar o URL."</string>
+ <string name="httpErrorUnsupportedAuthScheme">"O esquema de autenticação não é suportado."</string>
+ <string name="httpErrorAuth">"Falha na autenticação."</string>
+ <string name="httpErrorProxyAuth">"Falha na autenticação pelo servidor proxy."</string>
+ <string name="httpErrorConnect">"Falha na conexão com o servidor."</string>
+ <string name="httpErrorIO">"Falha de comunicação com o servidor. Tente novamente mais tarde."</string>
+ <string name="httpErrorTimeout">"Tempo limite da conexão com o servidor esgotado."</string>
+ <string name="httpErrorRedirectLoop">"A página contém muitos redirecionamentos do servidor."</string>
+ <string name="httpErrorUnsupportedScheme">"O protocolo não é suportado."</string>
+ <string name="httpErrorFailedSslHandshake">"Não foi possível estabelecer uma conexão segura."</string>
+ <string name="httpErrorBadUrl">"A página não pode ser aberta, pois o URL é inválido."</string>
+ <string name="httpErrorFile">"Não foi possível acessar o arquivo."</string>
+ <string name="httpErrorFileNotFound">"O arquivo solicitado não foi encontrado."</string>
+ <string name="httpErrorTooManyRequests">"Muitas solicitações sendo processadas. Tente novamente mais tarde."</string>
+ <string name="contentServiceSync">"Sincronizar"</string>
+ <string name="contentServiceSyncNotificationTitle">"Sincronizar"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc">"Muitas exclusões do <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+ <string name="low_memory">"O armazenamento do telefone está cheio! Exclua alguns arquivos para liberar espaço."</string>
+ <string name="me">"Eu"</string>
+ <string name="power_dialog">"Opções do telefone"</string>
+ <string name="silent_mode">"Modo silencioso"</string>
+ <string name="turn_on_radio">"Ativar rede sem fio"</string>
+ <string name="turn_off_radio">"Desativar a rede sem fio"</string>
+ <string name="screen_lock">"Bloqueio de tela"</string>
+ <string name="power_off">"Desligar"</string>
+ <string name="shutdown_progress">"Desligando…"</string>
+ <string name="shutdown_confirm">"Seu telefone desligará"</string>
+ <string name="no_recent_tasks">"Nenhum aplicativo recente."</string>
+ <string name="global_actions">"Opções do telefone"</string>
+ <string name="global_action_lock">"Bloqueio de tela"</string>
+ <string name="global_action_power_off">"Desligar"</string>
+ <string name="global_action_toggle_silent_mode">"Modo silencioso"</string>
+ <string name="global_action_silent_mode_on_status">"O som está DESLIGADO"</string>
+ <string name="global_action_silent_mode_off_status">"O som está ATIVADO"</string>
+ <!-- no translation found for global_actions_toggle_airplane_mode (5884330306926307456) -->
+ <skip />
+ <!-- no translation found for global_actions_airplane_mode_on_status (2719557982608919750) -->
+ <skip />
+ <!-- no translation found for global_actions_airplane_mode_off_status (5075070442854490296) -->
+ <skip />
+ <string name="safeMode">"Modo de segurança"</string>
+ <!-- no translation found for android_system_label (6577375335728551336) -->
+ <skip />
+ <string name="permgrouplab_costMoney">"Serviços que custam dinheiro"</string>
+ <string name="permgroupdesc_costMoney">"Permite que os aplicativos façam coisas que podem custar dinheiro."</string>
+ <string name="permgrouplab_messages">"Suas mensagens"</string>
+ <string name="permgroupdesc_messages">"Ler e gravar suas mensagens SMS, e-mail e outras mensagens."</string>
+ <string name="permgrouplab_personalInfo">"Suas informações pessoais"</string>
+ <string name="permgroupdesc_personalInfo">"Acesso direto aos seus contatos e calendário armazenados no telefone."</string>
+ <string name="permgrouplab_location">"Sua localização"</string>
+ <string name="permgroupdesc_location">"Monitore seu local físico"</string>
+ <string name="permgrouplab_network">"Comunicação de rede"</string>
+ <string name="permgroupdesc_network">"Permite que os aplicativos acessem diversos recursos de rede."</string>
+ <string name="permgrouplab_accounts">"Suas contas do Google"</string>
+ <string name="permgroupdesc_accounts">"Acesse as contas do Google disponíveis."</string>
+ <string name="permgrouplab_hardwareControls">"Controles de hardware"</string>
+ <string name="permgroupdesc_hardwareControls">"Acesso direto ao hardware no handset."</string>
+ <string name="permgrouplab_phoneCalls">"Chamadas telefônicas"</string>
+ <string name="permgroupdesc_phoneCalls">"Monitorar, registrar e processar chamadas telefônicas."</string>
+ <string name="permgrouplab_systemTools">"Ferramentas do sistema"</string>
+ <string name="permgroupdesc_systemTools">"Acesso de nível inferior e controle do sistema."</string>
+ <string name="permgrouplab_developmentTools">"Ferramentas de desenvolvimento"</string>
+ <string name="permgroupdesc_developmentTools">"Recursos necessários apenas aos desenvolvedores de aplicativo."</string>
+ <!-- no translation found for permgrouplab_storage (1971118770546336966) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_storage (9203302214915355774) -->
+ <skip />
+ <string name="permlab_statusBar">"desativar ou modificar a barra de status"</string>
+ <string name="permdesc_statusBar">"Permite que os aplicativos desativem a barra de status ou adicionem e removam ícones do sistema."</string>
+ <string name="permlab_expandStatusBar">"expandir/recolher barra de status"</string>
+ <string name="permdesc_expandStatusBar">"Permite que um aplicativo expanda ou recolha a barra de status."</string>
+ <string name="permlab_processOutgoingCalls">"Interceptar chamadas realizadas"</string>
+ <string name="permdesc_processOutgoingCalls">"Permite que aplicativos processem chamadas realizadas e alterem o número a ser discado. Aplicativos maliciosos podem monitorar, redirecionar ou impedir chamadas realizadas."</string>
+ <string name="permlab_receiveSms">"receber SMS"</string>
+ <string name="permdesc_receiveSms">"Permite que o aplicativo receba e processe mensagens SMS. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
+ <string name="permlab_receiveMms">"receber MMS"</string>
+ <string name="permdesc_receiveMms">"Permite que o aplicativo receba e processe mensagens MMS. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
+ <string name="permlab_sendSms">"enviar mensagens SMS"</string>
+ <string name="permdesc_sendSms">"Permite que os aplicativos enviem mensagens SMS. Os aplicativos maliciosos podem causar prejuízo financeiro a você ao enviar mensagens sem a sua confirmação."</string>
+ <string name="permlab_readSms">"ler SMS ou MMS"</string>
+ <string name="permdesc_readSms">"Permite que um aplicativo leia mensagens SMS armazenadas no seu telefone ou cartão SIM. Aplicativos maliciosos podem ler suas mensagens confidenciais."</string>
+ <string name="permlab_writeSms">"editar SMS ou MMS"</string>
+ <string name="permdesc_writeSms">"Permite que um aplicativo grave mensagens SMS armazenadas no seu telefone ou cartão SIM. Aplicativos maliciosos podem excluir suas mensagens."</string>
+ <string name="permlab_receiveWapPush">"receber WAP"</string>
+ <string name="permdesc_receiveWapPush">"Permite que o aplicativo receba e processe mensagens WAP. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
+ <string name="permlab_getTasks">"recuperar aplicativos em execução"</string>
+ <string name="permdesc_getTasks">"Permite que os aplicativos recuperem informações sobre as tarefas em execução no momento ou recentemente. Pode permitir que aplicativos maliciosos descubram informações particulares sobre outros aplicativos."</string>
+ <string name="permlab_reorderTasks">"reorganizar os aplicativos em execução"</string>
+ <string name="permdesc_reorderTasks">"Permite que um aplicativo mova as tarefas para o primeiro ou segundo plano. Os aplicativos maliciosos podem forçar sua permanência no primeiro plano sem o seu controle."</string>
+ <string name="permlab_setDebugApp">"ativar depuração do aplicativo"</string>
+ <string name="permdesc_setDebugApp">"Permite que um aplicativo ative a depuração de outro aplicativo. Aplicativos maliciosos podem usar isso para encerrar outros aplicativos."</string>
+ <string name="permlab_changeConfiguration">"alterar as configurações da sua IU"</string>
+ <string name="permdesc_changeConfiguration">"Permite que um aplicativo mude a configuração atual, como a localidade ou o tamanho geral de fonte."</string>
+ <string name="permlab_restartPackages">"reiniciar outros aplicativos"</string>
+ <string name="permdesc_restartPackages">"Permite que um aplicativo reinicie outros aplicativos forçosamente."</string>
+ <string name="permlab_forceBack">"forçar fechamento do aplicativo"</string>
+ <string name="permdesc_forceBack">"Permite que um aplicativo force qualquer atividade que esteja em primeiro plano a fechar e voltar. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_dump">"recuperar estado interno do sistema"</string>
+ <string name="permdesc_dump">"Permite que um aplicativo recupere o estado interno do sistema. Aplicativos maliciosos podem recuperar um ampla variedade de informações privadas e seguras, as quais não deveriam precisar normalmente."</string>
+ <!-- no translation found for permlab_shutdown (7185747824038909016) -->
+ <skip />
+ <!-- no translation found for permdesc_shutdown (7046500838746291775) -->
+ <skip />
+ <!-- no translation found for permlab_stopAppSwitches (4138608610717425573) -->
+ <skip />
+ <!-- no translation found for permdesc_stopAppSwitches (3857886086919033794) -->
+ <skip />
+ <string name="permlab_runSetActivityWatcher">"monitorar e controle toda inicialização de aplicativo"</string>
+ <string name="permdesc_runSetActivityWatcher">"Permite que um aplicativo monitore e controle como o sistema inicia as atividades. Os aplicativos maliciosos podem comprometer completamente o sistema. Esta permissão é necessária apenas para desenvolvimento, nunca para uso normal do telefone."</string>
+ <string name="permlab_broadcastPackageRemoved">"enviar transmissão de pacote removido"</string>
+ <string name="permdesc_broadcastPackageRemoved">"Permite que um aplicativo transmita uma notificação de que o pacote de um aplicativo foi removido. Aplicativos maliciosos podem usar isso para encerrar outro aplicativo em execução."</string>
+ <string name="permlab_broadcastSmsReceived">"enviar transmissão de SMS recebido"</string>
+ <string name="permdesc_broadcastSmsReceived">"Permite que um aplicativo transmita uma notificação de que uma mensagem SMS foi recebida. Aplicativos maliciosos podem usar isso para forjar o recebimento de mensagens SMS."</string>
+ <string name="permlab_broadcastWapPush">"enviar transmissão de WAP-PUSH recebido"</string>
+ <string name="permdesc_broadcastWapPush">"Permite que um aplicativo transmita uma notificação de que uma mensagem WAP PUSH foi recebida. Aplicativos maliciosos podem usar isso para forjar o recebimento de uma mensagem MMS ou substituir silenciosamente o conteúdo de qualquer página da web por variantes maliciosas."</string>
+ <string name="permlab_setProcessLimit">"limitar o número de processos em execução"</string>
+ <string name="permdesc_setProcessLimit">"Permite que um aplicativo controle o número máximo de processos que serão executados. Nunca é necessário para aplicativos normais."</string>
+ <string name="permlab_setAlwaysFinish">"fazer todos os aplicativos em segundo plano fechar"</string>
+ <string name="permdesc_setAlwaysFinish">"Permite que um aplicativo controle se as atividades são sempre concluídas assim que vão para o segundo plano. Nunca é necessário para aplicativos normais."</string>
+ <string name="permlab_batteryStats">"Modificar as estatísticas da bateria"</string>
+ <string name="permdesc_batteryStats">"Permite a modificação das estatísticas coletadas sobre a bateria. Não deve ser usado em aplicativos normais."</string>
+ <!-- no translation found for permlab_backup (470013022865453920) -->
+ <skip />
+ <!-- no translation found for permdesc_backup (2305432853944929371) -->
+ <skip />
+ <string name="permlab_internalSystemWindow">"exibir janelas não autorizadas"</string>
+ <string name="permdesc_internalSystemWindow">"Permite a criação de janelas que devem ser usadas pela interface de usuário do sistema interno. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_systemAlertWindow">"exibir alertas do nível do sistema"</string>
+ <string name="permdesc_systemAlertWindow">"Permite que um aplicativo mostre janelas de alerta do sistema. Aplicativos maliciosos podem assumir o controle de toda a tela do telefone."</string>
+ <string name="permlab_setAnimationScale">"modificar a velocidade de animação global"</string>
+ <string name="permdesc_setAnimationScale">"Permite que um aplicativo altere a velocidade de animação global (animações mais rápidas ou mais lentas) a qualquer momento."</string>
+ <string name="permlab_manageAppTokens">"gerenciar os símbolos do aplicativo"</string>
+ <string name="permdesc_manageAppTokens">"Permite que um aplicativo crie e gerencie seus próprio símbolos, ignorando a ordem-Z (Z-ordering). Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_injectEvents">"pressionar as teclas e os botões de controle"</string>
+ <string name="permdesc_injectEvents">"Permite que um aplicativo proporcione seus próprios eventos de entrada (pressionamentos de tecla etc.) a outros aplicativos. Aplicativos maliciosos podem usar isso para assumir o controle do telefone."</string>
+ <string name="permlab_readInputState">"registrar o que você digita e as ações que executa"</string>
+ <string name="permdesc_readInputState">"Permite que os aplicativos observem as teclas que você pressiona ao interagir com outro aplicativo (como ao digitar uma senha). Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_bindInputMethod">"aderir a um método de entrada"</string>
+ <string name="permdesc_bindInputMethod">"Permite que o portador se vincule à interface de nível superior de um método de entrada. Normalmente não é necessário em aplicativos normais."</string>
+ <string name="permlab_setOrientation">"alterar orientação da tela"</string>
+ <string name="permdesc_setOrientation">"Permite que um aplicativo altere a rotação da tela a qualquer momento. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_signalPersistentProcesses">"enviar sinais de Linux aos aplicativos"</string>
+ <string name="permdesc_signalPersistentProcesses">"Permite que o aplicativo solicite que o sinal fornecido seja enviado a todos os processos persistentes."</string>
+ <string name="permlab_persistentActivity">"fazer com que o aplicativo execute sempre"</string>
+ <string name="permdesc_persistentActivity">"Permite que um aplicativo torne partes dele mesmo persistentes, para que o sistema não possa usá-lo para outros aplicativos."</string>
+ <string name="permlab_deletePackages">"excluir aplicativos"</string>
+ <string name="permdesc_deletePackages">"Permite que um aplicativo exclua pacotes do Android. Aplicativos maliciosos podem usar isso para excluir aplicativos importantes."</string>
+ <string name="permlab_clearAppUserData">"excluir os dados de outros aplicativos"</string>
+ <string name="permdesc_clearAppUserData">"Permite que um aplicativo limpe os dados do usuário."</string>
+ <string name="permlab_deleteCacheFiles">"excluir o cache de outros aplicativos"</string>
+ <string name="permdesc_deleteCacheFiles">"Permite que um aplicativo exclua arquivos armazenados em cache."</string>
+ <string name="permlab_getPackageSize">"medir o espaço de armazenamento do aplicativo"</string>
+ <string name="permdesc_getPackageSize">"Permite que um aplicativo recupere seu código, dados e tamanho de cache"</string>
+ <string name="permlab_installPackages">"instalar os aplicativos diretamente"</string>
+ <string name="permdesc_installPackages">"Permite que um aplicativo instale pacotes novos ou atualizados do Android. Aplicativos maliciosos podem usar isso para adicionar novos aplicativos com permissões aleatórias avançadas."</string>
+ <string name="permlab_clearAppCache">"excluir todos os dados do cache do aplicativo"</string>
+ <string name="permdesc_clearAppCache">"Permite que um aplicativo libere espaço de armazenamento do telefone excluindo arquivos no diretório de cache do aplicativo. O acesso é normalmente restrito ao processo do sistema."</string>
+ <string name="permlab_readLogs">"ler arquivos do registro do sistema"</string>
+ <string name="permdesc_readLogs">"Permite que um aplicativo leia os diversos arquivos de registro do sistema. Isso permite que ele descubra informações gerais sobre o que você está fazendo com o telefone, mas esses arquivos não devem conter informações pessoais ou privadas."</string>
+ <string name="permlab_diagnostic">"ler/gravar em recursos que pertencem ao diagnóstico"</string>
+ <string name="permdesc_diagnostic">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo diag; por exemplo, arquivos em /dev. Isso poderia afetar a estabilidade e a segurança do sistema. Por isso, SÓ deve ser usado para diagnósticos específicos do hardware pelo fabricante ou operador."</string>
+ <string name="permlab_changeComponentState">"ativar ou desativar componentes do aplicativo"</string>
+ <string name="permdesc_changeComponentState">"Permite que um aplicativo altere a ativação ou desativação de um componente de outro aplicativo. Aplicativos maliciosos podem usar isso para desativar recursos importantes do telefone. É preciso ter permissão e cuidado no uso, pois é possível deixar os componentes do aplicativo em um estado inutilizável, inconsistente ou instável."</string>
+ <string name="permlab_setPreferredApplications">"definir aplicativos preferidos"</string>
+ <string name="permdesc_setPreferredApplications">"Permite que um aplicativo modifique seus aplicativos preferidos. Isso pode permitir que aplicativos maliciosos alterem silenciosamente os aplicativos em execução, falsificando seus aplicativos existentes para coletar seus dados privados."</string>
+ <string name="permlab_writeSettings">"modificar configurações globais do sistema"</string>
+ <string name="permdesc_writeSettings">"Permite que um aplicativo modifique os dados da configuração do sistema. Aplicativos maliciosos podem corromper a configuração do sistema."</string>
+ <string name="permlab_writeSecureSettings">"modificar configurações de segurança do sistema"</string>
+ <string name="permdesc_writeSecureSettings">"Permite que um aplicativo modifique os dados das configurações de segurança dos sistemas. Não deve ser usado em aplicativos normais."</string>
+ <string name="permlab_writeGservices">"modificar o mapa de serviços do Google"</string>
+ <string name="permdesc_writeGservices">"Permite que um aplicativo modifique o mapa de serviços do Google. Não deve ser usado em aplicativos normais."</string>
+ <string name="permlab_receiveBootCompleted">"iniciar automaticamente na inicialização"</string>
+ <string name="permdesc_receiveBootCompleted">"Permite que um aplicativo se inicie assim que o sistema termina de inicializar. Isso pode causar uma demora na inicialização do telefone e faz com que todo o telefone fique mais lento pela execução contínua do aplicativo."</string>
+ <string name="permlab_broadcastSticky">"enviar transmissão complexa"</string>
+ <string name="permdesc_broadcastSticky">"Permite que um aplicativo envie transmissões persistentes, as quais permanecem após o término da transmissão. Aplicativos maliciosos podem tornar o telefone lento ou instável fazendo com que use muita memória."</string>
+ <string name="permlab_readContacts">"ler dados de contato"</string>
+ <string name="permdesc_readContacts">"Permite que um aplicativo leia todos os dados de contato (endereço) armazenados no telefone. Aplicativos maliciosos podem usar isso para enviar seus dados a outras pessoas."</string>
+ <string name="permlab_writeContacts">"gravar dados de contato"</string>
+ <string name="permdesc_writeContacts">"Permite que um aplicativo modifique os dados de contato (endereço) armazenados no telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar seus dados de contato."</string>
+ <string name="permlab_writeOwnerData">"gravar dados do proprietário"</string>
+ <string name="permdesc_writeOwnerData">"Permite que um aplicativo modifique os dados do proprietário do telefone armazenados no seu telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar os dados do proprietário."</string>
+ <string name="permlab_readOwnerData">"ler dados do proprietário"</string>
+ <string name="permdesc_readOwnerData">"Permite que um aplicativo leia os dados do proprietário do telefone armazenados no seu telefone. Aplicativos maliciosos podem usar isso para ler os dados do proprietário."</string>
+ <string name="permlab_readCalendar">"ler os dados do calendário"</string>
+ <string name="permdesc_readCalendar">"Permite que um aplicativo leia todos os eventos de calendário armazenados no seu telefone. Aplicativos maliciosos podem usar isso para enviar os eventos do seu calendário a outras pessoas."</string>
+ <string name="permlab_writeCalendar">"gravar dados do calendário"</string>
+ <string name="permdesc_writeCalendar">"Permite que um aplicativo modifique os eventos do calendário armazenados no seu telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar seus dados de contato."</string>
+ <string name="permlab_accessMockLocation">"imitar fontes de localização para teste"</string>
+ <string name="permdesc_accessMockLocation">"Criar imitação de fontes de localização para teste. Os aplicativos maliciosos podem usar isso para sobrescrever o local e/ou status retornado pelas fontes de localização reais como GPS ou provedores de rede."</string>
+ <string name="permlab_accessLocationExtraCommands">"acessar comandos extra do provedor de localização"</string>
+ <string name="permdesc_accessLocationExtraCommands">"Acessar comandos extra de fornecedor de localização. Aplicativos maliciosos podem usar isso para interferir com a operação do GPS ou com outras fontes de localização."</string>
+ <!-- no translation found for permlab_installLocationProvider (6578101199825193873) -->
+ <skip />
+ <!-- no translation found for permdesc_installLocationProvider (5449175116732002106) -->
+ <skip />
+ <string name="permlab_accessFineLocation">"Localização precisa (GPS)"</string>
+ <string name="permdesc_accessFineLocation">"Acesse fontes de localização precisa como o sistema GPS (Global Positioning System) no telefone, quando estiver disponível. Aplicativos maliciosos podem usar isso para determinar onde você está e também pode consumir energia da bateria."</string>
+ <string name="permlab_accessCoarseLocation">"Local inadequado (com base na rede)"</string>
+ <string name="permdesc_accessCoarseLocation">"Acessar fontes de localização aproximada como o banco de dados de rede de celular para determinar a localização aproximada de um telefone, quando houver disponibilidade. Aplicativos maliciosos podem usar isso para determinar sua localização aproximada."</string>
+ <string name="permlab_accessSurfaceFlinger">"acessar SurfaceFlinger"</string>
+ <string name="permdesc_accessSurfaceFlinger">"Permite que o aplicativo use os recursos de nível inferior do SurfaceFlinger."</string>
+ <string name="permlab_readFrameBuffer">"ler buffer do quadro"</string>
+ <string name="permdesc_readFrameBuffer">"Permite que o aplicativo leia o conteúdo do buffer do quadro."</string>
+ <string name="permlab_modifyAudioSettings">"alterar as configurações do seu áudio"</string>
+ <string name="permdesc_modifyAudioSettings">"Permite que o aplicativo modifique as configurações de áudio globais como volume e roteamento."</string>
+ <string name="permlab_recordAudio">"gravar áudio"</string>
+ <string name="permdesc_recordAudio">"Permite que o aplicativo acesso o caminho do registro de áudio."</string>
+ <string name="permlab_camera">"tirar fotos"</string>
+ <string name="permdesc_camera">"Permite que o aplicativo tire fotos com a câmera. Isso permite que o aplicativo colete imagens exibidas pela câmera a qualquer momento."</string>
+ <string name="permlab_brick">"desativar permanentemente o telefone"</string>
+ <string name="permdesc_brick">"Permite que o aplicativo desative todo o telefone permanentemente. Isso é muito perigoso."</string>
+ <string name="permlab_reboot">"forçar reinicializarão do telefone"</string>
+ <string name="permdesc_reboot">"Permite que o aplicativo force a reinicialização do telefone."</string>
+ <string name="permlab_mount_unmount_filesystems">"montar e desmontar sistemas de arquivos"</string>
+ <string name="permdesc_mount_unmount_filesystems">"Permite que o aplicativo monte e desmonte sistemas de arquivos para armazenamento removível."</string>
+ <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
+ <skip />
+ <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
+ <skip />
+ <string name="permlab_vibrate">"controlar vibrador"</string>
+ <string name="permdesc_vibrate">"Permite que o aplicativo controle o vibrador."</string>
+ <string name="permlab_flashlight">"controlar lanterna"</string>
+ <string name="permdesc_flashlight">"Permite que o aplicativo controle a lanterna."</string>
+ <string name="permlab_hardware_test">"testar hardware"</string>
+ <string name="permdesc_hardware_test">"Permite que o aplicativo controle diversos periféricos para teste de hardware."</string>
+ <string name="permlab_callPhone">"chamar números de telefone diretamente"</string>
+ <string name="permdesc_callPhone">"Permite que o aplicativo chame números de telefone sem sua intervenção. Aplicativos maliciosos podem causar a aparição de chamadas inesperadas na conta do seu telefone. Observe que isso não permite que o aplicativo ligue para números de emergência."</string>
+ <string name="permlab_callPrivileged">"chamar quaisquer números de telefone diretamente"</string>
+ <string name="permdesc_callPrivileged">"Permite que o aplicativo chame qualquer número de telefone, incluindo números de emergência, sem sua intervenção. Aplicativos maliciosos podem fazer chamadas desnecessárias e ilegais para serviços de emergência."</string>
+ <string name="permlab_locationUpdates">"controlar notificações de atualização de localização"</string>
+ <string name="permdesc_locationUpdates">"Permite a ativação/desativação das notificações sobre atualização de localização pelo rádio. Não deve ser usado em aplicativos normais."</string>
+ <string name="permlab_checkinProperties">"acessar propriedades de verificação"</string>
+ <string name="permdesc_checkinProperties">"Permite acesso de leitura/gravação às propriedades enviadas pelo serviço de verificação. Não deve ser usado em aplicativos normais."</string>
+ <!-- no translation found for permlab_bindGadget (776905339015863471) -->
+ <skip />
+ <!-- no translation found for permdesc_bindGadget (2098697834497452046) -->
+ <skip />
+ <string name="permlab_modifyPhoneState">"modificar estado do telefone"</string>
+ <string name="permdesc_modifyPhoneState">"Permite que o aplicativo controle os recursos do telefone do dispositivo. Um aplicativo com essa permissão pode alternar entre redes, ligar e desligar o rádio e executar ações parecidas sem o notificar."</string>
+ <string name="permlab_readPhoneState">"ler estado do telefone"</string>
+ <string name="permdesc_readPhoneState">"Permite que o aplicativo acesse os recursos do telefone do aparelho. Um aplicativo com essa permissão pode determinar o número deste telefone, se uma chamada está ativa, o número com o qual está chamada está conectada e outras coisas semelhantes."</string>
+ <string name="permlab_wakeLock">"impedir que o telefone entre em repouso"</string>
+ <string name="permdesc_wakeLock">"Permite que um aplicativo impeça o telefone de entrar em repouso."</string>
+ <string name="permlab_devicePower">"ligar ou desligar o telefone"</string>
+ <string name="permdesc_devicePower">"Permite que o aplicativo ligue ou desligue o telefone."</string>
+ <string name="permlab_factoryTest">"executar no modo de teste de fábrica"</string>
+ <string name="permdesc_factoryTest">"Executar como um teste de fabricante de nível inferior, permitindo o acesso completo ao hardware do telefone. Disponível apenas quando um telefone está executando no modo de teste de fábrica."</string>
+ <string name="permlab_setWallpaper">"definir papel de parede"</string>
+ <string name="permdesc_setWallpaper">"Permite que o aplicativo defina o papel de parede do sistema."</string>
+ <string name="permlab_setWallpaperHints">"definir dicas de tamanho de papel de parede"</string>
+ <string name="permdesc_setWallpaperHints">"Permite que o aplicativo defina as dicas de tamanho do papel de parede do sistema."</string>
+ <string name="permlab_masterClear">"reiniciar o sistema com o padrão de fábrica"</string>
+ <string name="permdesc_masterClear">"Permite que um aplicativo reinicie completamente o sistema com suas configurações de fábrica, apagando todos os dados, configuração e aplicativos instalados."</string>
+ <string name="permlab_setTimeZone">"definir fuso horário"</string>
+ <string name="permdesc_setTimeZone">"Permite que um aplicativo altere o fuso horário do telefone."</string>
+ <string name="permlab_getAccounts">"descobrir contas conhecidas"</string>
+ <string name="permdesc_getAccounts">"Permite que um aplicativo obtenha a lista de contas conhecidas pelo telefone."</string>
+ <string name="permlab_accessNetworkState">"exibir estado da rede"</string>
+ <string name="permdesc_accessNetworkState">"Permite que um aplicativo exiba o estado de todas as redes."</string>
+ <string name="permlab_createNetworkSockets">"acesso total à Internet"</string>
+ <string name="permdesc_createNetworkSockets">"Permite que um aplicativo crie soquetes de rede."</string>
+ <string name="permlab_writeApnSettings">"gravar configurações de Nome do ponto de acesso"</string>
+ <string name="permdesc_writeApnSettings">"Permite que um aplicativo modifique as configurações de APN, como Proxy e a Porta de qualquer APN."</string>
+ <string name="permlab_changeNetworkState">"alterar conectividade da rede"</string>
+ <string name="permdesc_changeNetworkState">"Permite que um aplicativo mude o estado da conectividade da rede."</string>
+ <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
+ <skip />
+ <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
+ <skip />
+ <string name="permlab_accessWifiState">"exibir estado da rede Wi-Fi"</string>
+ <string name="permdesc_accessWifiState">"Permite que um aplicativo exiba as informações sobre o estado da rede Wi-Fi."</string>
+ <string name="permlab_changeWifiState">"Alterar estado de Wi-Fi"</string>
+ <string name="permdesc_changeWifiState">"Permite que um aplicativo se conecte e desconecte dos pontos de acesso Wi-Fi e faça alterações nas redes Wi-Fi configuradas."</string>
+ <!-- no translation found for permlab_changeWifiMulticastState (1368253871483254784) -->
+ <skip />
+ <!-- no translation found for permdesc_changeWifiMulticastState (8199464507656067553) -->
+ <skip />
+ <string name="permlab_bluetoothAdmin">"administração do bluetooth"</string>
+ <string name="permdesc_bluetoothAdmin">"Permite que um aplicativo configure o telefone Bluetooth local, além de descobrir e parear com dispositivos remotos."</string>
+ <string name="permlab_bluetooth">"criar conexões Bluetooth"</string>
+ <string name="permdesc_bluetooth">"Permite que um aplicativo exiba a configuração do telefone Bluetooth local e faça e aceite conexões com os dispositivos pareados."</string>
+ <string name="permlab_disableKeyguard">"desativar bloqueio de teclado"</string>
+ <string name="permdesc_disableKeyguard">"Permite que um aplicativo desative o bloqueio do teclado e qualquer segurança de senha associada. Um exemplo legítimo disso é o telefone desativando o bloqueio do teclado ao receber uma chamada e reativando o bloqueio ao final da chamada."</string>
+ <string name="permlab_readSyncSettings">"ler configurações de sincronização"</string>
+ <string name="permdesc_readSyncSettings">"Permite que um aplicativo leia as configurações de sincronização, por exemplo se a sincronização está ativada para Contatos."</string>
+ <string name="permlab_writeSyncSettings">"gravar configurações de sincronização"</string>
+ <string name="permdesc_writeSyncSettings">"Permite que um aplicativo modifique as configurações de sincronização, por exemplo se a sincronização está ativada para Contatos."</string>
+ <string name="permlab_readSyncStats">"ler estatísticas de sincronização"</string>
+ <string name="permdesc_readSyncStats">"Permite que um aplicativo leia as estatísticas de sincronização; por exemplo, o histórico de sincronizações realizadas."</string>
+ <string name="permlab_subscribedFeedsRead">"ler feeds inscritos"</string>
+ <string name="permdesc_subscribedFeedsRead">"Permite que um aplicativo obtenha detalhes sobre os feeds sincronizados atualmente."</string>
+ <string name="permlab_subscribedFeedsWrite">"gravar feeds inscritos"</string>
+ <string name="permdesc_subscribedFeedsWrite">"Permite que um aplicativo modifique seus feeds sincronizados recentemente. Isso poderia permitir que um aplicativo malicioso alterasse seus feeds sincronizados."</string>
+ <!-- no translation found for permlab_readDictionary (432535716804748781) -->
+ <skip />
+ <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
+ <skip />
+ <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
+ <skip />
+ <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
+ <skip />
+ <!-- no translation found for permlab_sdcardWrite (8079403759001777291) -->
+ <skip />
+ <!-- no translation found for permdesc_sdcardWrite (6643963204976471878) -->
+ <skip />
+ <string-array name="phoneTypes">
+ <item>"Página Inicial"</item>
+ <item>"Celular"</item>
+ <item>"Trabalho"</item>
+ <item>"Fax comercial"</item>
+ <item>"Fax doméstico"</item>
+ <item>"Pager"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="emailAddressTypes">
+ <item>"Página Inicial"</item>
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <!-- no translation found for mobileEmailTypeName (2858957283716687707) -->
+ <skip />
+ <string-array name="postalAddressTypes">
+ <item>"Página Inicial"</item>
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="imAddressTypes">
+ <item>"Página Inicial"</item>
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="organizationTypes">
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="imProtocols">
+ <item>"AIM"</item>
+ <item>"Windows Live"</item>
+ <item>"Yahoo"</item>
+ <item>"Skype"</item>
+ <item>"QQ"</item>
+ <item>"Google Talk"</item>
+ <item>"ICQ"</item>
+ <item>"Jabber"</item>
+ </string-array>
+ <string name="keyguard_password_enter_pin_code">"Digite o código PIN"</string>
+ <string name="keyguard_password_wrong_pin_code">"Código PIN incorreto!"</string>
+ <string name="keyguard_label_text">"Para desbloquear, pressione Menu e 0."</string>
+ <string name="emergency_call_dialog_number_for_display">"Número de emergência"</string>
+ <string name="lockscreen_carrier_default">"(Sem serviço)"</string>
+ <string name="lockscreen_screen_locked">"Tela bloqueada."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled">"Pressione Menu para desbloquear ou fazer chamada de emergência."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled">"Pressione Menu para desbloquear."</string>
+ <string name="lockscreen_pattern_instructions">"Desenhar padrão para desbloqueio"</string>
+ <string name="lockscreen_emergency_call">"Chamada de emergência"</string>
+ <string name="lockscreen_pattern_correct">"Correto!"</string>
+ <string name="lockscreen_pattern_wrong">"Sentimos muito, tente novamente"</string>
+ <!-- no translation found for lockscreen_plugged_in (613343852842944435) -->
+ <skip />
+ <string name="lockscreen_low_battery">"Conecte o carregador."</string>
+ <string name="lockscreen_missing_sim_message_short">"Sem cartão SIM."</string>
+ <string name="lockscreen_missing_sim_message">"Não há um cartão SIM no telefone."</string>
+ <string name="lockscreen_missing_sim_instructions">"Insira um cartão SIM."</string>
+ <string name="lockscreen_network_locked_message">"Rede bloqueada"</string>
+ <string name="lockscreen_sim_puk_locked_message">"O cartão SIM está bloqueado pelo PUK."</string>
+ <!-- no translation found for lockscreen_sim_puk_locked_instructions (635967534992394321) -->
+ <skip />
+ <string name="lockscreen_sim_locked_message">"O cartão SIM está bloqueado."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message">"Desbloqueando cartão SIM…"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message">"Você desenhou incorretamente seu padrão de desbloqueio <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, você receberá uma solicitação para desbloquear o telefone usando seu login do Google."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown">"Tentar novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_forgot_pattern_button_text">"Esqueceu o padrão?"</string>
+ <string name="lockscreen_glogin_too_many_attempts">"Muitas tentativas de padrão!"</string>
+ <!-- no translation found for lockscreen_glogin_instructions (1816635201812207709) -->
+ <skip />
+ <string name="lockscreen_glogin_username_hint">"Nome de usuário (e-mail)"</string>
+ <string name="lockscreen_glogin_password_hint">"Senha"</string>
+ <string name="lockscreen_glogin_submit_button">"Fazer login"</string>
+ <string name="lockscreen_glogin_invalid_input">"Nome de usuário ou senha inválida."</string>
+ <!-- no translation found for hour_ampm (4329881288269772723) -->
+ <skip />
+ <!-- no translation found for hour_cap_ampm (1829009197680861107) -->
+ <skip />
+ <string name="status_bar_clear_all_button">"Limpar notificações"</string>
+ <string name="status_bar_no_notifications_title">"Sem modificações"</string>
+ <string name="status_bar_ongoing_events_title">"Em andamento"</string>
+ <string name="status_bar_latest_events_title">"Notificações"</string>
+ <!-- no translation found for battery_status_text_percent_format (7660311274698797147) -->
+ <skip />
+ <string name="battery_status_charging">"Carregando..."</string>
+ <string name="battery_low_title">"Conecte o carregador"</string>
+ <string name="battery_low_subtitle">"A carga da bateria está ficando baixa:"</string>
+ <string name="battery_low_percent_format">"menos de <xliff:g id="NUMBER">%d%%</xliff:g> restantes."</string>
+ <string name="factorytest_failed">"Falha no teste de fábrica"</string>
+ <string name="factorytest_not_system">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string>
+ <string name="factorytest_no_action">"Nenhum pacote foi encontrado que forneça a ação FACTORY_TEST."</string>
+ <string name="factorytest_reboot">"Reiniciar"</string>
+ <!-- no translation found for js_dialog_title (8143918455087008109) -->
+ <skip />
+ <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
+ <skip />
+ <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
+ <skip />
+ <string name="save_password_label">"Confirmar"</string>
+ <string name="save_password_message">"Deseja que o navegador se lembre desta senha?"</string>
+ <string name="save_password_notnow">"Não agora"</string>
+ <string name="save_password_remember">"Lembre-se"</string>
+ <string name="save_password_never">"Nunca"</string>
+ <string name="open_permission_deny">"Você não tem permissão para abrir essa página."</string>
+ <string name="text_copied">"Texto copiado para a área de transferência."</string>
+ <string name="more_item_label">"Mais"</string>
+ <string name="prepend_shortcut_label">"Menu+"</string>
+ <string name="menu_space_shortcut_label">"espaço"</string>
+ <string name="menu_enter_shortcut_label">"enter"</string>
+ <string name="menu_delete_shortcut_label">"excluir"</string>
+ <string name="search_go">"Procurar"</string>
+ <string name="oneMonthDurationPast">"1 mês atrás"</string>
+ <string name="beforeOneMonthDurationPast">"Antes de 1 mês atrás"</string>
+ <plurals name="num_seconds_ago">
+ <item quantity="one">"1 segundo atrás"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> segundos atrás"</item>
+ </plurals>
+ <plurals name="num_minutes_ago">
+ <item quantity="one">"1 minute atrás"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutos atrás"</item>
+ </plurals>
+ <plurals name="num_hours_ago">
+ <item quantity="one">"1 hora trás"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> horas atrás"</item>
+ </plurals>
+ <plurals name="num_days_ago">
+ <item quantity="one">"ontem"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dias atrás"</item>
+ </plurals>
+ <plurals name="in_num_seconds">
+ <item quantity="one">"em 1 segundo"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
+ </plurals>
+ <plurals name="in_num_minutes">
+ <item quantity="one">"em 1 minuto"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> minutos"</item>
+ </plurals>
+ <plurals name="in_num_hours">
+ <item quantity="one">"em 1 hora"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> horas"</item>
+ </plurals>
+ <plurals name="in_num_days">
+ <item quantity="one">"amanhã"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> dias"</item>
+ </plurals>
+ <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
+ <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
+ <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
+ <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
+ <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
+ <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
+ <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
+ <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
+ <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
+ <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
+ <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
+ <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
+ <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
+ <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
+ <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
+ <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <string name="preposition_for_date">"em %s"</string>
+ <string name="preposition_for_time">"a %s"</string>
+ <string name="preposition_for_year">"em %s"</string>
+ <string name="day">"dia"</string>
+ <string name="days">"dias"</string>
+ <string name="hour">"hora"</string>
+ <string name="hours">"horas"</string>
+ <string name="minute">"minuto"</string>
+ <string name="minutes">"minutos"</string>
+ <string name="second">"segundos"</string>
+ <string name="seconds">"segundos"</string>
+ <string name="week">"semana"</string>
+ <string name="weeks">"semanas"</string>
+ <string name="year">"ano"</string>
+ <string name="years">"anos"</string>
+ <string name="every_weekday">"Todo dia de semana (Seg–Sex)"</string>
+ <string name="daily">"Diariamente"</string>
+ <string name="weekly">"Semanalmente em <xliff:g id="DAY">%s</xliff:g>"</string>
+ <string name="monthly">"Mensalmente"</string>
+ <string name="yearly">"Anualmente"</string>
+ <string name="VideoView_error_title">"Não é possível reproduzir o vídeo"</string>
+ <!-- no translation found for VideoView_error_text_invalid_progressive_playback (897920883624437033) -->
+ <skip />
+ <string name="VideoView_error_text_unknown">"Sentimos muito, este vídeo não pode ser reproduzido."</string>
+ <string name="VideoView_error_button">"OK"</string>
+ <!-- no translation found for relative_time (1818557177829411417) -->
+ <skip />
+ <string name="noon">"meio-dia"</string>
+ <string name="Noon">"Meio-dia"</string>
+ <string name="midnight">"meia-noite"</string>
+ <string name="Midnight">"Meia-noite"</string>
+ <string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
+ <string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
+ <string name="selectAll">"Selecionar tudo"</string>
+ <string name="selectText">"Selecionar texto"</string>
+ <string name="stopSelectingText">"Interromper seleção de texto"</string>
+ <string name="cut">"Recortar"</string>
+ <string name="cutAll">"Recortar tudo"</string>
+ <string name="copy">"Copiar"</string>
+ <string name="copyAll">"Copiar tudo"</string>
+ <string name="paste">"Colar"</string>
+ <string name="copyUrl">"Copiar URL"</string>
+ <string name="inputMethod">"Método de entrada"</string>
+ <!-- no translation found for addToDictionary (726256909274177272) -->
+ <skip />
+ <string name="editTextMenuTitle">"Editar texto"</string>
+ <string name="low_internal_storage_view_title">"Pouco espaço"</string>
+ <string name="low_internal_storage_view_text">"O espaço de armazenamento do telefone está diminuindo."</string>
+ <string name="ok">"OK"</string>
+ <string name="cancel">"Cancelar"</string>
+ <string name="yes">"OK"</string>
+ <string name="no">"Cancelar"</string>
+ <!-- no translation found for dialog_alert_title (2049658708609043103) -->
+ <skip />
+ <string name="capital_on">"LIGAR"</string>
+ <string name="capital_off">"DESLIGADO"</string>
+ <string name="whichApplication">"Completar ação usando"</string>
+ <string name="alwaysUse">"Use por padrão para esta ação."</string>
+ <string name="clearDefaultHintMsg">"Limpar o padrão nas Configurações da página inicial&gt; Aplicativos &gt; Gerenciar aplicativos."</string>
+ <string name="chooseActivity">"Selecione uma ação"</string>
+ <string name="noApplications">"Nenhum aplicativo pode executar essa ação."</string>
+ <string name="aerr_title">"Sentimos muito."</string>
+ <string name="aerr_application">"O aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g>(processo <xliff:g id="PROCESS">%2$s</xliff:g>) parou inesperadamente. Tente novamente."</string>
+ <string name="aerr_process">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> parou inesperadamente. Tente novamente."</string>
+ <string name="anr_title">"Sentimos muito."</string>
+ <string name="anr_activity_application">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> (no aplicativo <xliff:g id="APPLICATION">%2$s</xliff:g>) não está respondendo."</string>
+ <string name="anr_activity_process">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g> em processamento) não está respondendo."</string>
+ <string name="anr_application_process">"O aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g> em processamento) não está respondendo."</string>
+ <string name="anr_process">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está respondendo."</string>
+ <string name="force_close">"Forçar fechamento"</string>
+ <!-- no translation found for report (4060218260984795706) -->
+ <skip />
+ <string name="wait">"Aguarde"</string>
+ <string name="debug">"Depuração"</string>
+ <string name="sendText">"Selecione uma ação para texto"</string>
+ <string name="volume_ringtone">"Volume da campainha"</string>
+ <string name="volume_music">"Volume da mídia"</string>
+ <string name="volume_music_hint_playing_through_bluetooth">"Reprodução usando Bluetooth"</string>
+ <string name="volume_call">"Volume da chamada recebida"</string>
+ <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
+ <skip />
+ <string name="volume_alarm">"Volume do alarme"</string>
+ <string name="volume_notification">"Volume da notificação"</string>
+ <string name="volume_unknown">"Volume"</string>
+ <string name="ringtone_default">"Ringtone padrão"</string>
+ <string name="ringtone_default_with_actual">"Ringtone padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_silent">"Silencioso"</string>
+ <string name="ringtone_picker_title">"Ringtones"</string>
+ <string name="ringtone_unknown">"Ringtone desconhecido"</string>
+ <plurals name="wifi_available">
+ <item quantity="one">"Rede Wi-Fi disponível"</item>
+ <item quantity="other">"Redes Wi-Fi disponíveis"</item>
+ </plurals>
+ <plurals name="wifi_available_detailed">
+ <item quantity="one">"Redes Wi-Fi abertas disponíveis"</item>
+ <item quantity="other">"Redes Wi-Fi abertas disponíveis"</item>
+ </plurals>
+ <string name="select_character">"Inserir caractere"</string>
+ <string name="sms_control_default_app_name">"Aplicativo desconhecido"</string>
+ <string name="sms_control_title">"Envio de mensagens SMS"</string>
+ <string name="sms_control_message">"Uma grande quantidade de mensagens SMS está sendo enviada. Selecione \"OK\" para continuar ou \"Cancelar\" para parar de enviar."</string>
+ <string name="sms_control_yes">"OK"</string>
+ <string name="sms_control_no">"Cancelar"</string>
+ <string name="date_time_set">"Definir"</string>
+ <string name="default_permission_group">"Padrão"</string>
+ <string name="no_permissions">"Nenhuma permissão é necessária"</string>
+ <string name="perms_hide"><b>"Ocultar"</b></string>
+ <string name="perms_show_all"><b>"Mostrar tudo"</b></string>
+ <string name="googlewebcontenthelper_loading">"Carregando…"</string>
+ <string name="usb_storage_title">"Conectado via USB"</string>
+ <string name="usb_storage_message">"Você conectou o telefone ao seu computador via USB. Selecione \"Montar\" se quiser copiar os arquivos entre seu computador e o cartão SD do telefone."</string>
+ <string name="usb_storage_button_mount">"Montar"</string>
+ <string name="usb_storage_button_unmount">"Não montar"</string>
+ <string name="usb_storage_error_message">"Há um problema com o uso do seu cartão SD para armazenamento USB."</string>
+ <string name="usb_storage_notification_title">"Conectado via USB"</string>
+ <string name="usb_storage_notification_message">"Selecione para copiar os arquivos para/do computador."</string>
+ <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
+ <skip />
+ <!-- no translation found for extmedia_format_title (8663247929551095854) -->
+ <skip />
+ <!-- no translation found for extmedia_format_message (3621369962433523619) -->
+ <skip />
+ <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
+ <skip />
+ <string name="select_input_method">"Selecionar método de entrada"</string>
+ <string name="fast_scroll_alphabet">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <string name="fast_scroll_numeric_alphabet">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <!-- no translation found for candidates_style (4333913089637062257) -->
+ <skip />
+ <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
+ <skip />
+ <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
+ <skip />
+ <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
+ <skip />
+ <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
+ <skip />
+ <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
+ <skip />
+ <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
+ <skip />
+ <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
+ <skip />
+ <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
+ <skip />
+ <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
+ <skip />
+ <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
+ <skip />
+ <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
+ <skip />
+ <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
+ <skip />
+ <!-- no translation found for activity_list_empty (4168820609403385789) -->
+ <skip />
+ <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
+ <skip />
+ <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
+ <skip />
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (1311810005957319690) -->
+ <skip />
+ <!-- no translation found for gadget_host_error_inflating (2613287218853846830) -->
+ <skip />
+ <!-- no translation found for ime_action_go (8320845651737369027) -->
+ <skip />
+ <!-- no translation found for ime_action_search (658110271822807811) -->
+ <skip />
+ <!-- no translation found for ime_action_send (2316166556349314424) -->
+ <skip />
+ <!-- no translation found for ime_action_next (3138843904009813834) -->
+ <skip />
+ <!-- no translation found for ime_action_done (8971516117910934605) -->
+ <skip />
+ <!-- no translation found for ime_action_default (2840921885558045721) -->
+ <skip />
+ <!-- no translation found for dial_number_using (5789176425167573586) -->
+ <skip />
+ <!-- no translation found for create_contact_using (4947405226788104538) -->
+ <skip />
+ <!-- no translation found for accessibility_compound_button_selected (5612776946036285686) -->
+ <skip />
+ <!-- no translation found for accessibility_compound_button_unselected (8864512895673924091) -->
+ <skip />
+</resources>
diff --git a/core/res/res/values-ro-rRO/donottranslate-cldr.xml b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
index 1ed2c81..3672c94 100644
--- a/core/res/res/values-ro-rRO/donottranslate-cldr.xml
+++ b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">azi</string>
<string name="tomorrow">mâine</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S, %d.%m.%Y</string>
+ <string name="date_time">%2$s, %1$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s, %1$s, %3$s/%2$s/%4$s - %10$s, %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s, %3$s.%2$s - %10$s, %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s, %1$s, %3$s %2$s - %10$s, %6$s, %8$s %7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s, %3$s.%2$s.%4$s - %10$s, %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s, %1$s, %2$s - %6$s, %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s, %2$s - %6$s, %5$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s %2$s - %6$s, %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s, %3$s %2$s - %10$s, %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s, %3$s %2$s - %10$s, %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s, %1$s, %3$s %2$s - %10$s, %6$s, %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s, %1$s, %3$s %2$s - %10$s, %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s, %3$s %2$s %4$s - %10$s, %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s, %3$s %2$s %4$s - %10$s, %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s, %1$s, %3$s %2$s %4$s - %10$s, %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s, %1$s, %3$s %2$s %4$s - %10$s, %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s %2$s - %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-ru-rRU/donottranslate-cldr.xml b/core/res/res/values-ru-rRU/donottranslate-cldr.xml
index 8faeb44..2b8c235 100644
--- a/core/res/res/values-ru-rRU/donottranslate-cldr.xml
+++ b/core/res/res/values-ru-rRU/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Сегодня</string>
<string name="tomorrow">Завтра</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e %B %Y г.</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s - %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s</string>
+ <string name="wday_date">%3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s </string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s </string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s г.</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s г.</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s - %8$s %7$s %9$s г.</string>
</resources>
diff --git a/core/res/res/values-ru/donottranslate-cldr.xml b/core/res/res/values-ru/donottranslate-cldr.xml
index 8faeb44..2b8c235 100644
--- a/core/res/res/values-ru/donottranslate-cldr.xml
+++ b/core/res/res/values-ru/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Сегодня</string>
<string name="tomorrow">Завтра</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e %B %Y г.</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %d.%m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s - %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s</string>
+ <string name="wday_date">%3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s </string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s </string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s г.</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s г.</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s - %8$s %7$s %9$s г.</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 2a15c43..048f6b1 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"Позволяет приложению изменять текущую конфигурацию, например локаль и общий размер шрифта."</string>
<string name="permlab_restartPackages">"перезапускать другие приложения"</string>
<string name="permdesc_restartPackages">"Разрешает приложению принудительно перезапускать другие приложения."</string>
- <string name="permlab_setProcessForeground">"предотвращать остановку"</string>
- <string name="permdesc_setProcessForeground">"Разрешает приложению запускать любые процессы на переднем плане так, что их нельзя прекратить. Не требуется обычным приложениям."</string>
<string name="permlab_forceBack">"принудительно закрывать приложения"</string>
<string name="permdesc_forceBack">"Позволяет приложению принудительно закрывать и переводить в фоновый режим действия, работающие на переднем плане. Не требуется обычным приложениям."</string>
<string name="permlab_dump">"получать внутреннее состояние системы"</string>
<string name="permdesc_dump">"Разрешает приложениям получать внутреннее состояние системы. Вредоносное ПО может получать множество личной и защищенной информации, которая обычно не была бы им доступна."</string>
- <string name="permlab_addSystemService">"публиковать службы низкого уровня"</string>
- <string name="permdesc_addSystemService">"Разрешает приложению публиковать собственные системные службы низкого уровня. Вредоносное ПО может взломать систему и украсть или повредить данные в ней."</string>
<string name="permlab_runSetActivityWatcher">"наблюдать и управлять запуском всех приложений"</string>
<string name="permdesc_runSetActivityWatcher">"Разрешает приложению следить и управлять тем, как система запускает действия. Вредоносное ПО может полностью нарушить работу системы. Это разрешение нужно только для разработки, но не при обычном использовании телефона."</string>
<string name="permlab_broadcastPackageRemoved">"отправлять оповещения об удалении пакетов"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"Позволяет приложению контролировать максимальное количество выполняемых процессов. Не требуется обычным приложениям."</string>
<string name="permlab_setAlwaysFinish">"закрывать все фоновые приложения"</string>
<string name="permdesc_setAlwaysFinish">"Разрешает приложению следить, чтобы действия всегда завершались после перехода в фоновый режим. Не требуется обычным приложениям."</string>
- <string name="permlab_fotaUpdate">"автоматически устанавливать системные обновления"</string>
- <string name="permdesc_fotaUpdate">"Разрешает приложению получать уведомления о предстоящих обновлениях системы и запускать их установку. Это дает вредоносному ПО возможность повредить систему неавторизованными обновлениями или помешать выполнению обновления."</string>
<string name="permlab_batteryStats">"изменять данные о батарее"</string>
<string name="permdesc_batteryStats">"Разрешает изменять данные о батарее. Не используется обычными приложениями."</string>
<string name="permlab_internalSystemWindow">"отображать неавторизованные окна"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"К сожалению, это видео не подходит для потокового воспроизведения на данном устройстве."</string>
<string name="VideoView_error_text_unknown">"К сожалению, это видео нельзя воспроизвести."</string>
<string name="VideoView_error_button">"ОК"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="noon">"полдень"</string>
<string name="Noon">"Полдень"</string>
<string name="midnight">"полночь"</string>
<string name="Midnight">"Полночь"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-sk-rSK/donottranslate-cldr.xml b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
index 05bc5d3..ea2a5ab 100644
--- a/core/res/res/values-sk-rSK/donottranslate-cldr.xml
+++ b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Dnes</string>
<string name="tomorrow">Zajtra</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e. %B %Y</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S %-e.%-m.%Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e.%-m.%Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e. %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s. - %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s.%2$s.%4$s - %10$s %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s. - %10$s %8$s.%7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s - %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s - %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s. - %8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s. - %8$s. %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-sl-rSI/donottranslate-cldr.xml b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
index e24b070..b9c30c9 100644
--- a/core/res/res/values-sl-rSI/donottranslate-cldr.xml
+++ b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Danes</string>
<string name="tomorrow">Jutri</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e. %m. %Y</string>
<string name="numeric_date_format">d. MM. yyyy</string>
+ <string name="numeric_date_template">"%s. %s. %s"</string>
<string name="month_day_year">%d. %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e. %b. %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e. %b. %Y</string>
<string name="month_day">%-e. %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s. %2$s. – %8$s. %7$s.</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s., %3$s. %2$s. – %6$s., %8$s. %7$s.</string>
+ <string name="numeric_mdy1_mdy2">%3$s. %2$s. %4$s – %8$s. %7$s. %9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s., %3$s. %2$s. %4$s – %6$s., %8$s. %7$s. %9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s. %2$s. – %10$s %8$s. %7$s.</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s. %4$s – %10$s %8$s. %7$s. %9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s. %2$s – %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s. %2$s – %10$s %8$s. %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s. %2$s – %10$s %8$s. %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s. %4$s – %10$s %8$s. %7$s. %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s. %4$s – %10$s %8$s. %7$s. %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s – %6$s, %9$s %7$s %8$s</string>
+ <string name="same_month_md1_md2">%3$s.–%8$s. %2$s.</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s. – %8$s. %7$s. %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s.–%8$s. %2$s. %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s., %3$s. %2$s. – %6$s., %8$s. %7$s. %9$s</string>
</resources>
diff --git a/core/res/res/values-sr-rRS/donottranslate-cldr.xml b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
index 7f98ae2..f88de6b 100644
--- a/core/res/res/values-sr-rRS/donottranslate-cldr.xml
+++ b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">данас</string>
<string name="tomorrow">сутра</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H.%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH.mm</string>
<string name="numeric_date">%-e.%-m.%Y.</string>
<string name="numeric_date_format">d.M.yyyy.</string>
+ <string name="numeric_date_template">"%s.%s.%s."</string>
<string name="month_day_year">%d. %B %Y.</string>
<string name="time_of_day">%H.%M.%S</string>
<string name="date_and_time">%H.%M.%S %d.%m.%Y.</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d.%m.%Y.</string>
<string name="month_day">%B %-e.</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e.</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b. %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s. - %8$s.%7$s.%9$s.</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s. - %6$s, %8$s.%7$s.%9$s.</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s. %4$s. - %10$s %6$s, %8$s. %7$s. %9$s.</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s. - %10$s %8$s.%7$s.%9$s.</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s. - %7$s %8$s.</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s. - %10$s %7$s %8$s.</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s. - %10$s %7$s %8$s.</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s. - %10$s %8$s. %7$s %9$s.</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s. %2$s %4$s. - %10$s %8$s. %7$s %9$s.</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s. - %10$s %6$s, %8$s. %7$s %9$s.</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s. %2$s %4$s. - %10$s %6$s, %8$s. %7$s %9$s.</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s %4$s. - %6$s, %8$s. %7$s %9$s.</string>
+ <string name="same_month_md1_md2">%3$s.-%8$s. %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s. %2$s - %6$s %8$s. %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s. %2$s - %8$s. %7$s %9$s.</string>
+ <string name="same_month_mdy1_mdy2">%3$s.-%8$s. %2$s %9$s.</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s.</string>
</resources>
diff --git a/core/res/res/values-sv-rSE/donottranslate-cldr.xml b/core/res/res/values-sv-rSE/donottranslate-cldr.xml
index 4570245..c846719 100644
--- a/core/res/res/values-sv-rSE/donottranslate-cldr.xml
+++ b/core/res/res/values-sv-rSE/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">idag</string>
<string name="tomorrow">imorgon</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k.%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H.mm</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y %b</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s – %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s – %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s/%2$s – %10$s %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %3$s %2$s – %10$s %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s %3$s %2$s %4$s – %10$s %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s – %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s – %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s–%8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s–%6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-th-rTH/donottranslate-cldr.xml b/core/res/res/values-th-rTH/donottranslate-cldr.xml
index cc680f6..53cd4d7 100644
--- a/core/res/res/values-th-rTH/donottranslate-cldr.xml
+++ b/core/res/res/values-th-rTH/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">วันนี้</string>
<string name="tomorrow">พรุ่งนี้</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%-e/%-m/%Y</string>
<string name="numeric_date_format">d/M/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%-e %B %Y</string>
<string name="time_of_day">%-k:%M:%S</string>
<string name="date_and_time">%-k:%M:%S, %-e %b %Y</string>
+ <string name="date_time">%2$s, %1$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s %3$s/%2$s – %6$s %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s – %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s %3$s/%2$s/%4$s – %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s, %1$s %3$s/%2$s/%4$s - %10$s, %6$s %8$s/%7$s/%9$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s, %3$s/%2$s - %10$s, %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s, %1$s, %3$s/%2$s - %10$s, %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s, %3$s/%2$s/%4$s - %10$s, %8$s/%7$s/%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s, %1$s %2$s - %6$s, %4$s %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s, %2$s - %6$s, %5$s</string>
+ <string name="time_wday_date">%1$s, %2$s %3$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s, %3$s %2$s - %10$s, %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s, %3$s %2$s - %10$s, %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s, %1$s %3$s %2$s - %10$s, %6$s %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s, %1$s %3$s %2$s - %10$s, %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s, %3$s %2$s %4$s - %10$s, %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s, %3$s %2$s %4$s - %10$s, %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s, %1$s %3$s %2$s %4$s - %10$s, %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s, %1$s %3$s %2$s %4$s - %10$s, %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s %4$s - %6$s %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s – %8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s – %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-tr-rTR/donottranslate-cldr.xml b/core/res/res/values-tr-rTR/donottranslate-cldr.xml
index acc0121..2475b21 100644
--- a/core/res/res/values-tr-rTR/donottranslate-cldr.xml
+++ b/core/res/res/values-tr-rTR/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Bugün</string>
<string name="tomorrow">Yarın</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%d %m %Y</string>
<string name="numeric_date_format">dd MM yyyy</string>
+ <string name="numeric_date_template">"%s %s %s"</string>
<string name="month_day_year">%d %B %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %d %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%d %b %Y</string>
<string name="month_day">%d %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%d %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%3$s.%2$s %1$s - %8$s.%7$s %6$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%3$s.%2$s.%4$s %1$s - %8$s.%7$s.%9$s %6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %3$s.%2$s.%4$s %1$s - %10$s %8$s.%7$s.%9$s %6$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s - %10$s %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %3$s/%2$s %1$s - %10$s %8$s/%7$s %6$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s %1$s - %6$s %5$s %4$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s %1$s - %5$s %4$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s %2$s</string>
+ <string name="wday_date">%3$s %2$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%3$s %2$s %1$s - %8$s %7$s %6$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s %1$s - %10$s %8$s %7$s %6$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %3$s %2$s %1$s - %10$s %8$s %7$s %6$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %3$s %2$s %4$s %1$s - %10$s %8$s %7$s %9$s %6$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %3$s %2$s %4$s %1$s - %10$s %8$s %7$s %9$s %6$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%3$s %2$s %4$s %1$s - %8$s %7$s %9$s %6$s</string>
+ <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%3$s %2$s %1$s - %8$s %7$s %6$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s %9$s %1$s - %8$s %7$s y %6$s</string>
</resources>
diff --git a/core/res/res/values-uk-rUA/donottranslate-cldr.xml b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
index 888df36..51dabd0 100644
--- a/core/res/res/values-uk-rUA/donottranslate-cldr.xml
+++ b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Сьогодні</string>
<string name="tomorrow">Завтра</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
+ <string name="numeric_date_template">"%s.%s.%s"</string>
<string name="month_day_year">%-e %B %Y р.</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%H:%M:%S %-e %b %Y</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%-e %b %Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%-b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%3$s.%2$s – %8$s.%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s – %6$s, %8$s.%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s – %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s – %6$s, %8$s.%7$s.%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s – %10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s – %10$s %8$s.%7$s.%9$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s – %6$s %4$s, %5$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s – %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+ <string name="time_wday_date">%1$s %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s %2$s – %6$s, %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s – %10$s %6$s, %8$s %7$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s – %10$s %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s – %10$s %8$s %7$s %9$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s – %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">%3$s–%8$s %2$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s %2$s – %6$s, %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">%3$s %2$s – %8$s %7$s %9$s</string>
+ <string name="same_month_mdy1_mdy2">%3$s–%8$s %2$s %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s – %6$s, %8$s %7$s %9$s</string>
</resources>
diff --git a/core/res/res/values-vi-rVN/donottranslate-cldr.xml b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
index 2a28b32..0d9eebc 100644
--- a/core/res/res/values-vi-rVN/donottranslate-cldr.xml
+++ b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">Ngày %d tháng %-m năm %Y</string>
<string name="time_of_day">%H:%M:%S</string>
<string name="date_and_time">%d-%m-%Y %H:%M:%S</string>
+ <string name="date_time">%1$s %2$s</string>
+ <string name="time_date">%3$s %1$s</string>
<string name="abbrev_month_day_year">%d-%m-%Y</string>
<string name="month_day">%-e %B</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%-e %b</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s - %2$s</string>
+ <string name="date1_date2">%2$s - %5$s</string>
+ <string name="numeric_md1_md2">%3$s/%2$s - %8$s/%7$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s/%2$s - %6$s, %8$s/%7$s</string>
+ <string name="numeric_mdy1_mdy2">%3$s/%2$s/%4$s - %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s/%2$s/%4$s - %6$s, %8$s/%7$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s-%2$s-%4$s %5$s - %6$s, %8$s-%7$s-%9$s %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%3$s-%2$s %5$s - %8$s-%7$s %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %3$s-%2$s %5$s - %6$s, %8$s-%7$s %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%3$s/%2$s/%4$s %5$s - %8$s/%7$s/%9$s %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s %2$s %3$s - %4$s %5$s %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s %2$s - %4$s %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s %3$s - %5$s %6$s</string>
+ <string name="time_wday_date">%2$s %3$s %1$s</string>
+ <string name="wday_date">%2$s %3$s</string>
+ <string name="time_wday">%2$s %1$s</string>
+ <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_md1_time1_md2_time2">%3$s %2$s %5$s - %8$s %7$s %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%3$s %2$s %5$s - %8$s %7$s %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s %3$s %2$s %5$s - %6$s %8$s %7$s %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s %3$s %2$s %5$s - %6$s %8$s %7$s %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">Ngày %3$s tháng %2$s năm %4$s %5$s - 'Ngày %8$s tháng %7$s năm %9$s %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">Ngày %3$s tháng %2$s năm %4$s %5$s - 'Ngày %8$s tháng %7$s năm %9$s %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s %2$s %4$s %5$s - %6$s, %8$s %7$s %9$s %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %3$s %2$s %4$s %5$s - %6$s, %8$s %7$s %9$s %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+ <string name="same_month_md1_md2">Ngày %3$s tháng %2$s - Ngày %8$s tháng %7$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s %3$s %2$s - %6$s %8$s %7$s</string>
+ <string name="same_year_mdy1_mdy2">Ngày %3$s tháng %2$s - Ngày %8$s tháng %7$s năm %9$s</string>
+ <string name="same_month_mdy1_mdy2">Ngày %3$s tháng %2$s - Ngày %8$s tháng M năm %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, ngày %3$s %2$s - %6$s, ngày %8$s %7$s năm %9$s</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/donottranslate-cldr.xml b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
index 18e37a9..6685a7d 100644
--- a/core/res/res/values-zh-rCN/donottranslate-cldr.xml
+++ b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">今天</string>
<string name="tomorrow">明天</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%p%-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
+ <string name="twelve_hour_time_format">ah:mm</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y-%-m-%-e</string>
<string name="numeric_date_format">yyyy-M-d</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
<string name="time_of_day">%p%I:%M:%S</string>
<string name="date_and_time">%p%I:%M:%S %Y-%-m-%-e</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y-%-m-%-e</string>
<string name="month_day">%B%-e日</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b%-e日</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y年%b</string>
+ <string name="time1_time2">%1$s–%2$s</string>
+ <string name="date1_date2">%2$s–%5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s至%7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s-%3$s%1$s至%7$s-%8$s%6$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s至%9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s-%2$s-%3$s%1$s至%9$s-%7$s-%8$s%6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s月%3$s日,%1$s–%10$s %9$s年%7$s月%8$s日,%6$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s–%10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s-%3$s%1$s–%10$s %7$s-%8$s%6$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s–%10$s %9$s-%7$s-%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s%1$s–%6$s %5$s%4$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s%1$s–%5$s%4$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s–%6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s%2$s</string>
+ <string name="wday_date">%3$s%2$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s%3$s日–%7$s%8$s日</string>
+ <string name="same_year_wday1_md1_wday2_md2">%2$s%3$s日%1$s–%7$s%8$s日%6$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s%3$s日–%10$s %7$s%8$s日</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s%3$s日–%10$s %7$s%8$s日</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日%1$s–%10$s %7$s%8$s日%6$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日%1$s–%10$s %7$s%8$s日%6$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日–%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日–%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日%1$s–%10$s %9$s年%7$s%8$s日%6$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日%1$s–%10$s %9$s年%7$s%8$s日%6$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%4$s年%2$s%3$s日%1$s–%9$s年%7$s%8$s日%6$s</string>
+ <string name="same_month_md1_md2">%2$s月%3$s日至%8$s日</string>
+ <string name="same_month_wday1_md1_wday2_md2">%2$s%3$s日%1$s–%7$s%8$s日%6$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s年%2$s%3$s日至%7$s月%8$s日</string>
+ <string name="same_month_mdy1_mdy2">%9$s年%2$s%3$s日至%8$s日</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s年%2$s%3$s日%1$s至%7$s月%8$s日%6$s</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index ee7b3cd..3be8aa0 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -166,14 +166,10 @@
<string name="permdesc_changeConfiguration">"允许应用程序更改当前配置,例如语言设置或整体的字体大小。"</string>
<string name="permlab_restartPackages">"重新启动其他应用程序"</string>
<string name="permdesc_restartPackages">"允许应用程序强制重新启动其他应用程序。"</string>
- <string name="permlab_setProcessForeground">"防止停止"</string>
- <string name="permdesc_setProcessForeground">"允许应用程序在前台运行任何进程,因此该进程不能被终止。普通应用程序从不需要使用此权限。"</string>
<string name="permlab_forceBack">"强制应用程序关闭"</string>
<string name="permdesc_forceBack">"允许应用程序强制前台的任何活动关闭和重新开始。普通应用程序从不需要使用此权限。"</string>
<string name="permlab_dump">"检索系统内部状态"</string>
<string name="permdesc_dump">"允许应用程序检索系统的内部状态。恶意应用程序可能会借此检索通常它们本不需要的各种私有和安全信息。"</string>
- <string name="permlab_addSystemService">"发布低级服务"</string>
- <string name="permdesc_addSystemService">"允许应用程序发布自己的低级系统服务。恶意应用程序可能会借此攻击系统,以及盗取或破坏系统中的任何数据。"</string>
<string name="permlab_runSetActivityWatcher">"监视和控制所有应用程序启动"</string>
<string name="permdesc_runSetActivityWatcher">"允许应用程序监视和控制系统启动活动的方式。恶意应用程序可能会借此彻底损坏系统。此权限仅在开发时才需要,普通的手机应用不需要。"</string>
<string name="permlab_broadcastPackageRemoved">"发送包删除的广播"</string>
@@ -186,8 +182,6 @@
<string name="permdesc_setProcessLimit">"允许应用程序控制运行的进程数上限。普通应用程序从不需要使用此权限。"</string>
<string name="permlab_setAlwaysFinish">"关闭所有后台应用程序"</string>
<string name="permdesc_setAlwaysFinish">"允许应用程序控制活动是否始终是一转至后台就完成。普通应用程序从不需要使用此权限。"</string>
- <string name="permlab_fotaUpdate">"自动安装系统更新"</string>
- <string name="permdesc_fotaUpdate">"允许应用程序接收有关未决系统更新的通知并安装这些更新。恶意应用程序可能会借此通过未经授权的更新破坏系统,通常情况下,它们会干扰更新过程。"</string>
<string name="permlab_batteryStats">"修改电池统计信息"</string>
<string name="permdesc_batteryStats">"允许修改收集的电池统计信息。普通应用程序不能使用此权限。"</string>
<string name="permlab_internalSystemWindow">"显示未授权的窗口"</string>
@@ -545,47 +539,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"抱歉,该视频不适合在此设备上播放。"</string>
<string name="VideoView_error_text_unknown">"很抱歉,此视频不能播放。"</string>
<string name="VideoView_error_button">"确定"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> 至 <xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g> 至 <xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g>至 <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> 至 <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="noon">"中午"</string>
<string name="Noon">"中午"</string>
<string name="midnight">"午夜"</string>
<string name="Midnight">"午夜"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至<xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日至 <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g>至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> 月 <xliff:g id="DAY1_0">%3$s</xliff:g> 日<xliff:g id="WEEKDAY1">%1$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> 至 <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> 月 <xliff:g id="DAY2_1">%8$s</xliff:g> 日<xliff:g id="WEEKDAY2">%6$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values-zh-rTW/donottranslate-cldr.xml b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
index 18e37a9..6685a7d 100644
--- a/core/res/res/values-zh-rTW/donottranslate-cldr.xml
+++ b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
@@ -91,13 +91,19 @@
<string name="today">今天</string>
<string name="tomorrow">明天</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%p%-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
+ <string name="twelve_hour_time_format">ah:mm</string>
+ <string name="twenty_four_hour_time_format">H:mm</string>
<string name="numeric_date">%Y-%-m-%-e</string>
<string name="numeric_date_format">yyyy-M-d</string>
+ <string name="numeric_date_template">"%s-%s-%s"</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
<string name="time_of_day">%p%I:%M:%S</string>
<string name="date_and_time">%p%I:%M:%S %Y-%-m-%-e</string>
+ <string name="date_time">%2$s %1$s</string>
+ <string name="time_date">%1$s %3$s</string>
<string name="abbrev_month_day_year">%Y-%-m-%-e</string>
<string name="month_day">%B%-e日</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b%-e日</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%Y年%b</string>
+ <string name="time1_time2">%1$s–%2$s</string>
+ <string name="date1_date2">%2$s–%5$s</string>
+ <string name="numeric_md1_md2">%2$s-%3$s至%7$s-%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%2$s-%3$s%1$s至%7$s-%8$s%6$s</string>
+ <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s至%9$s-%7$s-%8$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%4$s-%2$s-%3$s%1$s至%9$s-%7$s-%8$s%6$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s月%3$s日,%1$s–%10$s %9$s年%7$s月%8$s日,%6$s</string>
+ <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s–%10$s %7$s-%8$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %2$s-%3$s%1$s–%10$s %7$s-%8$s%6$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s–%10$s %9$s-%7$s-%8$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%3$s %2$s%1$s–%6$s %5$s%4$s</string>
+ <string name="wday1_date1_wday2_date2">%2$s%1$s–%5$s%4$s</string>
+ <string name="date1_time1_date2_time2">%3$s %2$s–%6$s %5$s</string>
+ <string name="time_wday_date">%1$s %3$s%2$s</string>
+ <string name="wday_date">%3$s%2$s</string>
+ <string name="time_wday">%1$s %2$s</string>
+ <string name="same_year_md1_md2">%2$s%3$s日–%7$s%8$s日</string>
+ <string name="same_year_wday1_md1_wday2_md2">%2$s%3$s日%1$s–%7$s%8$s日%6$s</string>
+ <string name="same_year_md1_time1_md2_time2">%5$s %2$s%3$s日–%10$s %7$s%8$s日</string>
+ <string name="same_month_md1_time1_md2_time2">%5$s %2$s%3$s日–%10$s %7$s%8$s日</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日%1$s–%10$s %7$s%8$s日%6$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s%3$s日%1$s–%10$s %7$s%8$s日%6$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日–%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s年%2$s%3$s日–%10$s %9$s年%7$s%8$s日</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日%1$s–%10$s %9$s年%7$s%8$s日%6$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %4$s年%2$s%3$s日%1$s–%10$s %9$s年%7$s%8$s日%6$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%4$s年%2$s%3$s日%1$s–%9$s年%7$s%8$s日%6$s</string>
+ <string name="same_month_md1_md2">%2$s月%3$s日至%8$s日</string>
+ <string name="same_month_wday1_md1_wday2_md2">%2$s%3$s日%1$s–%7$s%8$s日%6$s</string>
+ <string name="same_year_mdy1_mdy2">%9$s年%2$s%3$s日至%7$s月%8$s日</string>
+ <string name="same_month_mdy1_mdy2">%9$s年%2$s%3$s日至%8$s日</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s年%2$s%3$s日%1$s至%7$s月%8$s日%6$s</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index a742228..8cace66 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -161,14 +161,10 @@
<string name="permdesc_changeConfiguration">"允許應用程式變更目前設定,例如:地區設定或字型大小。"</string>
<string name="permlab_restartPackages">"重新啟動其他應用程式"</string>
<string name="permdesc_restartPackages">"允許應用程式強制重新啟動其他應用程式。"</string>
- <string name="permlab_setProcessForeground">"保持已停止狀態"</string>
- <string name="permdesc_setProcessForeground">"允許應用程式在前端執行任何程序 (無法中止)。一般應用程式不需要此功能。"</string>
<string name="permlab_forceBack">"強制關閉應用程式"</string>
<string name="permdesc_forceBack">"允許應用程式強制關閉在前端運作的活動並返回。一般應用程式不需要此功能。"</string>
<string name="permlab_dump">"接收系統內部狀態"</string>
<string name="permdesc_dump">"允許應用程式取得系統內部狀態。請注意:惡意程式可能利用此功能,不當取得私人或安全性資料。"</string>
- <string name="permlab_addSystemService">"發行低階服務"</string>
- <string name="permdesc_addSystemService">"允許應用程式發行自有低階系統服務。請注意:惡意程式可能利用此功能綁架系統或偷取、竄改資料內容。"</string>
<string name="permlab_runSetActivityWatcher">"監視控制所有應用程式啟動狀態。"</string>
<string name="permdesc_runSetActivityWatcher">"允許應用程式監控管理系統啟動活動。請注意:惡意程式可能因此癱瘓整個系統。此權限只在開發時需要,一般手機使用不需要此權限。"</string>
<string name="permlab_broadcastPackageRemoved">"傳送程式已移除廣播"</string>
@@ -181,8 +177,6 @@
<string name="permdesc_setProcessLimit">"允許應用程式控制可使用的最大執行緒。一般應用程式不需要此功能。"</string>
<string name="permlab_setAlwaysFinish">"關閉所有背景程式"</string>
<string name="permdesc_setAlwaysFinish">"允許應用程式控制哪些活動在被移到背景執行時,儘速結束。一般應用程式不需要此功能。"</string>
- <string name="permlab_fotaUpdate">"自動安裝系統更新"</string>
- <string name="permdesc_fotaUpdate">"允許應用程式接收可安裝系統更新的通知,並啟動安裝。請注意:惡意程式可能透過未授權的更新竄改系統,或干擾更新程序。"</string>
<string name="permlab_batteryStats">"編輯電池狀態"</string>
<string name="permdesc_batteryStats">"允許修改電池狀態。一般應用程式不會使用此功能。"</string>
<string name="permlab_internalSystemWindow">"顯示未授權視窗"</string>
@@ -539,47 +533,13 @@
<string name="VideoView_error_text_invalid_progressive_playback">"很抱歉,影片格式無效,裝置無法進行串流處理。"</string>
<string name="VideoView_error_text_unknown">"很抱歉,此影片無法播放。"</string>
<string name="VideoView_error_button">"確定"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>,<xliff:g id="WEEKDAY2">%4$s</xliff:g>,<xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>,<xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
- <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>,<xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>,<xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
- <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g>,<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g>,<xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>,<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="noon">"中午"</string>
<string name="Noon">"中午"</string>
<string name="midnight">"午夜"</string>
<string name="Midnight">"午夜"</string>
<!-- no translation found for month (7026169712234774086) -->
<skip />
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日 – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>,<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>,<xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_mdy1_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日 – <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日 – <xliff:g id="DAY2">%8$s</xliff:g> 日"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> 日 <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g> 日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g> 年 <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> 日,<xliff:g id="WEEKDAY1">%1$s</xliff:g>,<xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="YEAR2">%9$s</xliff:g> 年 <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g> 日,<xliff:g id="WEEKDAY2">%6$s</xliff:g>,<xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
<string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 9b9c2e4..66f0e82 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -131,7 +131,7 @@
the first component from this list which is found to be installed is set as the
preferred activity. -->
<string-array name="default_web_search_providers">
- <item>com.google.android.providers.genie/.GenieLauncher</item>
+ <item>com.google.android.providers.enhancedgooglesearch/.Launcher</item>
<item>com.android.googlesearch/.GoogleSearch</item>
<item>com.android.websearch/.Search.1</item>
</string-array>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8c4b714..d778f5c 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -79,9 +79,11 @@
<attr name="textColorPrimaryInverseNoDisable" format="reference|color" />
<!-- Dim inverse text color. This does not differentiate the disabled state. -->
<attr name="textColorSecondaryInverseNoDisable" format="reference|color" />
-
+
<!-- Text color for urls in search suggestions, used by things like global search and the browser. @hide -->
<attr name="textColorSearchUrl" format="reference|color" />
+ <!-- Search widget more corpus result item background. -->
+ <attr name="searchWidgetCorpusItemBackground" format="reference|color" />
<!-- Text color, typeface, size, and style for "large" text. Defaults to primary text color. -->
<attr name="textAppearanceLarge" format="reference" />
@@ -97,9 +99,9 @@
<!-- Text color, typeface, size, and style for "small" inverse text. Defaults to secondary inverse text color. -->
<attr name="textAppearanceSmallInverse" format="reference" />
- <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. @hide -->
- <attr name="textAppearanceSearchResultTitle" format="reference" />
- <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
+ <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. @hide -->
+ <attr name="textAppearanceSearchResultTitle" format="reference" />
+ <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
<attr name="textAppearanceSearchResultSubtitle" format="reference" />
@@ -669,7 +671,7 @@
<attr name="x" format="dimension" />
<!-- A coordinate in the Y dimension. -->
<attr name="y" format="dimension" />
-
+
<!-- Specifies how to place the content of an object, both
on the x and y axis, within the object itself. -->
<attr name="gravity">
@@ -1381,19 +1383,6 @@
will use only the number of items in the adapter and the number of items visible
on screen to determine the scrollbar's properties. -->
<attr name="smoothScrollbar" format="boolean" />
- <!-- Defines the type of gesture to enable for the widget. -->
- <attr name="gestures">
- <!-- No gesture -->
- <enum name="none" value="0" />
- <!-- Gestures jump to a specific position in the content. This requires
- fast scroll to be enabled. If fast scroll is enabled from XML,
- jump gestures will be enabled automatically. -->
- <enum name="jump" value="1" />
- <!-- Gestures filter the content. This requires text filtering to be enabled.
- If text filtering is enabled from XML, filter gestures will be enabled
- automatically. -->
- <enum name="filter" value="2" />
- </attr>
</declare-styleable>
<declare-styleable name="AbsSpinner">
<!-- Reference to an array resource that will populate the Spinner. For static content,
@@ -2848,16 +2837,24 @@
string will be placed in the data field of the {@link android.content.Intent Intent}
when the user clicks a suggestion. <i>Optional attribute.</i> -->
<attr name="searchSuggestIntentData" format="string" />
-
+
<!-- If provided, this is the minimum number of characters needed to trigger
search suggestions. The default value is 0. <i>Optional attribute.</i> -->
<attr name="searchSuggestThreshold" format="integer" />
-
+
<!-- If provided and <code>true</code>, this searchable activity will be
included in any global lists of search targets.
The default value is <code>false</code>. <i>Optional attribute.</i>. -->
<attr name="includeInGlobalSearch" format="boolean" />
-
+
+ <!-- If provided and <code>true</code>, this searchable activity will be invoked for all
+ queries in a particular session. If set to <code>false</code> and the activity
+ returned zero results for a query, it will not be invoked again in that session for
+ supersets of that zero-results query. For example, if the activity returned zero
+ results for "bo", it would not be queried again for "bob".
+ The default value is <code>false</code>. <i>Optional attribute.</i>. -->
+ <attr name="queryAfterZeroResults" format="boolean" />
+
</declare-styleable>
<!-- In order to process special action keys during search, you must define them using
@@ -3290,7 +3287,6 @@
<attr name="configure" format="string" />
</declare-styleable>
-
<!-- =============================== -->
<!-- Accounts package class attributes -->
<!-- =============================== -->
@@ -3301,6 +3297,10 @@
<declare-styleable name="AccountAuthenticator">
<!-- the account type this authenticator handles. -->
<attr name="accountType" format="string"/>
+ <!-- the user-visible name of the authenticator. -->
+ <attr name="label"/>
+ <!-- the icon of the authenticator. -->
+ <attr name="icon"/>
</declare-styleable>
<!-- =============================== -->
@@ -3316,6 +3316,5 @@
<attr name="accountType"/>
</declare-styleable>
-
</resources>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0a2d208..91cd9fd 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -596,7 +596,8 @@
{@link #AndroidManifestUsesPermission uses-permission},
{@link #AndroidManifestUsesConfiguration uses-configuration},
{@link #AndroidManifestApplication application},
- {@link #AndroidManifestInstrumentation instrumentation}. -->
+ {@link #AndroidManifestInstrumentation instrumentation},
+ {@link #AndroidManifestUsesFeature uses-feature}. -->
<declare-styleable name="AndroidManifest">
<attr name="versionCode" />
<attr name="versionName" />
@@ -765,6 +766,22 @@
<attr name="reqFiveWayNav" />
</declare-styleable>
+ <!-- The <code>uses-feature</code> tag specifies
+ a specific feature used by the application.
+ For example an application might specify that it requires
+ specific version of open gl. Multiple such attribute
+ values can be specified by the application.
+
+ <p>This appears as a child tag of the root
+ {@link #AndroidManifest manifest} tag. -->
+ <declare-styleable name="AndroidManifestUsesFeature" parent="AndroidManifest">
+ <!-- The GLES driver version number needed by an application.
+ The higher 16 bits represent the major number and the lower 16 bits
+ represent the minor number. For example for GL 1.2 referring to
+ 0x00000102, the actual value should be set as 0x00010002. -->
+ <attr name="glEsVersion" format="integer"/>
+ </declare-styleable>
+
<!-- The <code>uses-sdk</code> tag describes the SDK features that the
containing package must be running on to operate correctly.
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index f67f04c..d284d0f 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -75,6 +75,7 @@
<!-- For search-related UIs -->
<color name="search_url_text">#7fa87f</color>
+ <color name="search_widget_corpus_item_background">@android:color/lighter_gray</color>
</resources>
diff --git a/core/res/res/values/donottranslate-cldr.xml b/core/res/res/values/donottranslate-cldr.xml
index f305948..56c58e2 100644
--- a/core/res/res/values/donottranslate-cldr.xml
+++ b/core/res/res/values/donottranslate-cldr.xml
@@ -85,19 +85,25 @@
<string name="day_of_week_shortest_friday">F</string>
<string name="day_of_week_shortest_saturday">S</string>
- <string name="am">a.m.</string>
- <string name="pm">p.m.</string>
+ <string name="am">am</string>
+ <string name="pm">pm</string>
<string name="yesterday">Yesterday</string>
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
+ <string name="twelve_hour_time_format">h:mm a</string>
+ <string name="twenty_four_hour_time_format">HH:mm</string>
<string name="numeric_date">%-m/%-e/%Y</string>
<string name="numeric_date_format">M/d/yyyy</string>
+ <string name="numeric_date_template">"%s/%s/%s"</string>
<string name="month_day_year">%B %-e, %Y</string>
<string name="time_of_day">%-l:%M:%S %p</string>
- <string name="date_and_time">%-l:%M:%S %p %b %-e, %Y</string>
+ <string name="date_and_time">%b %-e, %Y, %-l:%M:%S %p</string>
+ <string name="date_time">%1$s, %2$s</string>
+ <string name="time_date">%1$s, %3$s</string>
<string name="abbrev_month_day_year">%b %-e, %Y</string>
<string name="month_day">%B %-e</string>
<string name="month">%-B</string>
@@ -105,4 +111,36 @@
<string name="abbrev_month_day">%b %-e</string>
<string name="abbrev_month">%-b</string>
<string name="abbrev_month_year">%b %Y</string>
+ <string name="time1_time2">%1$s – %2$s</string>
+ <string name="date1_date2">%2$s – %5$s</string>
+ <string name="numeric_md1_md2">%2$s/%3$s – %7$s/%8$s</string>
+ <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s/%3$s – %6$s, %7$s/%8$s</string>
+ <string name="numeric_mdy1_mdy2">%2$s/%3$s/%4$s – %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %2$s/%3$s/%4$s – %6$s, %7$s/%8$s/%9$s</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s/%3$s/%4$s, %5$s – %6$s, %7$s/%8$s/%9$s, %10$s</string>
+ <string name="numeric_md1_time1_md2_time2">%2$s/%3$s, %5$s – %7$s/%8$s, %10$s</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s/%3$s, %5$s – %6$s, %7$s/%8$s, %10$s</string>
+ <string name="numeric_mdy1_time1_mdy2_time2">%2$s/%3$s/%4$s, %5$s – %7$s/%8$s/%9$s, %10$s</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">%1$s, %2$s, %3$s – %4$s, %5$s, %6$s</string>
+ <string name="wday1_date1_wday2_date2">%1$s, %2$s – %4$s, %5$s</string>
+ <string name="date1_time1_date2_time2">%2$s, %3$s – %5$s, %6$s</string>
+ <string name="time_wday_date">%1$s, %2$s, %3$s</string>
+ <string name="wday_date">%2$s, %3$s</string>
+ <string name="time_wday">%1$s, %2$s</string>
+ <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+ <string name="same_year_wday1_md1_wday2_md2">%1$s, %2$s %3$s – %6$s, %7$s %8$s</string>
+ <string name="same_year_md1_time1_md2_time2">%2$s %3$s, %5$s – %7$s %8$s, %10$s</string>
+ <string name="same_month_md1_time1_md2_time2">%2$s %3$s, %5$s – %7$s %8$s, %10$s</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s – %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">%1$s, %2$s %3$s, %5$s – %6$s, %7$s %8$s, %10$s</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s – %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">%2$s %3$s, %4$s, %5$s – %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s – %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%1$s, %2$s %3$s, %4$s, %5$s – %6$s, %7$s %8$s, %9$s, %10$s</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s, %4$s – %6$s, %7$s %8$s, %9$s</string>
+ <string name="same_month_md1_md2">%2$s %3$s – %8$s</string>
+ <string name="same_month_wday1_md1_wday2_md2">%1$s, %2$s %3$s – %6$s, %7$s %8$s</string>
+ <string name="same_year_mdy1_mdy2">%2$s %3$s – %7$s %8$s, %9$s</string>
+ <string name="same_month_mdy1_mdy2">%2$s %3$s – %8$s, %9$s</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s – %6$s, %7$s %8$s, %9$s</string>
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ca32cdd..41db0fa 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1106,7 +1106,6 @@
<public type="attr" name="uncertainGestureColor" />
<public type="attr" name="fadeOffset" />
<public type="attr" name="fadeDuration" />
- <public type="attr" name="gestures" />
<public type="attr" name="gestureStrokeType" />
<public type="attr" name="gestureStrokeLengthThreshold" />
<public type="attr" name="gestureStrokeSquarenessThreshold" />
@@ -1115,6 +1114,8 @@
<public type="attr" name="fadeEnabled" />
<public type="attr" name="backupAgent" />
<public type="attr" name="allowBackup" />
+ <public type="attr" name="glEsVersion" />
+ <public type="attr" name="queryAfterZeroResults" />
<public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2aed931..19fde5c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -30,6 +30,11 @@
<string name="terabyteShort">TB</string>
<!-- Suffix added to a number to signify size in petabytes. -->
<string name="petabyteShort">PB</string>
+ <!-- Format string used to add a suffix like "KB" or "MB" to a number
+ to display a size in kilobytes, megabytes, or other size units.
+ Some languages (like French) will want to add a space between
+ the placeholders. -->
+ <string name="fileSizeSuffix"><xliff:g id="number" example="123">%1$s</xliff:g><xliff:g id="unit" example="KB">%2$s</xliff:g></string>
<!-- Used in Contacts for a field that has no label and in Note Pad
for a note with no name. -->
@@ -463,13 +468,6 @@
forcibly restart other applications.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_setProcessForeground">keep from being stopped</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_setProcessForeground">Allows an application to make
- any process run in the foreground, so it can\'t be killed.
- Should never be needed for normal applications.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_forceBack">force application to close</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_forceBack">Allows an application to force any
@@ -485,13 +483,6 @@
never normally need.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_addSystemService">publish low-level services</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_addSystemService">Allows application to publish
- its own low-level system services. Malicious applications may hijack
- the system, and steal or corrupt any data on it.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_shutdown">partial shutdown</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_shutdown">Puts the activity manager into a shutdown
@@ -550,15 +541,6 @@
go to the background. Never needed for normal applications.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_fotaUpdate">automatically install system updates</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_fotaUpdate">Allows an application to receive
- notifications about pending system updates and trigger their
- installation. Malicious applications may use this to corrupt the system
- with unauthorized updates, or generally interfere with the update
- process.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_batteryStats">modify battery statistics</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_batteryStats">Allows the modification of
@@ -1538,49 +1520,12 @@
<string name="VideoView_error_button">OK</string>
- <!-- Format indicating a range of time, from a time on one day to a time on another day.
- Example: "Mon, Dec 31, 2007, 8am - Tue, Jan 1, 2008, 5pm" -->
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="weekday1" example="Monday">%1$s</xliff:g>, <xliff:g id="date1" example="December 31, 2007">%2$s</xliff:g>, <xliff:g id="time1" example="8am">%3$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Tuesday">%4$s</xliff:g>, <xliff:g id="date2" example="January 1, 2008">%5$s</xliff:g>, <xliff:g id="time2" example="5pm">%6$s</xliff:g>"</string>
-
- <!-- Format indicating a range of dates, from one date to another.
- Example: "Mon, Dec 31, 2007 - Tue, Jan 1, 2008" -->
- <string name="wday1_date1_wday2_date2">"<xliff:g id="weekday1" example="Monday">%1$s</xliff:g>, <xliff:g id="date1" example="Dec 31, 2007">%2$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Thursday">%4$s</xliff:g>, <xliff:g id="date2" example="Jan 1, 2008">%5$s</xliff:g>"</string>
-
- <!-- Format indicating a range of time, from a time on one day to a time on another day.
- Example: "Dec 31, 2007, 8am - Jan 1, 2008, 5pm" -->
- <string name="date1_time1_date2_time2">"<xliff:g id="date1" example="Dec 31, 2007">%2$s</xliff:g>, <xliff:g id="time1" example="8am">%3$s</xliff:g> \u2013 <xliff:g id="date2" example="Jan 1, 2008">%5$s</xliff:g>, <xliff:g id="time2" example="5pm">%6$s</xliff:g>"</string>
-
- <!-- Format indicating a range of dates, from one date to another.
- Example: "Dec 31, 2007 - Jan 1, 2008" -->
- <string name="date1_date2">"<xliff:g id="date1" example="Dec 31, 2007">%2$s</xliff:g> \u2013 <xliff:g id="date2" example="Jan 1, 2008">%5$s</xliff:g>"</string>
-
- <!-- Format indicating a range of times, from one time to another.
- Example: "10:00 - 11:00 am" -->
- <string name="time1_time2">"<xliff:g id="time1" example="10:00">%1$s</xliff:g> \u2013 <xliff:g id="time2" example="11:00">%2$s</xliff:g>"</string>
- <!-- Format indicating a range of times on a particular date.
- Example: "8:00 - 11:00 am, Mon, Dec 31, 2007" -->
- <string name="time_wday_date">"<xliff:g id="time_range" example="8:00 - 11:00 am">%1$s</xliff:g>, <xliff:g id="weekday" example="Mon">%2$s</xliff:g>, <xliff:g id="date" example="Dec 31, 2007">%3$s</xliff:g>"</string>
-
- <!-- Format indicating a weekday and date.
- Example: "Mon, Dec 31, 2007" -->
- <string name="wday_date">"<xliff:g id="weekday" example="Monday">%2$s</xliff:g>, <xliff:g id="date" example="Dec 31, 2007">%3$s</xliff:g>"</string>
-
- <!-- Format indicating a range of times on a particular date.
- Example: "8:00 - 11:00 am, Dec 31, 2007" -->
- <string name="time_date">"<xliff:g id="time_range" example="8:00 - 11:00 am">%1$s</xliff:g>, <xliff:g id="date" example="Dec 31, 2007">%3$s</xliff:g>"</string>
-
- <!-- Format indicating a specific date and time.
- Example: "Dec 31, 2007, 11:00 am" -->
- <string name="date_time">"<xliff:g id="date" example="Dec 31, 2007">%1$s</xliff:g>, <xliff:g id="time" example="11:00 am">%2$s</xliff:g>"</string>
<!-- Format indicating a relative expression and time.
Example: "4 hours ago, 11:00 am" -->
<string name="relative_time">"<xliff:g id="date" example="4 hours ago">%1$s</xliff:g>, <xliff:g id="time" example="11:00 am">%2$s</xliff:g>"</string>
- <!-- Format indicating a range of times on a particular day of the week.
- Example: "8:00 - 11:00 am, Mon" -->
- <string name="time_wday">"<xliff:g id="time_range" example="8:00 - 11:00 am">%1$s</xliff:g>, <xliff:g id="weekday" example="Mon">%2$s</xliff:g>"</string>
<!-- Quoted name for 12pm, lowercase -->
<string name="noon">"noon"</string>
@@ -1591,103 +1536,13 @@
<!-- Quoted name for 12am, uppercase first letter -->
<string name="Midnight">"Midnight"</string>
- <!-- Format indicating a range of dates in the same year.
- Example: "Oct 31 - Nov 3" -->
- <string name="same_year_md1_md2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>"</string>
-
- <!-- Format indicating a range of dates in the same year, with weekday.
- Example: "Wed, Oct 31 - Sat, Nov 3" -->
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>"</string>
-
- <!-- Format indicating a range of dates in the same year.
- Example: "Oct 31 - Nov 3, 2007" -->
- <string name="same_year_mdy1_mdy2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year" example="2007">%9$s</xliff:g>"</string>
-
- <!-- Format indicating a range of dates in the same year, with weekdays.
- Example: "Wed, Oct 31 - Sat, Nov 3, 2007" -->
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year" example="2007">%9$s</xliff:g>"</string>
-
- <!-- Format indicating a range of time from a time on one day to a time on another.
- Example: "Oct 31, 8:00am - Nov 3, 5:00pm" -->
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
- <!-- Format indicating a range of time from a time on one day to a time on another, with weekdays.
- Example: "Wed, Oct 31, 8:00am - Sat, Nov 3, 5:00pm" -->
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id ="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
- <!-- Format indicating a range of time from a time on one day to a time on another, with years and weekdays.
- Example: "Oct 31, 2007, 8:00am - Nov 3, 2007, 5:00pm" -->
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
- <!-- Format indicating a range of time from a time on one day to a time on another.
- Example: "Wed, Oct 31, 2007, 8:00am - Sat, Nov 3, 2007, 5:00pm" -->
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
-
- <!-- Format indicating a range of (numeric) dates.
- Example: "10/31 - 11/3" -->
- <string name="numeric_md1_md2">"<xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates.
- Example: "Wed, 10/31 - Sat, 11/3" -->
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates.
- Example: "10/31/2007 - 11/3/2007" -->
- <string name="numeric_mdy1_mdy2">"<xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g>/<xliff:g id="year1" example="2007">%4$s</xliff:g> \u2013 <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>/<xliff:g id="year2" example="2007">%9$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates.
- Example: "Wed, 10/31/2007 - Sat, 11/3/2007" -->
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g>/<xliff:g id="year1" example="2007">%4$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>/<xliff:g id="year2" example="2007">%9$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates and times.
- Example: "10/31, 8:00am - 11/3, 5:00pm" -->
- <string name="numeric_md1_time1_md2_time2">"<xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates and times.
- Example: "Wed, 10/31, 8:00am - Sat, 11/3, 5:00pm" -->
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates and times.
- Example: "10/31/2007, 8:00am - 11/3/2007, 5:00pm" -->
- <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g>/<xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>/<xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
- <!-- Format indicating a range of (numeric) dates and times.
- Example: "Wed, 10/31/2007, 8:00am - Sat, 11/3/2007, 5:00pm" -->
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="10">%2$s</xliff:g>/<xliff:g id="day1" example="31">%3$s</xliff:g>/<xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="11">%7$s</xliff:g>/<xliff:g id="day2" example="30">%8$s</xliff:g>/<xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
-
-
- <!-- Format indicating a range of dates.
- Example: "Oct 9 - 10" -->
- <string name="same_month_md1_md2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="day2" example="3">%8$s</xliff:g>"</string>
- <!-- Format indicating a range of dates.
- Example: "Tue, Oct 9 - Wed, Oct 10" -->
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>"</string>
- <!-- Format indicating a range of dates.
- Example: "Oct 9 - 10, 2007" -->
- <string name="same_month_mdy1_mdy2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>"</string>
- <!-- Format indicating a range of dates.
- Example: "Tue, Oct 9, 2007 - Wed, Oct 10, 2007" -->
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="year1" example="2007">%4$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>"</string>
- <!-- Format indicating a range of dates and times.
- Example: "Oct 9, 8:00am - Oct 10, 5:00pm" -->
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
- <!-- Format indicating a range of dates and times.
- Example: "Tue, Oct 9, 8:00am - Wed, Oct 10, 5:00pm" -->
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
- <!-- Format indicating a range of dates and times.
- Example: "Oct 9, 2007, 8:00am - Oct 10, 2007, 5:00pm" -->
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
- <!-- Format indicating a range of dates and times.
- Example: "Tue, Oct 9, 2007, 8:00am - Wed, Oct 10, 2007, 5:00pm" -->
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="weekday1" example="Wed">%1$s</xliff:g>, <xliff:g id="month1" example="Oct">%2$s</xliff:g> <xliff:g id="day1" example="31">%3$s</xliff:g>, <xliff:g id="year1" example="2007">%4$s</xliff:g>, <xliff:g id="time1" example="8:00am">%5$s</xliff:g> \u2013 <xliff:g id="weekday2" example="Sat">%6$s</xliff:g>, <xliff:g id="month2" example="Nov">%7$s</xliff:g> <xliff:g id="day2" example="3">%8$s</xliff:g>, <xliff:g id="year2" example="2007">%9$s</xliff:g>, <xliff:g id="time2" example="5:00pm">%10$s</xliff:g>"</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 72402d0..648a7dd 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -124,6 +124,12 @@
<item name="windowExitAnimation">@anim/shrink_fade_out_from_bottom</item>
</style>
+ <!-- {@hide} -->
+ <style name="Animation.SlidingCard">
+ <item name="windowEnterAnimation">@anim/slide_in_up</item>
+ <item name="windowExitAnimation">@anim/slide_out_down</item>
+ </style>
+
<!-- Window animations that are applied to input method overlay windows.
{@hide Pending API council approval} -->
<style name="Animation.InputMethod">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 1c87220..f37d514 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -183,6 +183,9 @@
<item name="editTextPreferenceStyle">@android:style/Preference.DialogPreference.EditTextPreference</item>
<item name="ringtonePreferenceStyle">@android:style/Preference.RingtonePreference</item>
<item name="preferenceLayoutChild">@android:layout/preference_child</item>
+
+ <!-- Search widget styles -->
+ <item name="searchWidgetCorpusItemBackground">@android:color/search_widget_corpus_item_background</item>
</style>
<!-- Variant of the default (dark) theme with no title bar -->
diff --git a/core/res/res/xml/power_profile_default.xml b/core/res/res/xml/power_profile.xml
index ceecb1a..859902e 100644
--- a/core/res/res/xml/power_profile_default.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -19,19 +19,22 @@
<device name="Android">
<item name="none">0</item>
- <item name="screen.on">30</item>
- <item name="bluetooth.active">103</item>
- <item name="bluetooth.on">5</item>
- <item name="screen.full">114</item>
- <item name="wifi.on">23</item>
- <item name="wifi.active">200</item>
- <item name="wifi.scan">200</item>
- <item name="cpu.idle">1.6</item>
- <item name="cpu.normal">100</item>
- <item name="cpu.full">140</item>
- <item name="dsp.audio">70</item>
- <item name="dsp.video">100</item>
- <item name="radio.on">3</item>
- <item name="radio.active">175</item>
- <item name="gps.on">120</item>
+ <item name="screen.on">0.1</item>
+ <item name="bluetooth.active">0.1</item>
+ <item name="bluetooth.on">0.1</item>
+ <item name="screen.full">0.1</item>
+ <item name="wifi.on">0.1</item>
+ <item name="wifi.active">0.1</item>
+ <item name="wifi.scan">0.1</item>
+ <item name="cpu.idle">0.1</item>
+ <item name="cpu.normal">0.2</item>
+ <item name="cpu.full">1</item>
+ <item name="dsp.audio">0.1</item>
+ <item name="dsp.video">0.1</item>
+ <item name="radio.active">1</item>
+ <item name="gps.on">1</item>
+ <array name="radio.on"> <!-- Strength 0 to BINS-1 -->
+ <value>1</value>
+ <value>0.1</value>
+ </array>
</device>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index ea326b0..07d0abe 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -5,32 +5,36 @@ home=true
<div id="mainBodyFixed">
<div id="mainBodyLeft">
<div id="homeMiddle">
- <div id="homeTitle">
- <h2>Developer Announcements</h2>
- </div><!-- end homeTitle -->
- <div id="announcement-block">
- <!-- total max width is 520px -->
- <img src="{@docRoot}assets/images/home/IO-logo.png" alt="Google I/O Developer Conference 2009" width="242px" />
- <div id="announcement" style="width:270px">
- <p>Google I/O is a two-day developer event that will take place May 27-28 at Moscone Center, San Francisco. The agenda includes a number of great sessions on Android topics by team engineers and other developers.</p>
- <p><a href="http://code.google.com/events/io/">Learn more &raquo;</a></p>
- </div> <!-- end annoucement -->
- </div> <!-- end annoucement-block -->
- <div id="carouselMain">
- <div id="bulletinImg"></div>
- <div id="bulletinDesc"></div>
- </div>
- <div class="clearer"></div>
- <div class="app-list-container" align="center">
- <a href="javascript:{}" id="arrow-left" onclick="" class="arrow-left-off"></a>
- <div id="list-clip">
- <div style="left: 0px;" id="app-list">
- <!-- populated by buildCarousel() -->
- </div>
- </div><!-- end list-clip -->
- <a href="javascript:page_right()" id="arrow-right" onclick="" class="arrow-right-on"></a>
+ <div id="topAnnouncement">
+ <div id="homeTitle">
+ <h2>Developer Announcements</h2>
+ </div><!-- end homeTitle -->
+ <div id="announcement-block">
+ <!-- total max width is 520px -->
+ <img src="/assets/images/home/IO-logo.png" alt="Google I/O Developer Conference 2009" width="242px" />
+ <div id="announcement" style="width:270px">
+ <p>Google I/O is a two-day developer event that will take place May 27-28 at Moscone Center, San Francisco. The agenda includes a number of great sessions on Android topics by team engineers and other developers.</p>
+ <p><a href="http://code.google.com/events/io/">Learn more &raquo;</a></p>
+ </div> <!-- end annoucement -->
+ </div> <!-- end annoucement-block -->
+ </div><!-- end topAnnouncement -->
+ <div id="carousel">
+ <div id="carouselMain">
+ <div id="bulletinImg"></div>
+ <div id="bulletinDesc"></div>
+ </div>
<div class="clearer"></div>
- </div><!-- end app-list container -->
+ <div class="app-list-container" align="center">
+ <a href="javascript:{}" id="arrow-left" onclick="" class="arrow-left-off"></a>
+ <div id="list-clip">
+ <div style="left: 0px;" id="app-list">
+ <!-- populated by buildCarousel() -->
+ </div>
+ </div><!-- end list-clip -->
+ <a href="javascript:page_right()" id="arrow-right" onclick="" class="arrow-right-on"></a>
+ <div class="clearer"></div>
+ </div><!-- end app-list container -->
+ </div><!-- end carousel -->
</div><!-- end homeMiddle -->
<div style="clear:both">&nbsp;</div>
diff --git a/docs/html/search.jd b/docs/html/search.jd
index 0a802a6..defba30 100644
--- a/docs/html/search.jd
+++ b/docs/html/search.jd
@@ -2,7 +2,7 @@ page.title=Search Results
@jd:body
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
-<script src="/assets/jquery-history.js" type="text/javascript"></script>
+<script src="{@docRoot}assets/jquery-history.js" type="text/javascript"></script>
<script type="text/javascript">
google.load('search', '1');
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 469098c..207e4e7 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -34,7 +34,7 @@ class IMediaPlayerService: public IInterface
public:
DECLARE_META_INTERFACE(MediaPlayerService);
- virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
+ virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0;
@@ -57,4 +57,3 @@ public:
}; // namespace android
#endif // ANDROID_IMEDIAPLAYERSERVICE_H
-
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 7f0e7b3..7bf555a 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -123,4 +123,3 @@ public:
#endif // ANDROID_MEDIAPLAYERINTERFACE_H
-
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 704a8cb..ffb325d 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -82,7 +82,7 @@ enum media_error_type {
// 0xx: Reserved
// 7xx: Android Player info/warning (e.g player lagging behind.)
// 8xx: Media info/warning (e.g media badly interleaved.)
-//
+//
enum media_info_type {
// 0xx
MEDIA_INFO_UNKNOWN = 1,
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 7555521..ad27903 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -33,7 +33,7 @@ class ICamera;
typedef void (*media_completion_f)(status_t status, void *cookie);
/* Do not change these values without updating their counterparts
- * in java/android/android/media/MediaRecorder.java!
+ * in media/java/android/media/MediaRecorder.java!
*/
enum audio_source {
AUDIO_SOURCE_DEFAULT = 0,
@@ -41,26 +41,47 @@ enum audio_source {
AUDIO_SOURCE_VOICE_UPLINK = 2,
AUDIO_SOURCE_VOICE_DOWNLINK = 3,
AUDIO_SOURCE_VOICE_CALL = 4,
- AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_CALL
+ AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_CALL,
+
+ AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type
};
enum video_source {
VIDEO_SOURCE_DEFAULT = 0,
VIDEO_SOURCE_CAMERA = 1,
+
+ VIDEO_SOURCE_LIST_END // must be last - used to validate audio source type
};
-//Please update java/android/android/media/MediaRecorder.java if the following is updated.
+//Please update media/java/android/media/MediaRecorder.java if the following is updated.
enum output_format {
OUTPUT_FORMAT_DEFAULT = 0,
- OUTPUT_FORMAT_THREE_GPP,
- OUTPUT_FORMAT_MPEG_4,
- OUTPUT_FORMAT_RAW_AMR,
+ OUTPUT_FORMAT_THREE_GPP = 1,
+ OUTPUT_FORMAT_MPEG_4 = 2,
+
+
+ OUTPUT_FORMAT_AUDIO_ONLY_START = 3, // Used in validating the output format. Should be the
+ // at the start of the audio only output formats.
+
+ /* These are audio only file formats */
+ OUTPUT_FORMAT_RAW_AMR = 3, //to be backward compatible
+ OUTPUT_FORMAT_AMR_NB = 3,
+ OUTPUT_FORMAT_AMR_WB = 4,
+ OUTPUT_FORMAT_AAC_ADIF = 5,
+ OUTPUT_FORMAT_AAC_ADTS = 6,
+
OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
};
enum audio_encoder {
AUDIO_ENCODER_DEFAULT = 0,
AUDIO_ENCODER_AMR_NB = 1,
+ AUDIO_ENCODER_AMR_WB = 2,
+ AUDIO_ENCODER_AAC = 3,
+ AUDIO_ENCODER_AAC_PLUS = 4,
+ AUDIO_ENCODER_EAAC_PLUS = 5,
+
+ AUDIO_ENCODER_LIST_END // must be the last - used to validate the audio encoder type
};
enum video_encoder {
@@ -68,8 +89,11 @@ enum video_encoder {
VIDEO_ENCODER_H263 = 1,
VIDEO_ENCODER_H264 = 2,
VIDEO_ENCODER_MPEG_4_SP = 3,
+
+ VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type
};
+
// Maximum frames per second is 24
#define MEDIA_RECORDER_MAX_FRAME_RATE 24
@@ -108,7 +132,7 @@ enum media_recorder_error_type {
// The codes are distributed as follow:
// 0xx: Reserved
// 8xx: General info/warning
-//
+//
enum media_recorder_info_type {
MEDIA_RECORDER_INFO_UNKNOWN = 1,
MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800,
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index bf62995..d2aa30e 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -16,33 +16,45 @@
#include <media/AudioSystem.h>
// This header defines the interface used by the Android platform
-// to access Text-To-Speech functionality in shared libraries that implement speech
-// synthesis and the management of resources associated with the synthesis.
-// An example of the implementation of this interface can be found in
+// to access Text-To-Speech functionality in shared libraries that implement
+// speech synthesis and the management of resources associated with the
+// synthesis.
+// An example of the implementation of this interface can be found in
// FIXME: add path+name to implementation of default TTS engine
// Libraries implementing this interface are used in:
// frameworks/base/tts/jni/android_tts_SpeechSynthesis.cpp
namespace android {
+enum tts_synth_status {
+ TTS_SYNTH_DONE = 0,
+ TTS_SYNTH_PENDING = 1
+};
+
+enum tts_callback_status {
+ TTS_CALLBACK_HALT = 0,
+ TTS_CALLBACK_CONTINUE = 1
+};
+
// The callback is used by the implementation of this interface to notify its
// client, the Android TTS service, that the last requested synthesis has been
-// completed.
+// completed. // TODO reword
// The callback for synthesis completed takes:
-// void * - The userdata pointer set in the original synth call
-// uint32_t - Track sampling rate in Hz
-// audio_format - The AudioSystem::audio_format enum
-// int - The number of channels
-// int8_t * - A buffer of audio data only valid during the execution of the callback
-// size_t - The size of the buffer
-// Note about memory management:
-// The implementation of TtsEngine is responsible for the management of the memory
-// it allocates to store the synthesized speech. After the execution of the callback
-// to hand the synthesized data to the client of TtsEngine, the TTS engine is
-// free to reuse or free the previously allocated memory.
-// This implies that the implementation of the "synthDoneCB" callback cannot use
-// the pointer to the buffer of audio samples outside of the callback itself.
-typedef void (synthDoneCB_t)(void *, uint32_t, AudioSystem::audio_format, int, int8_t *, size_t);
+// @param [inout] void *& - The userdata pointer set in the original
+// synth call
+// @param [in] uint32_t - Track sampling rate in Hz
+// @param [in] audio_format - The AudioSystem::audio_format enum
+// @param [in] int - The number of channels
+// @param [inout] int8_t *& - A buffer of audio data only valid during the
+// execution of the callback
+// @param [inout] size_t & - The size of the buffer
+// @param [in] tts_synth_status - indicate whether the synthesis is done, or
+// if more data is to be synthesized.
+// @return TTS_CALLBACK_HALT to indicate the synthesis must stop,
+// TTS_CALLBACK_CONTINUE to indicate the synthesis must continue if
+// there is more data to produce.
+typedef tts_callback_status (synthDoneCB_t)(void *&, uint32_t,
+ AudioSystem::audio_format, int, int8_t *&, size_t&, tts_synth_status);
class TtsEngine;
extern "C" TtsEngine* getTtsEngine();
@@ -69,38 +81,41 @@ public:
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result shutdown();
- // Interrupt synthesis and flushes any synthesized data that hasn't been output yet.
- // This will block until callbacks underway are completed.
+ // Interrupt synthesis and flushes any synthesized data that hasn't been
+ // output yet. This will block until callbacks underway are completed.
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result stop();
- // Load the resources associated with the specified language. The loaded language will
- // only be used once a call to setLanguage() with the same language value is issued.
- // Language values are based on the Android conventions for localization as described in
- // the Android platform documentation on internationalization. This implies that language
- // data is specified in the format xx-rYY, where xx is a two letter ISO 639-1 language code
- // in lowercase and rYY is a two letter ISO 3166-1-alpha-2 language code in uppercase
- // preceded by a lowercase "r".
+ // Load the resources associated with the specified language. The loaded
+ // language will only be used once a call to setLanguage() with the same
+ // language value is issued. Language values are based on the Android
+ // conventions for localization as described in the Android platform
+ // documentation on internationalization. This implies that language
+ // data is specified in the format xx-rYY, where xx is a two letter
+ // ISO 639-1 language code in lowercase and rYY is a two letter
+ // ISO 3166-1-alpha-2 language code in uppercase preceded by a
+ // lowercase "r".
// @param value pointer to the language value
// @param size length of the language value
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result loadLanguage(const char *value, const size_t size);
- // Signal the engine to use the specified language. This will force the language to be
- // loaded if it wasn't loaded previously with loadLanguage().
+ // Signal the engine to use the specified language. This will force the
+ // language to be loaded if it wasn't loaded previously with loadLanguage().
// See loadLanguage for the specification of the language.
// @param value pointer to the language value
// @param size length of the language value
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result setLanguage(const char *value, const size_t size);
- // Retrieve the currently set language, or an empty "value" if no language has
- // been set.
+ // Retrieve the currently set language, or an empty "value" if no language
+ // has been set.
// @param[out] value pointer to the retrieved language value
- // @param[inout] iosize in: stores the size available to store the language value in *value
- // out: stores the size required to hold the language value if
- // getLanguage() returned TTS_PROPERTY_SIZE_TOO_SMALL,
- // unchanged otherwise.
+ // @param[inout] iosize in: stores the size available to store the language
+ // value in *value
+ // out: stores the size required to hold the language
+ // value if getLanguage() returned
+ // TTS_PROPERTY_SIZE_TOO_SMALL, unchanged otherwise.
// @return TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL, or TTS_FAILURE
virtual tts_result getLanguage(char *value, size_t *iosize);
@@ -109,23 +124,31 @@ public:
// @param property pointer to the property name
// @param value pointer to the property value
// @param size maximum size required to store this type of property
- // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_FAILURE,
+ // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_FAILURE,
// or TTS_VALUE_INVALID
- virtual tts_result setProperty(const char *property, const char *value, const size_t size);
+ virtual tts_result setProperty(const char *property, const char *value,
+ const size_t size);
// Retrieve a property from the TTS engine
// @param property pointer to the property name
// @param[out] value pointer to the retrieved language value
- // @param[inout] iosize in: stores the size available to store the property value
- // out: stores the size required to hold the language value if
- // getLanguage() returned TTS_PROPERTY_SIZE_TOO_SMALL,
- // unchanged otherwise.
- // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL
- virtual tts_result getProperty(const char *property, char *value, size_t *iosize);
+ // @param[inout] iosize in: stores the size available to store the
+ // property value.
+ // out: stores the size required to hold the language
+ // value if getLanguage() returned
+ // TTS_PROPERTY_SIZE_TOO_SMALL, unchanged otherwise
+ // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS,
+ // or TTS_PROPERTY_SIZE_TOO_SMALL
+ virtual tts_result getProperty(const char *property, char *value,
+ size_t *iosize);
// Synthesize the text.
- // When synthesis completes, the engine invokes the callback to notify the TTS framework.
- // Note about the format of the input: the text parameter may use the following elements
+ // As the synthesis is performed, the engine invokes the callback to notify
+ // the TTS framework that it has filled the given buffer, and indicates how
+ // many bytes it wrote. The callback is called repeatedly until the engine
+ // has generated all the audio data corresponding to the text.
+ // Note about the format of the input: the text parameter may use the
+ // following elements
// and their respective attributes as defined in the SSML 1.0 specification:
// * lang
// * say-as:
@@ -154,14 +177,25 @@ public:
// Text is coded in UTF-8.
// @param text the UTF-8 text to synthesize
// @param userdata pointer to be returned when the call is invoked
+ // @param buffer the location where the synthesized data must be written
+ // @param bufferSize the number of bytes that can be written in buffer
// @return TTS_SUCCESS or TTS_FAILURE
- virtual tts_result synthesizeText(const char *text, void *userdata);
-
- // Synthesize IPA text. When synthesis completes, the engine must call the given callback to notify the TTS API.
+ virtual tts_result synthesizeText(const char *text, int8_t *buffer,
+ size_t bufferSize, void *userdata);
+
+ // Synthesize IPA text.
+ // As the synthesis is performed, the engine invokes the callback to notify
+ // the TTS framework that it has filled the given buffer, and indicates how
+ // many bytes it wrote. The callback is called repeatedly until the engine
+ // has generated all the audio data corresponding to the IPA data.
// @param ipa the IPA data to synthesize
// @param userdata pointer to be returned when the call is invoked
- // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported, otherwise TTS_SUCCESS or TTS_FAILURE
- virtual tts_result synthesizeIpa(const char *ipa, void *userdata);
+ // @param buffer the location where the synthesized data must be written
+ // @param bufferSize the number of bytes that can be written in buffer
+ // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported,
+ // otherwise TTS_SUCCESS or TTS_FAILURE
+ virtual tts_result synthesizeIpa(const char *ipa, int8_t *buffer,
+ size_t bufferSize, void *userdata);
};
} // namespace android
diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h
index 24b6c9e..f60f4ea 100644
--- a/include/utils/BackupHelpers.h
+++ b/include/utils/BackupHelpers.h
@@ -118,7 +118,7 @@ private:
};
int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
- char const* fileBase, char const* const* files, int fileCount);
+ char const* const* files, char const* const *keys, int fileCount);
#define TEST_BACKUP_HELPERS 1
@@ -127,6 +127,8 @@ int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapsh
int backup_helper_test_empty();
int backup_helper_test_four();
int backup_helper_test_files();
+int backup_helper_test_null_base();
+int backup_helper_test_missing_file();
int backup_helper_test_data_writer();
int backup_helper_test_data_reader();
#endif
diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java
new file mode 100644
index 0000000..71c1cf4
--- /dev/null
+++ b/keystore/java/android/security/Keystore.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+/**
+ * The Keystore class provides the functions to list the certs/keys in keystore.
+ * {@hide}
+ */
+public abstract class Keystore {
+ private static final String TAG = "Keystore";
+ private static final String[] NOTFOUND = new String[0];
+
+ /**
+ */
+ public static Keystore getInstance() {
+ return new FileKeystore();
+ }
+
+ /**
+ */
+ public abstract String getUserkey(String key);
+
+ /**
+ */
+ public abstract String getCertificate(String key);
+
+ /**
+ */
+ public abstract String[] getAllCertificateKeys();
+
+ /**
+ */
+ public abstract String[] getAllUserkeyKeys();
+
+ public abstract String[] getSupportedKeyStrenghs();
+
+ /**
+ * Generates a key pair and returns the certificate request.
+ * @param keyStrengthIndex index to the array of supported key strengths
+ * @param challenge the challenge message in the keygen tag
+ * @param organizations the organization string, e.g.,
+ * "/C=US/ST={state}/L={city}/O={company}/OU={app}/CN={hostname}"
+ * @return the certificate request
+ */
+ public abstract String generateKeyPair(
+ int keyStrengthIndex, String challenge, String organizations);
+
+ public abstract void addCertificate(String cert);
+
+ private static class FileKeystore extends Keystore {
+ private static final String SERVICE_NAME = "keystore";
+ private static final String LIST_CERTIFICATES = "listcerts";
+ private static final String LIST_USERKEYS = "listuserkeys";
+ private static final String PATH = "/data/misc/keystore/";
+ private static final String USERKEY_PATH = PATH + "userkeys/";
+ private static final String CERT_PATH = PATH + "certs/";
+ private static final ServiceCommand mServiceCommand =
+ new ServiceCommand(SERVICE_NAME);
+
+ @Override
+ public String getUserkey(String key) {
+ return USERKEY_PATH + key;
+ }
+
+ @Override
+ public String getCertificate(String key) {
+ return CERT_PATH + key;
+ }
+
+ /**
+ * Returns the array of the certificate names in keystore if successful.
+ * Or return an empty array if error.
+ *
+ * @return array of the certificates
+ */
+ @Override
+ public String[] getAllCertificateKeys() {
+ try {
+ String result = mServiceCommand.execute(LIST_CERTIFICATES);
+ if (result != null) return result.split("\\s+");
+ return NOTFOUND;
+ } catch (NumberFormatException ex) {
+ return NOTFOUND;
+ }
+ }
+
+ /**
+ * Returns the array of the names of private keys in keystore if successful.
+ * Or return an empty array if errors.
+ *
+ * @return array of the user keys
+ */
+ @Override
+ public String[] getAllUserkeyKeys() {
+ try {
+ String result = mServiceCommand.execute(LIST_USERKEYS);
+ if (result != null) return result.split("\\s+");
+ return NOTFOUND;
+ } catch (NumberFormatException ex) {
+ return NOTFOUND;
+ }
+ }
+
+ @Override
+ public String[] getSupportedKeyStrenghs() {
+ // TODO: real implementation
+ return new String[] {"High Grade", "Medium Grade"};
+ }
+
+ @Override
+ public String generateKeyPair(int keyStrengthIndex, String challenge,
+ String organizations) {
+ // TODO: real implementation
+ return "-----BEGIN CERTIFICATE REQUEST-----"
+ + "\nMIICzjCCAbYCAQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh"
+ + "\nMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRYw"
+ + "\nFAYDVQQLEw1SZW1vdGUgQWNjZXNzMRAwDgYDVQQLEwdHbGFwdG9wMQ0wCwYDVQQD"
+ + "\nEwR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznwy7a16O35u"
+ + "\nODLQOw6yHAxozrrX1J+c0reiIh8GYohwKrBedFnQ/FnTls6bxY4fNHD+SZvFFgvU"
+ + "\nECBFOfRmRm7AFo51qT0t2a8qgvDLM6L1qGkmy94W28Q3OlcpF2QianHYdjyGT+Ac"
+ + "\nYDek1Zi/E/mdPzuVM/K8tkB7n8ktC0PTm1ZtdMRauE5R0WrEhWuF6In/2gy1Q/Zh"
+ + "\noy7/zQqpbPl2ouulvkx1Y3OXHM6XPNFLoHS1gH0HyAuBUokO0QmetRn6ngJSvz7e"
+ + "\nVD7QYRppGp+g4BxqaV9XSxhaaKrMs4PAld9enV51X9qjvjCRBve2QxtuJgMfGJdU"
+ + "\njGr/JweZoQIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBADtxOtEseoLOVYh6sh4b"
+ + "\nWCdngK87uHn2bdGipFwKdNTxQDdxNQLAKdoGYIfbVsC1cDgFiufeNwVukxxymdnm"
+ + "\nk0GGK+0O0tZKENv8ysgfbgEsHpJH9FoR5Y5XEq1etejkcgCp59dyhrSk0DLyVm0D"
+ + "\nIfTC/nsK95H7AAGOkbbDFo2otyLNNrthYncQ9diAG0UzzLacA+86JXZmD3HyC48u"
+ + "\nI9hsivVnTTfl9afcfVAhfxbQ6HgkhZZjbjFjfABSd4v8wKlAAqK58VxCajNVOVcV"
+ + "\ncCzOWf6NpE7xEHCf32i8bWDP6hi0WgQcdpQwnZNKhhTLGNb23Uty6HYlJhbxexC7"
+ + "\nUoM="
+ + "\n-----END CERTIFICATE REQUEST-----";
+ }
+
+ @Override
+ public void addCertificate(String cert) {
+ // TODO: real implementation
+ }
+ }
+}
diff --git a/keystore/java/android/security/ServiceCommand.java b/keystore/java/android/security/ServiceCommand.java
new file mode 100644
index 0000000..f1d4302
--- /dev/null
+++ b/keystore/java/android/security/ServiceCommand.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import android.net.LocalSocketAddress;
+import android.net.LocalSocket;
+import android.util.Config;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/*
+ * ServiceCommand is used to connect to a service throught the local socket,
+ * and send out the command, return the result to the caller.
+ * {@hide}
+ */
+public class ServiceCommand {
+ public static final String SUCCESS = "0";
+ public static final String FAILED = "-1";
+
+ private String mServiceName;
+ private String mTag;
+ private InputStream mIn;
+ private OutputStream mOut;
+ private LocalSocket mSocket;
+ private static final int BUFFER_LENGTH = 1024;
+
+ private byte buf[] = new byte[BUFFER_LENGTH];
+ private int buflen = 0;
+
+ private boolean connect() {
+ if (mSocket != null) {
+ return true;
+ }
+ Log.i(mTag, "connecting...");
+ try {
+ mSocket = new LocalSocket();
+
+ LocalSocketAddress address = new LocalSocketAddress(
+ mServiceName, LocalSocketAddress.Namespace.RESERVED);
+
+ mSocket.connect(address);
+
+ mIn = mSocket.getInputStream();
+ mOut = mSocket.getOutputStream();
+ } catch (IOException ex) {
+ disconnect();
+ return false;
+ }
+ return true;
+ }
+
+ private void disconnect() {
+ Log.i(mTag,"disconnecting...");
+ try {
+ if (mSocket != null) mSocket.close();
+ } catch (IOException ex) { }
+ try {
+ if (mIn != null) mIn.close();
+ } catch (IOException ex) { }
+ try {
+ if (mOut != null) mOut.close();
+ } catch (IOException ex) { }
+ mSocket = null;
+ mIn = null;
+ mOut = null;
+ }
+
+ private boolean readBytes(byte buffer[], int len) {
+ int off = 0, count;
+ if (len < 0) return false;
+ while (off != len) {
+ try {
+ count = mIn.read(buffer, off, len - off);
+ if (count <= 0) {
+ Log.e(mTag, "read error " + count);
+ break;
+ }
+ off += count;
+ } catch (IOException ex) {
+ Log.e(mTag,"read exception");
+ break;
+ }
+ }
+ if (off == len) return true;
+ disconnect();
+ return false;
+ }
+
+ private boolean readReply() {
+ int len, ret;
+ buflen = 0;
+
+ if (!readBytes(buf, 2)) return false;
+ ret = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8);
+ if (ret != 0) return false;
+
+ if (!readBytes(buf, 2)) return false;
+ len = (((int) buf[0]) & 0xff) | ((((int) buf[1]) & 0xff) << 8);
+ if (len > BUFFER_LENGTH) {
+ Log.e(mTag,"invalid reply length (" + len + ")");
+ disconnect();
+ return false;
+ }
+ if (!readBytes(buf, len)) return false;
+ buflen = len;
+ return true;
+ }
+
+ private boolean writeCommand(String _cmd) {
+ byte[] cmd = _cmd.getBytes();
+ int len = cmd.length;
+ if ((len < 1) || (len > BUFFER_LENGTH)) return false;
+ buf[0] = (byte) (len & 0xff);
+ buf[1] = (byte) ((len >> 8) & 0xff);
+ try {
+ mOut.write(buf, 0, 2);
+ mOut.write(cmd, 0, len);
+ } catch (IOException ex) {
+ Log.e(mTag,"write error");
+ disconnect();
+ return false;
+ }
+ return true;
+ }
+
+ private String executeCommand(String cmd) {
+ if (!writeCommand(cmd)) {
+ /* If service died and restarted in the background
+ * (unlikely but possible) we'll fail on the next
+ * write (this one). Try to reconnect and write
+ * the command one more time before giving up.
+ */
+ Log.e(mTag, "write command failed? reconnect!");
+ if (!connect() || !writeCommand(cmd)) {
+ return null;
+ }
+ }
+ if (readReply()) {
+ return new String(buf, 0, buflen);
+ } else {
+ return null;
+ }
+ }
+
+ public synchronized String execute(String cmd) {
+ String result;
+ if (!connect()) {
+ Log.e(mTag, "connection failed");
+ return null;
+ }
+ result = executeCommand(cmd);
+ disconnect();
+ return result;
+ }
+
+ public ServiceCommand(String service) {
+ mServiceName = service;
+ mTag = service;
+ }
+}
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
index 874f2c4..ea7d6c2 100644
--- a/libs/audioflinger/Android.mk
+++ b/libs/audioflinger/Android.mk
@@ -51,8 +51,7 @@ ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_SRC_FILES += A2dpAudioInterface.cpp
LOCAL_SHARED_LIBRARIES += liba2dp
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
- LOCAL_C_INCLUDES += $(call include-path-for, bluez-libs)
- LOCAL_C_INCLUDES += $(call include-path-for, bluez-utils)
+ LOCAL_C_INCLUDES += $(call include-path-for, bluez)
endif
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 6ff39a4..06c0595 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -1,11 +1,11 @@
# Only build if BUILD_RENDERSCRIPT is defined to true in the environment.
ifeq ($(BUILD_RENDERSCRIPT),true)
-TOP_LOCAL_PATH:=$(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_PATH:= $(TOP_LOCAL_PATH)
+LOCAL_PATH:=$(call my-dir)
+
-# Build rsg-generator
+# Build rsg-generator ====================
+include $(CLEAR_VARS)
LOCAL_MODULE := rsg-generator
@@ -14,7 +14,7 @@ LOCAL_MODULE := rsg-generator
LOCAL_IS_HOST_MODULE := true
LOCAL_MODULE_CLASS := EXECUTABLES
-intermediates:= $(local-intermediates-dir)
+intermediates := $(local-intermediates-dir)
GEN := $(addprefix $(intermediates)/, \
lex.yy.c \
@@ -28,21 +28,21 @@ $(LOCAL_PATH)/rsg_generator.c : $(intermediates)/lex.yy.c
LOCAL_SRC_FILES:= \
rsg_generator.c
-
+
include $(BUILD_HOST_EXECUTABLE)
+# TODO: This should go into build/core/config.mk
RSG_GENERATOR:=$(LOCAL_BUILT_MODULE)
-# Build render script lib
+
+# Build render script lib ====================
include $(CLEAR_VARS)
LOCAL_MODULE := libRS
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
intermediates:= $(local-intermediates-dir)
-RS_GENERATED_INCLUDE_DIR:=$(intermediates)
-
# Generate custom headers
GEN := $(addprefix $(intermediates)/, \
@@ -50,12 +50,14 @@ GEN := $(addprefix $(intermediates)/, \
rsgApiFuncDecl.h \
)
-$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(TOP_LOCAL_PATH)/rs.spec
+$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(PRIVATE_PATH)/rs.spec
$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec
$(GEN): $(intermediates)/%.h : $(LOCAL_PATH)/%.h.rsg
$(transform-generated-source)
-RS_GENERATED_SOURCES += $(GEN)
+# used in jni/Android.mk
+rs_generated_source += $(GEN)
LOCAL_GENERATED_SOURCES += $(GEN)
# Generate custom source files
@@ -65,12 +67,15 @@ GEN := $(addprefix $(intermediates)/, \
rsgApiReplay.cpp \
)
-$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(TOP_LOCAL_PATH)/rs.spec
+$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN) : PRIVATE_CUSTOM_TOOL = $(RSG_GENERATOR) $< $@ <$(PRIVATE_PATH)/rs.spec
$(GEN) : $(RSG_GENERATOR) $(LOCAL_PATH)/rs.spec
$(GEN): $(intermediates)/%.cpp : $(LOCAL_PATH)/%.cpp.rsg
$(transform-generated-source)
-RS_GENERATED_SOURCES += $(GEN)
+# used in jni/Android.mk
+rs_generated_source += $(GEN)
+
LOCAL_GENERATED_SOURCES += $(GEN)
LOCAL_SRC_FILES:= \
@@ -99,45 +104,14 @@ LOCAL_LDLIBS := -lpthread -ldl
LOCAL_MODULE:= libRS
LOCAL_PRELINK_MODULE := false
-#LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
-# Build JNI library
-
-LOCAL_PATH:= $(TOP_LOCAL_PATH)/jni
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- RenderScript_jni.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libandroid_runtime \
- libacc \
- libnativehelper \
- libRS \
- libcutils \
- libsgl \
- libutils \
- libui
-
-LOCAL_STATIC_LIBRARIES :=
-
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE) \
- $(RS_GENERATED_INCLUDE_DIR) \
- $(call include-path-for, corecg graphics)
-
-LOCAL_CFLAGS +=
-
-LOCAL_LDLIBS := -lpthread
-
-LOCAL_MODULE:= libRS_jni
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_ADDITIONAL_DEPENDENCIES += $(RS_GENERATED_SOURCES)
-
-include $(BUILD_SHARED_LIBRARY)
+# Include the subdirectories ====================
+include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk,\
+ jni \
+ java \
+ ))
-include $(call all-subdir-makefiles)
endif # BUILD_RENDERSCRIPT
diff --git a/libs/rs/java/Fountain/Android.mk b/libs/rs/java/Fountain/Android.mk
index cf08467..af3d5fc 100644
--- a/libs/rs/java/Fountain/Android.mk
+++ b/libs/rs/java/Fountain/Android.mk
@@ -18,14 +18,8 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
LOCAL_PACKAGE_NAME := Fountain
include $(BUILD_PACKAGE)
-##################################################
-include $(CLEAR_VARS)
-
-include $(BUILD_MULTI_PREBUILT)
-
-# Use the folloing include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c
index 8b473ab..3bd9496 100644
--- a/libs/rs/java/Fountain/res/raw/fountain.c
+++ b/libs/rs/java/Fountain/res/raw/fountain.c
@@ -1,5 +1,12 @@
// Fountain test script
+#pragma version(1)
+#pragma stateVertex(orthoWindow)
+#pragma stateRaster(flat)
+#pragma stateFragment(PgmFragBackground)
+#pragma stateFragmentStore(MyBlend)
+
+
int main(void* con, int ft, int launchID) {
int count, touch, x, y, rate, maxLife, lifeShift;
int life;
@@ -28,9 +35,8 @@ int main(void* con, int ft, int launchID) {
}
}
- contextBindProgramFragment(con, loadI32(con, 0, 7));
drawRect(con, 0, 256, 0, 512);
- contextBindProgramFragment(con, loadI32(con, 0, 6));
+ contextBindProgramFragment(con, NAMED_PgmFragParts);
if (touch) {
newPart = loadI32(con, 2, 0);
@@ -99,6 +105,6 @@ int main(void* con, int ft, int launchID) {
}
}
- drawTriangleArray(con, loadI32(con, 0, 5), drawCount);
+ drawTriangleArray(con, NAMED_PartBuffer, drawCount);
return 1;
}
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
index 0d66966..58c78fa 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
@@ -16,6 +16,9 @@
package com.android.fountain;
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
new file mode 100644
index 0000000..0a0b05a
--- /dev/null
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fountain;
+
+import java.io.Writer;
+
+import android.renderscript.RenderScript;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+
+public class FountainRS {
+
+ public FountainRS() {
+ }
+
+ public void init(RenderScript rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ initRS();
+ }
+
+ public void newTouchPosition(int x, int y) {
+ mParams[0] = 1;
+ mParams[1] = x;
+ mParams[2] = y;
+ mIntAlloc.subData1D(2, 3, mParams);
+ }
+
+
+ /////////////////////////////////////////
+
+ private Resources mRes;
+
+ private RenderScript mRS;
+ private RenderScript.Allocation mIntAlloc;
+ private RenderScript.Allocation mPartAlloc;
+ private RenderScript.Allocation mVertAlloc;
+ private RenderScript.Script mScript;
+ private RenderScript.ProgramFragmentStore mPFS;
+ private RenderScript.ProgramFragment mPF;
+ private RenderScript.ProgramFragment mPF2;
+ private RenderScript.Allocation mTexture;
+ private RenderScript.Sampler mSampler;
+
+ private Bitmap mBackground;
+
+ int mParams[] = new int[10];
+
+ private void initRS() {
+ int partCount = 1024;
+
+ mIntAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, 10);
+ mPartAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, partCount * 3 * 3);
+ mPartAlloc.setName("PartBuffer");
+ mVertAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, partCount * 5 + 1);
+
+ {
+ Drawable d = mRes.getDrawable(R.drawable.gadgets_clock_mp3);
+ BitmapDrawable bd = (BitmapDrawable)d;
+ Bitmap b = bd.getBitmap();
+ mTexture = mRS.allocationCreateFromBitmap(b,
+ RenderScript.ElementPredefined.RGB_565,
+ true);
+ mTexture.uploadToTexture(0);
+ }
+
+ mRS.programFragmentStoreBegin(null, null);
+ mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.SRC_ALPHA, RenderScript.BlendDstFunc.ONE);
+ mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS);
+ mPFS = mRS.programFragmentStoreCreate();
+ mPFS.setName("MyBlend");
+ mRS.contextBindProgramFragmentStore(mPFS);
+
+ mRS.samplerBegin();
+ mRS.samplerSet(RenderScript.SamplerParam.FILTER_MAG, RenderScript.SamplerValue.LINEAR);
+ mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, RenderScript.SamplerValue.LINEAR);
+ mSampler = mRS.samplerCreate();
+
+
+ mRS.programFragmentBegin(null, null);
+ mPF = mRS.programFragmentCreate();
+ mPF.setName("PgmFragParts");
+
+ mRS.programFragmentBegin(null, null);
+ mRS.programFragmentSetTexEnable(0, true);
+ mPF2 = mRS.programFragmentCreate();
+ mRS.contextBindProgramFragment(mPF2);
+ mPF2.bindTexture(mTexture, 0);
+ mPF2.bindSampler(mSampler, 0);
+ mPF2.setName("PgmFragBackground");
+
+ mParams[0] = 0;
+ mParams[1] = partCount;
+ mParams[2] = 0;
+ mParams[3] = 0;
+ mParams[4] = 0;
+ mIntAlloc.data(mParams);
+
+ int t2[] = new int[partCount * 4*3];
+ for (int ct=0; ct < t2.length; ct++) {
+ t2[ct] = 0;
+ }
+ mPartAlloc.data(t2);
+
+ mRS.scriptCBegin();
+ mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ mRS.scriptCSetScript(mRes, R.raw.fountain);
+ mRS.scriptCSetRoot(true);
+ mScript = mRS.scriptCCreate();
+
+ mScript.bindAllocation(mIntAlloc, 0);
+ mScript.bindAllocation(mPartAlloc, 1);
+ mScript.bindAllocation(mVertAlloc, 2);
+ mRS.contextBindRootScript(mScript);
+ }
+
+}
+
+
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
index 3381525..be8b24e 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -20,6 +20,9 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -44,125 +47,26 @@ public class FountainView extends RSSurfaceView {
}
private RenderScript mRS;
- private RenderScript.Allocation mIntAlloc;
- private RenderScript.Allocation mPartAlloc;
- private RenderScript.Allocation mVertAlloc;
- private RenderScript.Script mScript;
- private RenderScript.ProgramFragmentStore mPFS;
- private RenderScript.ProgramFragment mPF;
- private RenderScript.ProgramFragment mPF2;
- private RenderScript.Allocation mTexture;
- private RenderScript.Sampler mSampler;
-
- private Bitmap mBackground;
-
- int mParams[] = new int[10];
-
- private void initRS() {
- mRS = createRenderScript();
-
- int partCount = 1024;
-
- mIntAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, 10);
- mPartAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, partCount * 3 * 3);
- mVertAlloc = mRS.allocationCreatePredefSized(RenderScript.ElementPredefined.USER_I32, partCount * 5 + 1);
-
- {
- Resources res = getResources();
- Drawable d = res.getDrawable(R.drawable.gadgets_clock_mp3);
- BitmapDrawable bd = (BitmapDrawable)d;
- Bitmap b = bd.getBitmap();
- mTexture = mRS.allocationCreateFromBitmap(b,
- RenderScript.ElementPredefined.RGB_565,
- true);
- mTexture.uploadToTexture(0);
- }
-
- mRS.programFragmentStoreBegin(null, null);
- mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.SRC_ALPHA, RenderScript.BlendDstFunc.ONE);
- mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS);
- mPFS = mRS.programFragmentStoreCreate();
- mRS.contextBindProgramFragmentStore(mPFS);
-
- mRS.samplerBegin();
- mRS.samplerSet(RenderScript.SamplerParam.FILTER_MAG, RenderScript.SamplerValue.LINEAR);
- mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN, RenderScript.SamplerValue.LINEAR);
- mSampler = mRS.samplerCreate();
-
-
- mRS.programFragmentBegin(null, null);
- mPF = mRS.programFragmentCreate();
- //mRS.contextBindProgramFragment(mPF);
-
- mRS.programFragmentBegin(null, null);
- mRS.programFragmentSetTexEnable(0, true);
- mPF2 = mRS.programFragmentCreate();
- mRS.contextBindProgramFragment(mPF2);
- mPF2.bindTexture(mTexture, 0);
- mPF2.bindSampler(mSampler, 0);
-
- mParams[0] = 0;
- mParams[1] = partCount;
- mParams[2] = 0;
- mParams[3] = 0;
- mParams[4] = 0;
- mParams[5] = mPartAlloc.mID;
- mParams[6] = mPF.mID;
- mParams[7] = mPF2.mID;
- mIntAlloc.data(mParams);
-
- int t2[] = new int[partCount * 4*3];
- for (int ct=0; ct < t2.length; ct++) {
- t2[ct] = 0;
- }
- mPartAlloc.data(t2);
-
- mRS.scriptCBegin();
- mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- mRS.scriptCSetScript(getResources(), R.raw.fountain);
- mRS.scriptCSetRoot(true);
- mScript = mRS.scriptCCreate();
-
- mScript.bindAllocation(mIntAlloc, 0);
- mScript.bindAllocation(mPartAlloc, 1);
- mScript.bindAllocation(mVertAlloc, 2);
- mRS.contextBindRootScript(mScript);
-
- }
+ private FountainRS mRender;
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
super.surfaceChanged(holder, format, w, h);
- initRS();
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event)
- {
- // break point at here
- // this method doesn't work when 'extends View' include 'extends ScrollView'.
- return super.onKeyDown(keyCode, event);
+ mRS = createRenderScript();
+ mRender = new FountainRS();
+ mRender.init(mRS, getResources(), w, h);
}
- int mTouchAction;
@Override
public boolean onTouchEvent(MotionEvent ev)
{
- //Log.e("FountainView", ev.toString());
boolean ret = true;
int act = ev.getAction();
- mParams[1] = (int)ev.getX();
- mParams[2] = (int)ev.getY();
-
- if (act == ev.ACTION_DOWN) {
- mParams[0] = 1;
- } else if (act == ev.ACTION_UP) {
- //mParams[0] = 0;
+ if (act == ev.ACTION_UP) {
ret = false;
}
- mIntAlloc.subData1D(2, 3, mParams);
-
+ mRender.newTouchPosition((int)ev.getX(), (int)ev.getY());
return ret;
}
}
diff --git a/libs/rs/java/RenderScript/Android.mk b/libs/rs/java/RenderScript/Android.mk
new file mode 100644
index 0000000..616fbd2
--- /dev/null
+++ b/libs/rs/java/RenderScript/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2008 Esmertec AG.
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+# the library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ $(call all-subdir-java-files)
+
+LOCAL_MODULE:= android.renderscript
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/libs/rs/java/RenderScript/android/renderscript/Matrix.java b/libs/rs/java/RenderScript/android/renderscript/Matrix.java
new file mode 100644
index 0000000..03222aa
--- /dev/null
+++ b/libs/rs/java/RenderScript/android/renderscript/Matrix.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+class Matrix {
+
+ public Matrix() {
+ mMat = new float[16];
+ loadIdentity();
+ }
+
+ public float get(int i, int j) {
+ return mMat[i*4 + j];
+ }
+
+ public void set(int i, int j, float v) {
+ mMat[i*4 + j] = v;
+ }
+
+ public void loadIdentity() {
+ mMat[0] = 1;
+ mMat[1] = 0;
+ mMat[2] = 0;
+ mMat[3] = 0;
+
+ mMat[4] = 0;
+ mMat[5] = 1;
+ mMat[6] = 0;
+ mMat[7] = 0;
+
+ mMat[8] = 0;
+ mMat[9] = 0;
+ mMat[10] = 1;
+ mMat[11] = 0;
+
+ mMat[12] = 0;
+ mMat[13] = 0;
+ mMat[14] = 0;
+ mMat[15] = 1;
+ }
+
+ public void load(Matrix src) {
+ mMat = src.mMat;
+ }
+
+ public void loadRotate(float rot, float x, float y, float z) {
+ float c, s;
+ mMat[3] = 0;
+ mMat[7] = 0;
+ mMat[11]= 0;
+ mMat[12]= 0;
+ mMat[13]= 0;
+ mMat[14]= 0;
+ mMat[15]= 1;
+ rot *= (float)(java.lang.Math.PI / 180.0f);
+ c = (float)java.lang.Math.cos(rot);
+ s = (float)java.lang.Math.sin(rot);
+
+ float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
+ if (!(len != 1)) {
+ float recipLen = 1.f / len;
+ x *= recipLen;
+ y *= recipLen;
+ z *= recipLen;
+ }
+ float nc = 1.0f - c;
+ float xy = x * y;
+ float yz = y * z;
+ float zx = z * x;
+ float xs = x * s;
+ float ys = y * s;
+ float zs = z * s;
+ mMat[ 0] = x*x*nc + c;
+ mMat[ 4] = xy*nc - zs;
+ mMat[ 8] = zx*nc + ys;
+ mMat[ 1] = xy*nc + zs;
+ mMat[ 5] = y*y*nc + c;
+ mMat[ 9] = yz*nc - xs;
+ mMat[ 2] = zx*nc - ys;
+ mMat[ 6] = yz*nc + xs;
+ mMat[10] = z*z*nc + c;
+ }
+
+ public void loadScale(float x, float y, float z) {
+ loadIdentity();
+ mMat[0] = x;
+ mMat[5] = y;
+ mMat[10] = z;
+ }
+
+ public void loadTranslate(float x, float y, float z) {
+ loadIdentity();
+ mMat[12] = x;
+ mMat[13] = y;
+ mMat[14] = z;
+ }
+
+ public void loadMultiply(Matrix lhs, Matrix rhs) {
+ for (int i=0 ; i<4 ; i++) {
+ float ri0 = 0;
+ float ri1 = 0;
+ float ri2 = 0;
+ float ri3 = 0;
+ for (int j=0 ; j<4 ; j++) {
+ float rhs_ij = rhs.get(i,j);
+ ri0 += lhs.get(j,0) * rhs_ij;
+ ri1 += lhs.get(j,1) * rhs_ij;
+ ri2 += lhs.get(j,2) * rhs_ij;
+ ri3 += lhs.get(j,3) * rhs_ij;
+ }
+ set(i,0, ri0);
+ set(i,1, ri1);
+ set(i,2, ri2);
+ set(i,3, ri3);
+ }
+ }
+
+ public void loadOrtho(float l, float r, float b, float t, float n, float f) {
+ loadIdentity();
+ mMat[0] = 2 / (r - l);
+ mMat[5] = 2 / (t - b);
+ mMat[10]= -2 / (f - n);
+ mMat[12]= -(r + l) / (r - l);
+ mMat[12]= -(t + b) / (t - b);
+ mMat[12]= -(f + n) / (f - n);
+ }
+
+ public void loadFrustum(float l, float r, float b, float t, float n, float f) {
+ loadIdentity();
+ mMat[0] = 2 * n / (r - l);
+ mMat[5] = 2 * n / (t - b);
+ mMat[8] = (r + l) / (r - l);
+ mMat[9] = (t + b) / (t - b);
+ mMat[10]= -(f + n) / (f - n);
+ mMat[11]= -1;
+ mMat[14]= -2*f*n / (f - n);
+ mMat[15]= 0;
+ }
+
+ public void multiply(Matrix rhs) {
+ Matrix tmp = new Matrix();
+ tmp.loadMultiply(this, rhs);
+ load(tmp);
+ }
+ public void rotate(float rot, float x, float y, float z) {
+ Matrix tmp = new Matrix();
+ tmp.loadRotate(rot, x, y, z);
+ multiply(tmp);
+ }
+ public void scale(float x, float y, float z) {
+ Matrix tmp = new Matrix();
+ tmp.loadScale(x, y, z);
+ multiply(tmp);
+ }
+ public void translate(float x, float y, float z) {
+ Matrix tmp = new Matrix();
+ tmp.loadTranslate(x, y, z);
+ multiply(tmp);
+ }
+
+
+
+ float[] mMat;
+
+}
+
+
+
+
+
diff --git a/libs/rs/java/RenderScript/android/renderscript/ProgramVertexAlloc.java b/libs/rs/java/RenderScript/android/renderscript/ProgramVertexAlloc.java
new file mode 100644
index 0000000..020ddb2
--- /dev/null
+++ b/libs/rs/java/RenderScript/android/renderscript/ProgramVertexAlloc.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+public class ProgramVertexAlloc {
+ public static final int MODELVIEW_OFFSET = 0;
+ public static final int PROJECTION_OFFSET = 16;
+ public static final int TEXTURE_OFFSET = 32;
+
+ Matrix mModel;
+ Matrix mProjection;
+ Matrix mTexture;
+
+ public RenderScript.Allocation mAlloc;
+
+ public ProgramVertexAlloc(RenderScript rs) {
+ mModel = new Matrix();
+ mProjection = new Matrix();
+ mTexture = new Matrix();
+
+ mAlloc = rs.allocationCreatePredefSized(
+ RenderScript.ElementPredefined.USER_FLOAT,
+ 48);
+
+ mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat);
+ mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ mAlloc.subData1D(TEXTURE_OFFSET, 16, mTexture.mMat);
+ }
+
+ public void loadModelview(Matrix m) {
+ mModel = m;
+ mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat);
+ }
+
+ public void loadProjection(Matrix m) {
+ mProjection = m;
+ mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat);
+ }
+
+ public void loadTexture(Matrix m) {
+ mTexture = m;
+ mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat);
+ }
+
+ public void setupOrthoWindow(int w, int h) {
+ mProjection.loadOrtho(0,w, h,0, -1,1);
+ mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ }
+
+ public void setupOrthoNormalized(int w, int h) {
+ // range -1,1 in the narrow axis.
+ if(w > h) {
+ float aspect = ((float)w) / h;
+ mProjection.loadOrtho(-aspect,aspect, -1,1, -1,1);
+ } else {
+ float aspect = ((float)h) / w;
+ mProjection.loadOrtho(-1,1, -aspect,aspect, -1,1);
+ }
+ mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ }
+
+ public void setupProjectionNormalized(int w, int h) {
+ // range -1,1 in the narrow axis at z = 0.
+ Matrix m1 = new Matrix();
+ Matrix m2 = new Matrix();
+
+ if(w > h) {
+ float aspect = ((float)w) / h;
+ m1.loadFrustum(-aspect,aspect, -1,1, 1,100);
+ } else {
+ float aspect = ((float)h) / w;
+ m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
+ }
+
+ m2.loadRotate(180, 0, 1, 0);
+ m1.loadMultiply(m1, m2);
+
+ m2.loadScale(-2, 2, 1);
+ m1.loadMultiply(m1, m2);
+
+ m2.loadTranslate(0, 0, 2);
+ m1.loadMultiply(m1, m2);
+
+ mProjection = m1;
+ mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat);
+ }
+
+}
+
+
+
+
+
+
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/RSSurfaceView.java b/libs/rs/java/RenderScript/android/renderscript/RSSurfaceView.java
index a8b3bca..3d37c13 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/RSSurfaceView.java
+++ b/libs/rs/java/RenderScript/android/renderscript/RSSurfaceView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.fountain;
+package android.renderscript;
import java.io.Writer;
import java.util.ArrayList;
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/RenderScript.java b/libs/rs/java/RenderScript/android/renderscript/RenderScript.java
index 796fe35..afb4ae3 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/RenderScript.java
+++ b/libs/rs/java/RenderScript/android/renderscript/RenderScript.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.fountain;
+package android.renderscript;
import java.io.InputStream;
import java.io.IOException;
@@ -67,6 +67,9 @@ public class RenderScript {
native private void nContextBindSampler(int sampler, int slot);
native private void nContextBindProgramFragmentStore(int pfs);
native private void nContextBindProgramFragment(int pf);
+ native private void nContextBindProgramVertex(int pf);
+
+ native private void nAssignName(int obj, byte[] name);
native private void nElementBegin();
native private void nElementAddPredefined(int predef);
@@ -100,6 +103,7 @@ public class RenderScript {
native private void nTriangleMeshAddVertex_XYZ (float x, float y, float z);
native private void nTriangleMeshAddVertex_XY_ST (float x, float y, float s, float t);
native private void nTriangleMeshAddVertex_XYZ_ST (float x, float y, float z, float s, float t);
+ native private void nTriangleMeshAddVertex_XYZ_ST_NORM (float x, float y, float z, float s, float t, float nx, float ny, float nz);
native private void nTriangleMeshAddTriangle(int i1, int i2, int i3);
native private int nTriangleMeshCreate();
@@ -135,6 +139,7 @@ public class RenderScript {
native private void nProgramFragmentStoreBlendFunc(int src, int dst);
native private void nProgramFragmentStoreDither(boolean enable);
native private int nProgramFragmentStoreCreate();
+ native private void nProgramFragmentStoreDestroy(int pgm);
native private void nProgramFragmentBegin(int in, int out);
native private void nProgramFragmentBindTexture(int vpf, int slot, int a);
@@ -143,6 +148,17 @@ public class RenderScript {
native private void nProgramFragmentSetEnvMode(int slot, int env);
native private void nProgramFragmentSetTexEnable(int slot, boolean enable);
native private int nProgramFragmentCreate();
+ native private void nProgramFragmentDestroy(int pgm);
+
+ native private void nProgramVertexDestroy(int pv);
+ native private void nProgramVertexBindAllocation(int pv, int slot, int mID);
+ native private void nProgramVertexBegin(int inID, int outID);
+ native private void nProgramVertexSetType(int slot, int mID);
+ native private void nProgramVertexSetCameraMode(boolean isOrtho);
+ native private void nProgramVertexSetTextureMatrixEnable(boolean enable);
+ native private void nProgramVertexSetModelMatrixEnable(boolean enable);
+ native private void nProgramVertexSetProjectionMatrixEnable(boolean enable);
+ native private int nProgramVertexCreate();
private int mDev;
@@ -165,7 +181,31 @@ public class RenderScript {
mID = 0;
}
+ public int getID() {
+ return mID;
+ }
+
int mID;
+ String mName;
+
+ public void setName(String s) throws IllegalStateException, IllegalArgumentException
+ {
+ if(s.length() < 1) {
+ throw new IllegalArgumentException("setName does not accept a zero length string.");
+ }
+ if(mName != null) {
+ throw new IllegalArgumentException("setName object already has a name.");
+ }
+
+ try {
+ byte[] bytes = s.getBytes("UTF-8");
+ nAssignName(mID, bytes);
+ mName = s;
+ } catch (java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
protected void finalize() throws Throwable
{
if (mID != 0) {
@@ -191,17 +231,19 @@ public class RenderScript {
A_8 (7),
RGB_565 (8),
- RGB_888 (12),
+ RGB_888 (11),
RGBA_5551 (9),
RGBA_4444 (10),
- RGBA_8888 (13),
+ RGBA_8888 (12),
- INDEX_16 (16),
- INDEX_32 (17),
- XY_F32 (18),
- XYZ_F32 (19),
- ST_XY_F32 (20),
- ST_XYZ_F32 (21);
+ INDEX_16 (13),
+ INDEX_32 (14),
+ XY_F32 (15),
+ XYZ_F32 (16),
+ ST_XY_F32 (17),
+ ST_XYZ_F32 (18),
+ NORM_XYZ_F32 (19),
+ NORM_ST_XYZ_F32 (20);
int mID;
ElementPredefined(int id) {
@@ -554,6 +596,10 @@ public class RenderScript {
nTriangleMeshAddVertex_XYZ_ST(x, y, z, s, t);
}
+ public void triangleMeshAddVertex_XYZ_ST_NORM(float x, float y, float z, float s, float t, float nx, float ny, float nz) {
+ nTriangleMeshAddVertex_XYZ_ST_NORM(x, y, z, s, t, nx, ny, nz);
+ }
+
public void triangleMeshAddTriangle(int i1, int i2, int i3) {
nTriangleMeshAddTriangle(i1, i2, i3);
}
@@ -653,6 +699,63 @@ public class RenderScript {
}
//////////////////////////////////////////////////////////////////////////////////
+ // ProgramVertex
+
+ public class ProgramVertex extends BaseObj {
+ ProgramVertex(int id) {
+ mID = id;
+ }
+
+ public void destroy() {
+ nProgramVertexDestroy(mID);
+ mID = 0;
+ }
+
+ public void bindAllocation(int slot, Allocation va) {
+ nProgramVertexBindAllocation(mID, slot, va.mID);
+ }
+
+ }
+
+ public void programVertexBegin(Element in, Element out) {
+ int inID = 0;
+ int outID = 0;
+ if (in != null) {
+ inID = in.mID;
+ }
+ if (out != null) {
+ outID = out.mID;
+ }
+ nProgramVertexBegin(inID, outID);
+ }
+
+ public void programVertexSetType(int slot, Type t) {
+ nProgramVertexSetType(slot, t.mID);
+ }
+
+ public void programVertexSetCameraMode(boolean isOrtho) {
+ nProgramVertexSetCameraMode(isOrtho);
+ }
+
+ public void programVertexSetTextureMatrixEnable(boolean enable) {
+ nProgramVertexSetTextureMatrixEnable(enable);
+ }
+
+ public void programVertexSetModelMatrixEnable(boolean enable) {
+ nProgramVertexSetModelMatrixEnable(enable);
+ }
+
+ public void programVertexSetProjectionMatrixEnable(boolean enable) {
+ nProgramVertexSetProjectionMatrixEnable(enable);
+ }
+
+ public ProgramVertex programVertexCreate() {
+ int id = nProgramVertexCreate();
+ return new ProgramVertex(id);
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////////////
// ProgramFragmentStore
public class ProgramFragmentStore extends BaseObj {
@@ -661,7 +764,7 @@ public class RenderScript {
}
public void destroy() {
- nScriptDestroy(mID);
+ nProgramFragmentStoreDestroy(mID);
mID = 0;
}
}
@@ -712,7 +815,7 @@ public class RenderScript {
}
public void destroy() {
- nScriptDestroy(mID);
+ nProgramFragmentDestroy(mID);
mID = 0;
}
@@ -801,6 +904,10 @@ public class RenderScript {
nContextBindProgramFragment(pf.mID);
}
+ public void contextBindProgramVertex(ProgramVertex pf) {
+ nContextBindProgramVertex(pf.mID);
+ }
+
/*
RsAdapter2D rsAdapter2DCreate ();
void rsAdapter2DBindAllocation (RsAdapter2D adapt, RsAllocation alloc);
diff --git a/libs/rs/java/Rollo/Android.mk b/libs/rs/java/Rollo/Android.mk
new file mode 100644
index 0000000..1c6dfdf
--- /dev/null
+++ b/libs/rs/java/Rollo/Android.mk
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := Rollo
+
+include $(BUILD_PACKAGE)
diff --git a/libs/rs/java/Rollo/AndroidManifest.xml b/libs/rs/java/Rollo/AndroidManifest.xml
new file mode 100644
index 0000000..da160a3
--- /dev/null
+++ b/libs/rs/java/Rollo/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.rollo">
+ <application android:label="Rollo">
+ <activity android:name="Rollo"
+ android:theme="@android:style/Theme.Black.NoTitleBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c
new file mode 100644
index 0000000..b81c567
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/rollo.c
@@ -0,0 +1,13 @@
+#pragma version(1)
+#pragma stateVertex(PV)
+#pragma stateFragment(PF)
+#pragma stateFragmentStore(PFSBackground)
+
+int main(void* con, int ft, int launchID)
+{
+ int x;
+
+ renderTriangleMesh(con, NAMED_MeshCard);
+ return 1;
+}
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java
new file mode 100644
index 0000000..400d801
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/Rollo.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rollo;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Config;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+
+import java.lang.Runtime;
+
+public class Rollo extends Activity {
+ //EventListener mListener = new EventListener();
+
+ private static final String LOG_TAG = "libRS_jni";
+ private static final boolean DEBUG = false;
+ private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
+
+ private RolloView mView;
+
+ // get the current looper (from your Activity UI thread for instance
+
+
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // Create our Preview view and set it as the content of our
+ // Activity
+ mView = new RolloView(this);
+ setContentView(mView);
+ }
+
+ @Override
+ protected void onResume() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onResume();
+ mView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.onPause();
+
+ Runtime.getRuntime().exit(0);
+ }
+
+
+ static void log(String message) {
+ if (LOG_ENABLED) {
+ Log.v(LOG_TAG, message);
+ }
+ }
+
+
+}
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java
new file mode 100644
index 0000000..c44a817
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloMesh.java
@@ -0,0 +1,65 @@
+ /*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.rollo;
+
+import java.io.Writer;
+import java.lang.Math;
+
+import android.renderscript.RenderScript;
+
+
+class RolloMesh {
+
+ static RenderScript.TriangleMesh createCard(RenderScript rs) {
+ RenderScript.Element vtx = rs.elementGetPredefined(
+ RenderScript.ElementPredefined.ST_XYZ_F32);
+ RenderScript.Element idx = rs.elementGetPredefined(
+ RenderScript.ElementPredefined.INDEX_16);
+
+ rs.triangleMeshBegin(vtx, idx);
+ rs.triangleMeshAddVertex_XYZ_ST(0, 0, 0, 0, 0);
+ rs.triangleMeshAddVertex_XYZ_ST(0, 1, 0, 0, 1);
+ rs.triangleMeshAddVertex_XYZ_ST(1, 1, 0, 1, 1);
+ rs.triangleMeshAddVertex_XYZ_ST(1, 0, 0, 1, 0);
+
+ rs.triangleMeshAddTriangle(0,1,2);
+ rs.triangleMeshAddTriangle(0,2,3);
+ return rs.triangleMeshCreate();
+ }
+
+ static RenderScript.TriangleMesh createTab(RenderScript rs) {
+ RenderScript.Element vtx = rs.elementGetPredefined(
+ RenderScript.ElementPredefined.ST_XYZ_F32);
+ RenderScript.Element idx = rs.elementGetPredefined(
+ RenderScript.ElementPredefined.INDEX_16);
+
+ rs.triangleMeshBegin(vtx, idx);
+ rs.triangleMeshAddVertex_XYZ_ST(0.0f, 0, 0, -1.0f, 0);
+ rs.triangleMeshAddVertex_XYZ_ST(0.2f, 1, 0, -0.8f, 1);
+ rs.triangleMeshAddVertex_XYZ_ST(1.8f, 1, 0, 0.8f, 1);
+ rs.triangleMeshAddVertex_XYZ_ST(2.0f, 0, 0, 1.0f, 0);
+ rs.triangleMeshAddTriangle(0,1,2);
+ rs.triangleMeshAddTriangle(0,2,3);
+ return rs.triangleMeshCreate();
+ }
+
+
+
+}
+
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
new file mode 100644
index 0000000..aa9f338
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rollo;
+
+import java.io.Writer;
+
+import android.renderscript.RenderScript;
+import android.renderscript.ProgramVertexAlloc;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class RolloRS {
+
+ public RolloRS() {
+ }
+
+ public void init(RenderScript rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ initNamed();
+ initRS();
+ }
+
+
+ private Resources mRes;
+ private RenderScript mRS;
+
+
+ private RenderScript.Script mScript;
+
+ private RenderScript.Sampler mSampler;
+ private RenderScript.ProgramFragmentStore mPFSBackground;
+ private RenderScript.ProgramFragmentStore mPFSImages;
+ private RenderScript.ProgramFragment mPFBackground;
+ private RenderScript.ProgramFragment mPFImages;
+ private RenderScript.ProgramVertex mPV;
+ private ProgramVertexAlloc mPVAlloc;
+
+ private RenderScript.Allocation mAllocEnv;
+ private RenderScript.Allocation mAllocPos;
+ private RenderScript.Allocation mAllocState;
+ //private RenderScript.Allocation mAllocPV;
+ private RenderScript.TriangleMesh mMeshCard;
+ private RenderScript.TriangleMesh mMeshTab;
+
+ private float[] mBufferPos;
+ //private float[] mBufferPV;
+
+ private void initNamed() {
+ //mMeshTab = RolloMesh.createTab(mRS);
+ //mMeshTab.setName("MeshTab");
+ mMeshCard = RolloMesh.createCard(mRS);
+ mMeshCard.setName("MeshCard");
+ Log.e("rs", "Done loading strips");
+
+ mRS.samplerBegin();
+ mRS.samplerSet(RenderScript.SamplerParam.FILTER_MIN,
+ RenderScript.SamplerValue.LINEAR_MIP_LINEAR);
+ mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_S,
+ RenderScript.SamplerValue.CLAMP);
+ mRS.samplerSet(RenderScript.SamplerParam.WRAP_MODE_T,
+ RenderScript.SamplerValue.CLAMP);
+ mSampler = mRS.samplerCreate();
+
+
+ mRS.programFragmentBegin(null, null);
+ mRS.programFragmentSetTexEnable(0, true);
+ //mRS.programFragmentSetEnvMode(0, RS_TEX_ENV_MODE_REPLACE);
+ mPFImages = mRS.programFragmentCreate();
+ mPFImages.setName("PF");
+ mPFImages.bindSampler(mSampler, 0);
+
+ mRS.programFragmentStoreBegin(null, null);
+ mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.ALWAYS);
+ mRS.programFragmentStoreDitherEnable(true);
+ mPFSBackground = mRS.programFragmentStoreCreate();
+ mPFSBackground.setName("PFSBackground");
+
+ /*
+ mRS.programFragmentStoreBegin(null, null);
+ mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.EQUAL);
+ mRS.programFragmentStoreDitherEnable(false);
+ mRS.programFragmentStoreDepthMask(false);
+ mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE,
+ RenderScript.BlendDstFunc.ONE);
+ mPFSImages = mRS.programFragmentStoreCreate();
+ mPFSImages.setName("PFSImages");
+*/
+
+
+ mPVAlloc = new ProgramVertexAlloc(mRS);
+ mRS.programVertexBegin(null, null);
+ mRS.programVertexSetCameraMode(true);
+ mRS.programVertexSetTextureMatrixEnable(true);
+ mRS.programVertexSetModelMatrixEnable(true);
+ mRS.programVertexSetProjectionMatrixEnable(true);
+ mPV = mRS.programVertexCreate();
+ mPV.setName("PV");
+ mPV.bindAllocation(0, mPVAlloc.mAlloc);
+
+ mPVAlloc.setupProjectionNormalized(320, 480);
+ //mPVAlloc.setupOrthoNormalized(320, 480);
+ mRS.contextBindProgramVertex(mPV);
+
+
+ Log.e("rs", "Done loading named");
+ }
+
+
+ private void initRS() {
+ mRS.scriptCBegin();
+ mRS.scriptCSetClearColor(0.0f, 0.7f, 0.0f, 1.0f);
+ mRS.scriptCSetScript(mRes, R.raw.rollo);
+ mRS.scriptCSetRoot(true);
+ mScript = mRS.scriptCCreate();
+
+
+ mRS.contextBindRootScript(mScript);
+ }
+}
+
+
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
new file mode 100644
index 0000000..9a30aed
--- /dev/null
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rollo;
+
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+public class RolloView extends RSSurfaceView {
+
+ public RolloView(Context context) {
+ super(context);
+
+ //setFocusable(true);
+ }
+
+ private RenderScript mRS;
+ private RolloRS mRender;
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+
+ mRS = createRenderScript();
+ mRender = new RolloRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event)
+ {
+ // break point at here
+ // this method doesn't work when 'extends View' include 'extends ScrollView'.
+ return super.onKeyDown(keyCode, event);
+ }
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev)
+ {
+ boolean ret = true;
+ int act = ev.getAction();
+ if (act == ev.ACTION_UP) {
+ ret = false;
+ }
+ //mRender.newTouchPosition((int)ev.getX(), (int)ev.getY());
+ return ret;
+ }
+}
+
+
diff --git a/libs/rs/jni/Android.mk b/libs/rs/jni/Android.mk
new file mode 100644
index 0000000..b3142ae
--- /dev/null
+++ b/libs/rs/jni/Android.mk
@@ -0,0 +1,36 @@
+LOCAL_PATH:=$(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ RenderScript_jni.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libandroid_runtime \
+ libacc \
+ libnativehelper \
+ libRS \
+ libcutils \
+ libsgl \
+ libutils \
+ libui
+
+LOCAL_STATIC_LIBRARIES :=
+
+rs_generated_include_dir := $(call intermediates-dir-for,SHARED_LIBRARIES,libRS,,)
+
+LOCAL_C_INCLUDES += \
+ $(JNI_H_INCLUDE) \
+ $(rs_generated_include_dir) \
+ $(call include-path-for, corecg graphics)
+
+LOCAL_CFLAGS +=
+
+LOCAL_LDLIBS := -lpthread
+
+LOCAL_MODULE:= libRS_jni
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_ADDITIONAL_DEPENDENCIES += $(rs_generated_source)
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/libs/rs/jni/RenderScript_jni.cpp b/libs/rs/jni/RenderScript_jni.cpp
index 61866b7..7a3a7af 100644
--- a/libs/rs/jni/RenderScript_jni.cpp
+++ b/libs/rs/jni/RenderScript_jni.cpp
@@ -35,8 +35,6 @@
#include "../RenderScript.h"
#include "../RenderScriptEnv.h"
-#include "acc/acc.h"
-
//#define LOG_API LOGE
#define LOG_API(...)
@@ -64,6 +62,21 @@ static void _nInit(JNIEnv *_env, jclass _this)
// ---------------------------------------------------------------------------
+static void
+nAssignName(JNIEnv *_env, jobject _this, jint obj, jbyteArray str)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nAssignName, con(%p), obj(%p)", con, obj);
+
+ jint len = _env->GetArrayLength(str);
+ jbyte * cptr = (jbyte *) _env->GetPrimitiveArrayCritical(str, 0);
+ rsAssignName((void *)obj, (const char *)cptr, len);
+ _env->ReleasePrimitiveArrayCritical(str, cptr, JNI_ABORT);
+}
+
+
+// ---------------------------------------------------------------------------
+
static jint
nDeviceCreate(JNIEnv *_env, jobject _this)
{
@@ -398,6 +411,15 @@ nTriangleMeshAddVertex_XYZ_ST(JNIEnv *_env, jobject _this, jfloat x, jfloat y, j
}
static void
+nTriangleMeshAddVertex_XYZ_ST_NORM(JNIEnv *_env, jobject _this, jfloat x, jfloat y, jfloat z, jfloat s, jfloat t, jfloat nx, jfloat ny, jfloat nz)
+{
+ float v[] = {nx, ny, nz, s, t, x, y, z};
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nTriangleMeshAddVertex_XYZ_ST, con(%p), x(%f), y(%f), z(%f), s(%f), t(%f)", con, x, y, z, s, t);
+ rsTriangleMeshAddVertex(v);
+}
+
+static void
nTriangleMeshAddTriangle(JNIEnv *_env, jobject _this, jint i1, jint i2, jint i3)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -567,8 +589,6 @@ nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef,
jint remaining;
jbyte* script_base = 0;
jbyte* script_ptr;
- ACCscript* script = 0;
- void* scriptEntry = 0;
if (!scriptRef) {
_exception = 1;
//_env->ThrowNew(IAEClass, "script == null");
@@ -594,22 +614,9 @@ nScriptCSetScript(JNIEnv *_env, jobject _this, jbyteArray scriptRef,
_env->GetPrimitiveArrayCritical(scriptRef, (jboolean *)0);
script_ptr = script_base + offset;
- {
- script = accCreateScript();
- const char* scriptSource[] = {(const char*) script_ptr};
- int scriptLength[] = {length} ;
- accScriptSource(script, 1, scriptSource, scriptLength);
- accCompileScript(script);
- accGetScriptLabel(script, "main", (ACCvoid**) &scriptEntry);
- }
- if (scriptEntry) {
- rsScriptCSetScript((void*) script, (void *)scriptEntry);
- script = 0;
- }
+ rsScriptCSetText((const char *)script_ptr, length);
+
exit:
- if (script) {
- accDeleteScript(script);
- }
if (script_base) {
_env->ReleasePrimitiveArrayCritical(scriptRef, script_base,
_exception ? JNI_ABORT: 0);
@@ -679,9 +686,18 @@ nProgramFragmentStoreCreate(JNIEnv *_env, jobject _this)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
LOG_API("nProgramFragmentStoreCreate, con(%p)", con);
+
return (jint)rsProgramFragmentStoreCreate();
}
+static void
+nProgramFragmentStoreDestroy(JNIEnv *_env, jobject _this, jint pgm)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramFragmentStoreDestroy, con(%p), pgm(%i)", con, pgm);
+ rsProgramFragmentStoreDestroy((RsProgramFragmentStore)pgm);
+}
+
// ---------------------------------------------------------------------------
static void
@@ -740,6 +756,90 @@ nProgramFragmentCreate(JNIEnv *_env, jobject _this, jint slot, jboolean enable)
return (jint)rsProgramFragmentCreate();
}
+static void
+nProgramFragmentDestroy(JNIEnv *_env, jobject _this, jint pgm)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramFragmentDestroy, con(%p), pgm(%i)", con, pgm);
+ rsProgramFragmentDestroy((RsProgramFragment)pgm);
+}
+
+// ---------------------------------------------------------------------------
+
+static void
+nProgramVertexBegin(JNIEnv *_env, jobject _this, jint in, jint out)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexBegin, con(%p), in(%p), out(%p)", con, (RsElement)in, (RsElement)out);
+ rsProgramVertexBegin((RsElement)in, (RsElement)out);
+}
+
+static void
+nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint slot, jint a)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
+ rsProgramVertexBindAllocation((RsProgramFragment)vpv, slot, (RsAllocation)a);
+}
+
+static void
+nProgramVertexSetType(JNIEnv *_env, jobject _this, jint slot, jint t)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexSetType, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsType)t);
+ rsProgramVertexSetType(slot, (RsType)t);
+}
+
+static void
+nProgramVertexSetCameraMode(JNIEnv *_env, jobject _this, jboolean isOrtho)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexSetCameraMode, con(%p), isOrtho(%i)", con, isOrtho);
+ rsProgramVertexSetCameraMode(isOrtho);
+}
+
+static void
+nProgramVertexSetTextureMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexSetTextureMatrixEnable, con(%p), enable(%i)", con, enable);
+ rsProgramVertexSetTextureMatrixEnable(enable);
+}
+
+static void
+nProgramVertexSetModelMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexSetModelMatrixEnable, con(%p), enable(%i)", con, enable);
+ rsProgramVertexSetModelMatrixEnable(enable);
+}
+
+static void
+nProgramVertexSetProjectionMatrixEnable(JNIEnv *_env, jobject _this, jboolean enable)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexSetProjectionMatrixEnable, con(%p), enable(%i)", con, enable);
+ rsProgramVertexSetProjectionMatrixEnable(enable);
+}
+
+static jint
+nProgramVertexCreate(JNIEnv *_env, jobject _this)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramVertexCreate, con(%p)", con);
+ return (jint)rsProgramVertexCreate();
+}
+
+static void
+nProgramVertexDestroy(JNIEnv *_env, jobject _this, jint pgm)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nProgramFragmentDestroy, con(%p), pgm(%i)", con, pgm);
+ rsProgramFragmentDestroy((RsProgramFragment)pgm);
+}
+
+
+
// ---------------------------------------------------------------------------
@@ -767,6 +867,14 @@ nContextBindProgramFragment(JNIEnv *_env, jobject _this, jint pf)
rsContextBindProgramFragment((RsProgramFragment)pf);
}
+static void
+nContextBindProgramVertex(JNIEnv *_env, jobject _this, jint pf)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+ LOG_API("nContextBindProgramVertex, con(%p), pf(%p)", con, (RsProgramVertex)pf);
+ rsContextBindProgramVertex((RsProgramVertex)pf);
+}
+
// ---------------------------------------------------------------------------
static void
@@ -805,7 +913,7 @@ nSamplerCreate(JNIEnv *_env, jobject _this)
// ---------------------------------------------------------------------------
-static const char *classPathName = "com/android/fountain/RenderScript";
+static const char *classPathName = "android/renderscript/RenderScript";
static JNINativeMethod methods[] = {
{"_nInit", "()V", (void*)_nInit },
@@ -813,6 +921,7 @@ static JNINativeMethod methods[] = {
{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy },
{"nContextCreate", "(ILandroid/view/Surface;I)I", (void*)nContextCreate },
{"nContextDestroy", "(I)V", (void*)nContextDestroy },
+{"nAssignName", "(I[B)V", (void*)nAssignName },
{"nElementBegin", "()V", (void*)nElementBegin },
{"nElementAddPredefined", "(I)V", (void*)nElementAddPredefined },
@@ -845,6 +954,7 @@ static JNINativeMethod methods[] = {
{"nTriangleMeshAddVertex_XYZ", "(FFF)V", (void*)nTriangleMeshAddVertex_XYZ },
{"nTriangleMeshAddVertex_XY_ST", "(FFFF)V", (void*)nTriangleMeshAddVertex_XY_ST },
{"nTriangleMeshAddVertex_XYZ_ST", "(FFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST },
+{"nTriangleMeshAddVertex_XYZ_ST_NORM", "(FFFFFFFF)V", (void*)nTriangleMeshAddVertex_XYZ_ST_NORM },
{"nTriangleMeshAddTriangle", "(III)V", (void*)nTriangleMeshAddTriangle },
{"nTriangleMeshCreate", "()I", (void*)nTriangleMeshCreate },
@@ -875,6 +985,7 @@ static JNINativeMethod methods[] = {
{"nProgramFragmentStoreBlendFunc", "(II)V", (void*)nProgramFragmentStoreBlendFunc },
{"nProgramFragmentStoreDither", "(Z)V", (void*)nProgramFragmentStoreDither },
{"nProgramFragmentStoreCreate", "()I", (void*)nProgramFragmentStoreCreate },
+{"nProgramFragmentStoreDestroy", "(I)V", (void*)nProgramFragmentStoreDestroy },
{"nProgramFragmentBegin", "(II)V", (void*)nProgramFragmentBegin },
{"nProgramFragmentBindTexture", "(III)V", (void*)nProgramFragmentBindTexture },
@@ -883,10 +994,22 @@ static JNINativeMethod methods[] = {
{"nProgramFragmentSetEnvMode", "(II)V", (void*)nProgramFragmentSetEnvMode },
{"nProgramFragmentSetTexEnable", "(IZ)V", (void*)nProgramFragmentSetTexEnable },
{"nProgramFragmentCreate", "()I", (void*)nProgramFragmentCreate },
+{"nProgramFragmentDestroy", "(I)V", (void*)nProgramFragmentDestroy },
+
+{"nProgramVertexDestroy", "(I)V", (void*)nProgramVertexDestroy },
+{"nProgramVertexBindAllocation", "(III)V", (void*)nProgramVertexBindAllocation },
+{"nProgramVertexBegin", "(II)V", (void*)nProgramVertexBegin },
+{"nProgramVertexSetType", "(II)V", (void*)nProgramVertexSetType },
+{"nProgramVertexSetCameraMode", "(Z)V", (void*)nProgramVertexSetCameraMode },
+{"nProgramVertexSetTextureMatrixEnable", "(Z)V", (void*)nProgramVertexSetTextureMatrixEnable },
+{"nProgramVertexSetModelMatrixEnable", "(Z)V", (void*)nProgramVertexSetModelMatrixEnable },
+{"nProgramVertexSetProjectionMatrixEnable", "(Z)V", (void*)nProgramVertexSetProjectionMatrixEnable },
+{"nProgramVertexCreate", "()I", (void*)nProgramVertexCreate },
{"nContextBindRootScript", "(I)V", (void*)nContextBindRootScript },
{"nContextBindProgramFragmentStore","(I)V", (void*)nContextBindProgramFragmentStore },
{"nContextBindProgramFragment", "(I)V", (void*)nContextBindProgramFragment },
+{"nContextBindProgramVertex", "(I)V", (void*)nContextBindProgramVertex },
{"nSamplerDestroy", "(I)V", (void*)nSamplerDestroy },
{"nSamplerBegin", "()V", (void*)nSamplerBegin },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 090be32..107096f 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -16,6 +16,11 @@ ContextBindProgramVertex {
param RsProgramVertex pgm
}
+AssignName {
+ param void *obj
+ param const char *name
+ param size_t len
+ }
ElementBegin {
}
@@ -286,10 +291,14 @@ ScriptCSetOrtho {
}
ScriptCSetScript {
- param void * accScript
param void * codePtr
}
+ScriptCSetText {
+ param const char * text
+ param uint32_t length
+ }
+
ScriptCCreate {
ret RsScript
}
@@ -328,6 +337,9 @@ ProgramFragmentStoreCreate {
ret RsProgramFragmentStore
}
+ProgramFragmentStoreDestroy {
+ param RsProgramFragmentStore pfs
+ }
ProgramFragmentBegin {
@@ -366,6 +378,9 @@ ProgramFragmentCreate {
ret RsProgramFragment
}
+ProgramFragmentDestroy {
+ param RsProgramFragment pf
+ }
ProgramVertexBegin {
@@ -400,3 +415,7 @@ ProgramVertexSetModelMatrixEnable {
param bool enable
}
+ProgramVertexSetProjectionMatrixEnable {
+ param bool enable
+ }
+
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index ec4a309..266c455 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -17,7 +17,7 @@
#include "rsDevice.h"
#include "rsContext.h"
#include "rsThreadIO.h"
-
+#include "utils/String8.h"
using namespace android;
using namespace android::renderscript;
@@ -37,13 +37,9 @@ void Context::initEGL()
EGL_NONE
};
- LOGE("EGL 1");
mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- LOGE("EGL 2 %p", mDisplay);
eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion);
- LOGE("EGL 3 %i %i", mMajorVersion, mMinorVersion);
eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs);
- LOGE("EGL 4 %p", mConfig);
if (mWndSurface) {
mSurface = eglCreateWindowSurface(mDisplay, mConfig,
@@ -55,30 +51,43 @@ void Context::initEGL()
NULL);
}
- LOGE("EGL 5");
mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL);
eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth);
eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight);
- LOGE("EGL 9");
+}
+
+bool Context::runScript(Script *s, uint32_t launchID)
+{
+ ObjectBaseRef<ProgramFragment> frag(mFragment);
+ ObjectBaseRef<ProgramVertex> vtx(mVertex);
+ ObjectBaseRef<ProgramFragmentStore> store(mFragmentStore);
+
+ bool ret = s->run(this, launchID);
+
+ mFragment.set(frag);
+ mVertex.set(vtx);
+ mFragmentStore.set(store);
+ return true;
}
+
bool Context::runRootScript()
{
- rsAssert(mRootScript->mIsRoot);
+ rsAssert(mRootScript->mEnviroment.mIsRoot);
glColor4f(1,1,1,1);
glEnable(GL_LIGHT0);
- glViewport(0, 0, 320, 480);
- float aspectH = 480.f / 320.f;
+ glViewport(0, 0, mWidth, mHeight);
- if(mRootScript->mIsOrtho) {
+ if(mRootScript->mEnviroment.mIsOrtho) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrthof(0, 320, 480, 0, 0, 1);
+ glOrthof(0, mWidth, mHeight, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
} else {
+ float aspectH = ((float)mWidth) / mHeight;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-1, 1, -aspectH, aspectH, 1, 100);
@@ -93,15 +102,15 @@ bool Context::runRootScript()
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glClearColor(mRootScript->mClearColor[0],
- mRootScript->mClearColor[1],
- mRootScript->mClearColor[2],
- mRootScript->mClearColor[3]);
- glClearDepthf(mRootScript->mClearDepth);
+ glClearColor(mRootScript->mEnviroment.mClearColor[0],
+ mRootScript->mEnviroment.mClearColor[1],
+ mRootScript->mEnviroment.mClearColor[2],
+ mRootScript->mEnviroment.mClearColor[3]);
+ glClearDepthf(mRootScript->mEnviroment.mClearDepth);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
- return mRootScript->run(this, 0);
+ return runScript(mRootScript.get(), 0);
}
void Context::setupCheck()
@@ -123,16 +132,11 @@ void * Context::threadProc(void *vrsc)
{
Context *rsc = static_cast<Context *>(vrsc);
- LOGE("TP 1");
gIO = new ThreadIO();
-
rsc->mServerCommands.init(128);
rsc->mServerReturns.init(128);
rsc->initEGL();
-
- LOGE("TP 2");
-
rsc->mRunning = true;
bool mDraw = true;
while (!rsc->mExit) {
@@ -149,7 +153,6 @@ void * Context::threadProc(void *vrsc)
}
}
- LOGE("TP 6");
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
@@ -159,7 +162,6 @@ void * Context::threadProc(void *vrsc)
Context::Context(Device *dev, Surface *sur)
{
- LOGE("CC 1");
dev->addContext(this);
mDev = dev;
mRunning = false;
@@ -171,7 +173,6 @@ Context::Context(Device *dev, Surface *sur)
// see comment in header
gCon = this;
- LOGE("CC 2");
int status;
pthread_attr_t threadAttr;
@@ -185,17 +186,16 @@ Context::Context(Device *dev, Surface *sur)
sparam.sched_priority = ANDROID_PRIORITY_DISPLAY;
pthread_attr_setschedparam(&threadAttr, &sparam);
+ LOGE("RS Launching thread");
status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
if (status) {
LOGE("Failed to start rs context thread.");
}
- LOGE("CC 3");
mWndSurface = sur;
while(!mRunning) {
sleep(1);
}
- LOGE("CC 4");
pthread_attr_destroy(&threadAttr);
}
@@ -205,14 +205,11 @@ Context::~Context()
mExit = true;
void *res;
- LOGE("DES 1");
int status = pthread_join(mThreadId, &res);
- LOGE("DES 2");
if (mDev) {
mDev->removeContext(this);
}
- LOGE("DES 3");
}
void Context::swapBuffers()
@@ -249,6 +246,46 @@ void Context::setVertex(ProgramVertex *pv)
pv->setupGL();
}
+void Context::assignName(ObjectBase *obj, const char *name, uint32_t len)
+{
+ rsAssert(!obj->getName());
+ obj->setName(name, len);
+ mNames.add(obj);
+}
+
+void Context::removeName(ObjectBase *obj)
+{
+ for(size_t ct=0; ct < mNames.size(); ct++) {
+ if (obj == mNames[ct]) {
+ mNames.removeAt(ct);
+ return;
+ }
+ }
+}
+
+ObjectBase * Context::lookupName(const char *name) const
+{
+ for(size_t ct=0; ct < mNames.size(); ct++) {
+ if (!strcmp(name, mNames[ct]->getName())) {
+ return mNames[ct];
+ }
+ }
+ return NULL;
+}
+
+void Context::appendNameDefines(String8 *str) const
+{
+ char buf[256];
+ for (size_t ct=0; ct < mNames.size(); ct++) {
+ str->append("#define NAMED_");
+ str->append(mNames[ct]->getName());
+ str->append(" ");
+ sprintf(buf, "%i\n", (int)mNames[ct]);
+ str->append(buf);
+ }
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////
//
@@ -292,6 +329,11 @@ void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
rsc->setVertex(pv);
}
+void rsi_AssignName(Context *rsc, void * obj, const char *name, uint32_t len)
+{
+ ObjectBase *ob = static_cast<ObjectBase *>(obj);
+ rsc->assignName(ob, name, len);
+}
}
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 64717e4..21ae8c5 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -42,7 +42,6 @@
namespace android {
namespace renderscript {
-
class Context
{
public:
@@ -77,6 +76,11 @@ public:
void setupCheck();
+ void assignName(ObjectBase *obj, const char *name, uint32_t len);
+ void removeName(ObjectBase *obj);
+ ObjectBase * lookupName(const char *name) const;
+ void appendNameDefines(String8 *str) const;
+
protected:
Device *mDev;
@@ -103,11 +107,16 @@ protected:
ObjectBaseRef<ProgramVertex> mVertex;
ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+ ProgramFragment * mDefaultFragment;
+ ProgramVertex * mDefaultVertex;
+ ProgramFragmentStore * mDefaultFragmentStore;
+
private:
Context();
void initEGL();
+ bool runScript(Script *s, uint32_t launchID);
bool runRootScript();
static void * threadProc(void *);
@@ -115,6 +124,8 @@ private:
// todo: put in TLS
static Context *gCon;
Surface *mWndSurface;
+
+ Vector<ObjectBase *> mNames;
};
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index f9cb9c8..8f5232a 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -23,6 +23,7 @@ using namespace android::renderscript;
ObjectBase::ObjectBase()
{
mRefCount = 0;
+ mName = NULL;
}
ObjectBase::~ObjectBase()
@@ -46,3 +47,24 @@ void ObjectBase::decRef() const
}
}
+void ObjectBase::setName(const char *name)
+{
+ delete mName;
+ mName = NULL;
+ if (name) {
+ mName = new char[strlen(name) +1];
+ strcpy(mName, name);
+ }
+}
+
+void ObjectBase::setName(const char *name, uint32_t len)
+{
+ delete mName;
+ mName = NULL;
+ if (name) {
+ mName = new char[len + 1];
+ memcpy(mName, name, len);
+ mName[len] = 0;
+ }
+}
+
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index 7761e49..b2c3338 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -33,7 +33,14 @@ public:
void incRef() const;
void decRef() const;
+ const char * getName() const {
+ return mName;
+ }
+ void setName(const char *);
+ void setName(const char *, uint32_t len);
+
private:
+ char * mName;
mutable int32_t mRefCount;
@@ -47,6 +54,20 @@ public:
mRef = NULL;
}
+ ObjectBaseRef(const ObjectBaseRef &ref) {
+ mRef = ref.get();
+ if (mRef) {
+ mRef->incRef();
+ }
+ }
+
+ ObjectBaseRef(T *ref) {
+ mRef = ref;
+ if (mRef) {
+ ref->incRef();
+ }
+ }
+
~ObjectBaseRef() {
clear();
}
@@ -55,10 +76,16 @@ public:
if (mRef != ref) {
clear();
mRef = ref;
- ref->incRef();
+ if (mRef) {
+ ref->incRef();
+ }
}
}
+ void set(const ObjectBaseRef &ref) {
+ set(ref.mRef);
+ }
+
void clear() {
if (mRef) {
mRef->decRef();
@@ -77,9 +104,6 @@ public:
protected:
T * mRef;
-private:
- ObjectBaseRef(const ObjectBaseRef &) {};
-
};
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 3d316ea..316e791 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -212,6 +212,14 @@ RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc)
return pf;
}
+void rsi_ProgramFragmentDestroy(Context *rsc, RsProgramFragment vpf)
+{
+ ProgramFragment *pf = (ProgramFragment *)vpf;
+ if (pf->getName()) {
+ rsc->removeName(pf);
+ }
+ pf->decRef();
+}
}
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index cc08aea..ed9c49b 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -85,7 +85,7 @@ public:
ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
-
+ Vector<ProgramFragment *> mPrograms;
};
diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp
index 7f5d5f4..a1855a6 100644
--- a/libs/rs/rsProgramFragmentStore.cpp
+++ b/libs/rs/rsProgramFragmentStore.cpp
@@ -202,7 +202,6 @@ ProgramFragmentStoreState::~ProgramFragmentStoreState()
}
-
namespace android {
namespace renderscript {
@@ -238,7 +237,6 @@ RsProgramFragmentStore rsi_ProgramFragmentStoreCreate(Context *rsc)
ProgramFragmentStore *pfs = rsc->mStateFragmentStore.mPFS;
pfs->incRef();
rsc->mStateFragmentStore.mPFS = 0;
-
return pfs;
}
@@ -247,6 +245,17 @@ void rsi_ProgramFragmentStoreDither(Context *rsc, bool enable)
rsc->mStateFragmentStore.mPFS->setDitherEnable(enable);
}
+void rsi_ProgramFragmentStoreDestroy(Context *rsc, RsProgramFragmentStore vpfs)
+{
+ ProgramFragmentStore *pfs = (ProgramFragmentStore *)vpfs;
+ if (pfs->getName()) {
+ rsc->removeName(pfs);
+ }
+ pfs->decRef();
+}
+
+
+
}
}
diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h
index bbd0f38..d862775 100644
--- a/libs/rs/rsProgramFragmentStore.h
+++ b/libs/rs/rsProgramFragmentStore.h
@@ -76,8 +76,6 @@ public:
~ProgramFragmentStoreState();
ProgramFragmentStore *mPFS;
-
-
};
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 8e2b82d..fc26ab5 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -47,7 +47,7 @@ void ProgramVertex::setupGL()
glMatrixMode(GL_PROJECTION);
if (mProjectionEnable) {
- //glLoadMatrixf(&f[OFFSET_PROJECTION]);
+ glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
} else {
}
@@ -57,7 +57,6 @@ void ProgramVertex::setupGL()
} else {
glLoadIdentity();
}
-
}
void ProgramVertex::setConstantType(uint32_t slot, const Type *t)
@@ -97,7 +96,6 @@ RsProgramVertex rsi_ProgramVertexCreate(Context *rsc)
ProgramVertex *pv = rsc->mStateVertex.mPV;
pv->incRef();
rsc->mStateVertex.mPV = 0;
-
return pv;
}
@@ -127,6 +125,11 @@ void rsi_ProgramVertexSetModelMatrixEnable(Context *rsc, bool enable)
rsc->mStateVertex.mPV->setTransformEnable(enable);
}
+void rsi_ProgramVertexSetProjectionMatrixEnable(Context *rsc, bool enable)
+{
+ rsc->mStateVertex.mPV->setProjectionEnable(enable);
+}
+
}
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index cd46900..677be6e 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -40,6 +40,7 @@ public:
void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
void setProjectionEnabled(bool e) {mProjectionEnable = e;}
void setTransformEnable(bool e) {mTransformEnable = e;}
+ void setProjectionEnable(bool e) {mProjectionEnable = e;}
protected:
bool mDirty;
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 24a630c..ae85c9c 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -21,11 +21,12 @@ using namespace android::renderscript;
Script::Script()
{
- mClearColor[0] = 0;
- mClearColor[1] = 0;
- mClearColor[2] = 0;
- mClearColor[3] = 1;
- mClearDepth = 1;
+ memset(&mEnviroment, 0, sizeof(mEnviroment));
+ mEnviroment.mClearColor[0] = 0;
+ mEnviroment.mClearColor[1] = 0;
+ mEnviroment.mClearColor[2] = 0;
+ mEnviroment.mClearColor[3] = 1;
+ mEnviroment.mClearDepth = 1;
}
Script::~Script()
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 0229860..d32f116 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -19,11 +19,15 @@
#include "rsAllocation.h"
+
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
-
+class ProgramVertex;
+class ProgramFragment;
+class ProgramRaster;
+class ProgramFragmentStore;
class Script : public ObjectBase
{
@@ -33,13 +37,20 @@ public:
virtual ~Script();
- bool mIsRoot;
- bool mIsOrtho;
+ struct Enviroment_t {
+ bool mIsRoot;
+ bool mIsOrtho;
+ float mClearColor[4];
+ float mClearDepth;
+ uint32_t mClearStencil;
- float mClearColor[4];
- float mClearDepth;
- uint32_t mClearStencil;
+ ObjectBaseRef<ProgramVertex> mVertex;
+ ObjectBaseRef<ProgramFragment> mFragment;
+ //ObjectBaseRef<ProgramRaster> mRaster;
+ ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+ };
+ Enviroment_t mEnviroment;
const Type * mConstantBufferTypes;
uint32_t mCounstantBufferCount;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 36019ab..d29eb9f 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -19,6 +19,7 @@
#include "rsMatrix.h"
#include "acc/acc.h"
+#include "utils/String8.h"
using namespace android;
using namespace android::renderscript;
@@ -27,7 +28,7 @@ using namespace android::renderscript;
ScriptC::ScriptC()
{
mAccScript = NULL;
- mScript = NULL;
+ memset(&mProgram, 0, sizeof(mProgram));
}
ScriptC::~ScriptC()
@@ -390,7 +391,15 @@ static rsc_FunctionTable scriptCPtrTable = {
bool ScriptC::run(Context *rsc, uint32_t launchID)
{
Env e = {rsc, this};
- return mScript(&e, &scriptCPtrTable, launchID) != 0;
+
+ if (mEnviroment.mFragmentStore.get()) {
+ rsc->setFragmentStore(mEnviroment.mFragmentStore.get());
+ }
+ if (mEnviroment.mFragment.get()) {
+ rsc->setFragment(mEnviroment.mFragment.get());
+ }
+
+ return mProgram.mScript(&e, &scriptCPtrTable, launchID) != 0;
}
ScriptCState::ScriptCState()
@@ -407,17 +416,96 @@ ScriptCState::~ScriptCState()
void ScriptCState::clear()
{
+ memset(&mProgram, 0, sizeof(mProgram));
+
mConstantBufferTypes.clear();
- mClearColor[0] = 0;
- mClearColor[1] = 0;
- mClearColor[2] = 0;
- mClearColor[3] = 1;
- mClearDepth = 1;
- mClearStencil = 0;
+
+ memset(&mEnviroment, 0, sizeof(mEnviroment));
+ mEnviroment.mClearColor[0] = 0;
+ mEnviroment.mClearColor[1] = 0;
+ mEnviroment.mClearColor[2] = 0;
+ mEnviroment.mClearColor[3] = 1;
+ mEnviroment.mClearDepth = 1;
+ mEnviroment.mClearStencil = 0;
+ mEnviroment.mIsRoot = false;
+ mEnviroment.mIsOrtho = true;
+
mAccScript = NULL;
- mScript = NULL;
- mIsRoot = false;
- mIsOrtho = true;
+
+}
+
+
+void ScriptCState::runCompiler(Context *rsc)
+{
+ mAccScript = accCreateScript();
+ String8 tmp;
+
+ rsc->appendNameDefines(&tmp);
+
+ const char* scriptSource[] = {tmp.string(), mProgram.mScriptText};
+ int scriptLength[] = {tmp.length(), mProgram.mScriptTextLength} ;
+ accScriptSource(mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength);
+ accCompileScript(mAccScript);
+ accGetScriptLabel(mAccScript, "main", (ACCvoid**) &mProgram.mScript);
+ rsAssert(mProgram.mScript);
+
+
+ if (mProgram.mScript) {
+ const static int pragmaMax = 16;
+ ACCsizei pragmaCount;
+ ACCchar * str[pragmaMax];
+ accGetPragmas(mAccScript, &pragmaCount, pragmaMax, &str[0]);
+
+ for (int ct=0; ct < pragmaCount; ct+=2) {
+ LOGE("pragma %i %s %s", ct, str[ct], str[ct+1]);
+
+ if (!strcmp(str[ct], "version")) {
+ continue;
+
+ }
+
+
+ if (!strcmp(str[ct], "stateVertex")) {
+ LOGE("Unreconized value %s passed to stateVertex", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateRaster")) {
+ LOGE("Unreconized value %s passed to stateRaster", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateFragment")) {
+ ProgramFragment * pf =
+ (ProgramFragment *)rsc->lookupName(str[ct+1]);
+ if (pf != NULL) {
+ mEnviroment.mFragment.set(pf);
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateFragment", str[ct+1]);
+ }
+
+ if (!strcmp(str[ct], "stateFragmentStore")) {
+ ProgramFragmentStore * pfs =
+ (ProgramFragmentStore *)rsc->lookupName(str[ct+1]);
+ if (pfs != NULL) {
+ mEnviroment.mFragmentStore.set(pfs);
+ continue;
+ }
+
+ if (!strcmp(str[ct+1], "parent")) {
+ //mEnviroment.mStateFragmentStore =
+ //Script::Enviroment_t::FRAGMENT_STORE_PARENT;
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateFragmentStore", str[ct+1]);
+ }
+
+ }
+
+
+ } else {
+ // Deal with an error.
+ }
+
}
namespace android {
@@ -432,22 +520,22 @@ void rsi_ScriptCBegin(Context * rsc)
void rsi_ScriptCSetClearColor(Context * rsc, float r, float g, float b, float a)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mClearColor[0] = r;
- ss->mClearColor[1] = g;
- ss->mClearColor[2] = b;
- ss->mClearColor[3] = a;
+ ss->mEnviroment.mClearColor[0] = r;
+ ss->mEnviroment.mClearColor[1] = g;
+ ss->mEnviroment.mClearColor[2] = b;
+ ss->mEnviroment.mClearColor[3] = a;
}
void rsi_ScriptCSetClearDepth(Context * rsc, float v)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mClearDepth = v;
+ ss->mEnviroment.mClearDepth = v;
}
void rsi_ScriptCSetClearStencil(Context * rsc, uint32_t v)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mClearStencil = v;
+ ss->mEnviroment.mClearStencil = v;
}
void rsi_ScriptCAddType(Context * rsc, RsType vt)
@@ -456,41 +544,45 @@ void rsi_ScriptCAddType(Context * rsc, RsType vt)
ss->mConstantBufferTypes.add(static_cast<const Type *>(vt));
}
-void rsi_ScriptCSetScript(Context * rsc, void* accScript, void *vp)
+void rsi_ScriptCSetScript(Context * rsc, void *vp)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mAccScript = reinterpret_cast<ACCscript*>(accScript);
- ss->mScript = reinterpret_cast<rsc_RunScript>(vp);
+ ss->mProgram.mScript = reinterpret_cast<rsc_RunScript>(vp);
}
void rsi_ScriptCSetRoot(Context * rsc, bool isRoot)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mIsRoot = isRoot;
+ ss->mEnviroment.mIsRoot = isRoot;
}
void rsi_ScriptCSetOrtho(Context * rsc, bool isOrtho)
{
ScriptCState *ss = &rsc->mScriptC;
- ss->mIsOrtho = isOrtho;
+ ss->mEnviroment.mIsOrtho = isOrtho;
}
+void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len)
+{
+ ScriptCState *ss = &rsc->mScriptC;
+ ss->mProgram.mScriptText = text;
+ ss->mProgram.mScriptTextLength = len;
+}
+
+
RsScript rsi_ScriptCCreate(Context * rsc)
{
ScriptCState *ss = &rsc->mScriptC;
+ ss->runCompiler(rsc);
+
ScriptC *s = new ScriptC();
+ s->incRef();
s->mAccScript = ss->mAccScript;
ss->mAccScript = NULL;
- s->mScript = ss->mScript;
- s->mClearColor[0] = ss->mClearColor[0];
- s->mClearColor[1] = ss->mClearColor[1];
- s->mClearColor[2] = ss->mClearColor[2];
- s->mClearColor[3] = ss->mClearColor[3];
- s->mClearDepth = ss->mClearDepth;
- s->mClearStencil = ss->mClearStencil;
- s->mIsRoot = ss->mIsRoot;
- s->mIsOrtho = ss->mIsOrtho;
+ s->mEnviroment = ss->mEnviroment;
+ s->mProgram = ss->mProgram;
+ ss->clear();
return s;
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 283007e..55a2cc6 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -36,13 +36,22 @@ public:
ScriptC();
virtual ~ScriptC();
+ struct Program_t {
+ const char * mScriptText;
+ uint32_t mScriptTextLength;
- virtual bool run(Context *, uint32_t launchID);
+ int mVersionMajor;
+ int mVersionMinor;
+
+ rsc_RunScript mScript;
+ };
+
+ Program_t mProgram;
ACCscript* mAccScript;
- rsc_RunScript mScript;
+ virtual bool run(Context *, uint32_t launchID);
struct Env {
Context *mContext;
@@ -57,17 +66,15 @@ public:
ScriptCState();
~ScriptCState();
- ACCscript* mAccScript;
- rsc_RunScript mScript;
- float mClearColor[4];
- float mClearDepth;
- uint32_t mClearStencil;
- bool mIsRoot;
- bool mIsOrtho;
+ ACCscript* mAccScript;
+
+ ScriptC::Program_t mProgram;
+ Script::Enviroment_t mEnviroment;
Vector<const Type *> mConstantBufferTypes;
void clear();
+ void runCompiler(Context *rsc);
};
diff --git a/libs/rs/rsTriangleMesh.h b/libs/rs/rsTriangleMesh.h
index 67f964f..4e15d5a 100644
--- a/libs/rs/rsTriangleMesh.h
+++ b/libs/rs/rsTriangleMesh.h
@@ -35,7 +35,7 @@ namespace renderscript {
// An element is a group of Components that occupies one cell in a structure.
-class TriangleMesh
+class TriangleMesh : public ObjectBase
{
public:
TriangleMesh();
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 120f23d..8c9f875 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -327,7 +327,7 @@ BackupDataReader::ReadAppHeader(String8* packageName, int* cookie)
}
size_t size = m_header.app.packageLen;
char* buf = packageName->lockBuffer(size);
- if (packageName == NULL) {
+ if (buf == NULL) {
packageName->unlockBuffer();
m_status = ENOMEM;
return m_status;
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 7f423a8..4c3e37d 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -41,8 +41,8 @@ namespace android {
#define MAGIC0 0x70616e53 // Snap
#define MAGIC1 0x656c6946 // File
-#if 0 // TEST_BACKUP_HELPERS
-#define LOGP(x...) printf(x)
+#if 1 // TEST_BACKUP_HELPERS
+#define LOGP(f, x...) printf(f "\n", x)
#else
#define LOGP(x...) LOGD(x)
#endif
@@ -62,6 +62,12 @@ struct FileState {
int nameLen;
};
+struct FileRec {
+ char const* file; // this object does not own this string
+ bool deleted;
+ FileState s;
+};
+
const static int ROUND_UP[4] = { 0, 3, 2, 1 };
static inline int
@@ -92,8 +98,8 @@ read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
FileState file;
char filenameBuf[128];
- amt = read(fd, &file, sizeof(file));
- if (amt != sizeof(file)) {
+ amt = read(fd, &file, sizeof(FileState));
+ if (amt != sizeof(FileState)) {
LOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
return 1;
}
@@ -128,20 +134,25 @@ read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
}
static int
-write_snapshot_file(int fd, const KeyedVector<String8,FileState>& snapshot)
+write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
{
+ int fileCount = 0;
int bytesWritten = sizeof(SnapshotHeader);
// preflight size
const int N = snapshot.size();
for (int i=0; i<N; i++) {
- const String8& name = snapshot.keyAt(i);
- bytesWritten += sizeof(FileState) + round_up(name.length());
+ const FileRec& g = snapshot.valueAt(i);
+ if (!g.deleted) {
+ const String8& name = snapshot.keyAt(i);
+ bytesWritten += sizeof(FileState) + round_up(name.length());
+ fileCount++;
+ }
}
LOGP("write_snapshot_file fd=%d\n", fd);
int amt;
- SnapshotHeader header = { MAGIC0, N, MAGIC1, bytesWritten };
+ SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
amt = write(fd, &header, sizeof(header));
if (amt != sizeof(header)) {
@@ -149,32 +160,34 @@ write_snapshot_file(int fd, const KeyedVector<String8,FileState>& snapshot)
return errno;
}
- for (int i=0; i<header.fileCount; i++) {
- const String8& name = snapshot.keyAt(i);
- FileState file = snapshot.valueAt(i);
- int nameLen = file.nameLen = name.length();
-
- amt = write(fd, &file, sizeof(file));
- if (amt != sizeof(file)) {
- LOGW("write_snapshot_file error writing header %s", strerror(errno));
- return 1;
- }
+ for (int i=0; i<N; i++) {
+ FileRec r = snapshot.valueAt(i);
+ if (!r.deleted) {
+ const String8& name = snapshot.keyAt(i);
+ int nameLen = r.s.nameLen = name.length();
+
+ amt = write(fd, &r.s, sizeof(FileState));
+ if (amt != sizeof(FileState)) {
+ LOGW("write_snapshot_file error writing header %s", strerror(errno));
+ return 1;
+ }
- // filename is not NULL terminated, but it is padded
- amt = write(fd, name.string(), nameLen);
- if (amt != nameLen) {
- LOGW("write_snapshot_file error writing filename %s", strerror(errno));
- return 1;
- }
- int paddingLen = ROUND_UP[nameLen % 4];
- if (paddingLen != 0) {
- int padding = 0xabababab;
- amt = write(fd, &padding, paddingLen);
- if (amt != paddingLen) {
- LOGW("write_snapshot_file error writing %d bytes of filename padding %s",
- paddingLen, strerror(errno));
+ // filename is not NULL terminated, but it is padded
+ amt = write(fd, name.string(), nameLen);
+ if (amt != nameLen) {
+ LOGW("write_snapshot_file error writing filename %s", strerror(errno));
return 1;
}
+ int paddingLen = ROUND_UP[nameLen % 4];
+ if (paddingLen != 0) {
+ int padding = 0xabababab;
+ amt = write(fd, &padding, paddingLen);
+ if (amt != paddingLen) {
+ LOGW("write_snapshot_file error writing %d bytes of filename padding %s",
+ paddingLen, strerror(errno));
+ return 1;
+ }
+ }
}
}
@@ -190,9 +203,9 @@ write_delete_file(BackupDataWriter* dataStream, const String8& key)
static int
write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
- const String8& realFilename)
+ char const* realFilename)
{
- LOGP("write_update_file %s (%s)\n", realFilename.string(), key.string());
+ LOGP("write_update_file %s (%s)\n", realFilename, key.string());
const int bufsize = 4*1024;
int err;
@@ -237,8 +250,7 @@ write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
}
}
LOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
- " You aren't doing proper locking!",
- realFilename.string(), fileSize, fileSize-bytesLeft);
+ " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
}
free(buf);
@@ -247,10 +259,10 @@ write_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
}
static int
-write_update_file(BackupDataWriter* dataStream, const String8& key, const String8& realFilename)
+write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
{
int err;
- int fd = open(realFilename.string(), O_RDONLY);
+ int fd = open(realFilename, O_RDONLY);
if (fd == -1) {
return errno;
}
@@ -281,12 +293,11 @@ compute_crc32(int fd)
int
back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
- char const* fileBase, char const* const* files, int fileCount)
+ char const* const* files, char const* const* keys, int fileCount)
{
int err;
- const String8 base(fileBase);
KeyedVector<String8,FileState> oldSnapshot;
- KeyedVector<String8,FileState> newSnapshot;
+ KeyedVector<String8,FileRec> newSnapshot;
if (oldSnapshotFD != -1) {
err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
@@ -297,26 +308,29 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
}
for (int i=0; i<fileCount; i++) {
- String8 name(files[i]);
- FileState s;
+ String8 key(keys[i]);
+ FileRec r;
+ char const* file = r.file = files[i];
struct stat st;
- String8 realFilename(base);
- realFilename.appendPath(name);
- err = stat(realFilename.string(), &st);
+ err = stat(file, &st);
if (err != 0) {
- LOGW("Error stating file %s", realFilename.string());
- continue;
+ LOGW("Error stating file %s", file);
+ r.deleted = true;
+ } else {
+ r.deleted = false;
+ r.s.modTime_sec = st.st_mtime;
+ r.s.modTime_nsec = 0; // workaround sim breakage
+ //r.s.modTime_nsec = st.st_mtime_nsec;
+ r.s.size = st.st_size;
+ // we compute the crc32 later down below, when we already have the file open.
+
+ if (newSnapshot.indexOfKey(key) >= 0) {
+ LOGP("back_up_files key already in use '%s'", key.string());
+ return -1;
+ }
}
-
- s.modTime_sec = st.st_mtime;
- s.modTime_nsec = 0; // workaround sim breakage
- //s.modTime_nsec = st.st_mtime_nsec;
- s.size = st.st_size;
-
- // we compute the crc32 later down below, when we already have the file open.
-
- newSnapshot.add(name, s);
+ newSnapshot.add(key, r);
}
int n = 0;
@@ -326,46 +340,42 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
while (n<N && m<fileCount) {
const String8& p = oldSnapshot.keyAt(n);
const String8& q = newSnapshot.keyAt(m);
+ FileRec& g = newSnapshot.editValueAt(m);
int cmp = p.compare(q);
- if (cmp > 0) {
- // file added
- String8 realFilename(base);
- realFilename.appendPath(q);
- LOGP("file added: %s\n", realFilename.string());
- write_update_file(dataStream, q, realFilename);
- m++;
- }
- else if (cmp < 0) {
+ if (g.deleted || cmp < 0) {
// file removed
- LOGP("file removed: %s\n", p.string());
+ LOGP("file removed: %s", p.string());
+ g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
dataStream->WriteEntityHeader(p, -1);
n++;
}
+ else if (cmp > 0) {
+ // file added
+ LOGP("file added: %s", g.file);
+ write_update_file(dataStream, q, g.file);
+ m++;
+ }
else {
-
// both files exist, check them
- String8 realFilename(base);
- realFilename.appendPath(q);
const FileState& f = oldSnapshot.valueAt(n);
- FileState& g = newSnapshot.editValueAt(m);
- int fd = open(realFilename.string(), O_RDONLY);
+ int fd = open(g.file, O_RDONLY);
if (fd < 0) {
// We can't open the file. Don't report it as a delete either. Let the
// server keep the old version. Maybe they'll be able to deal with it
// on restore.
- LOGP("Unable to open file %s - skipping", realFilename.string());
+ LOGP("Unable to open file %s - skipping", g.file);
} else {
- g.crc32 = compute_crc32(fd);
+ g.s.crc32 = compute_crc32(fd);
- LOGP("%s\n", q.string());
- LOGP(" new: modTime=%d,%d size=%-3d crc32=0x%08x\n",
+ LOGP("%s", q.string());
+ LOGP(" new: modTime=%d,%d size=%-3d crc32=0x%08x",
f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
- LOGP(" old: modTime=%d,%d size=%-3d crc32=0x%08x\n",
- g.modTime_sec, g.modTime_nsec, g.size, g.crc32);
- if (f.modTime_sec != g.modTime_sec || f.modTime_nsec != g.modTime_nsec
- || f.size != g.size || f.crc32 != g.crc32) {
- write_update_file(dataStream, fd, p, realFilename);
+ LOGP(" old: modTime=%d,%d size=%-3d crc32=0x%08x",
+ g.s.modTime_sec, g.s.modTime_nsec, g.s.size, g.s.crc32);
+ if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
+ || f.size != g.s.size || f.crc32 != g.s.crc32) {
+ write_update_file(dataStream, fd, p, g.file);
}
close(fd);
@@ -384,9 +394,8 @@ back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD
// these were added
while (m<fileCount) {
const String8& q = newSnapshot.keyAt(m);
- String8 realFilename(base);
- realFilename.appendPath(q);
- write_update_file(dataStream, q, realFilename);
+ FileRec& g = newSnapshot.editValueAt(m);
+ write_update_file(dataStream, q, g.file);
m++;
}
@@ -475,7 +484,7 @@ backup_helper_test_empty()
{
int err;
int fd;
- KeyedVector<String8,FileState> snapshot;
+ KeyedVector<String8,FileRec> snapshot;
const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
system("rm -r " SCRATCH_DIR);
@@ -534,7 +543,7 @@ backup_helper_test_four()
{
int err;
int fd;
- KeyedVector<String8,FileState> snapshot;
+ KeyedVector<String8,FileRec> snapshot;
const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
system("rm -r " SCRATCH_DIR);
@@ -549,38 +558,45 @@ backup_helper_test_four()
String8 filenames[4];
FileState states[4];
+ FileRec r;
+ r.deleted = false;
+ r.file = NULL;
states[0].modTime_sec = 0xfedcba98;
states[0].modTime_nsec = 0xdeadbeef;
states[0].size = 0xababbcbc;
states[0].crc32 = 0x12345678;
states[0].nameLen = -12;
+ r.s = states[0];
filenames[0] = String8("bytes_of_padding");
- snapshot.add(filenames[0], states[0]);
+ snapshot.add(filenames[0], r);
states[1].modTime_sec = 0x93400031;
states[1].modTime_nsec = 0xdeadbeef;
states[1].size = 0x88557766;
states[1].crc32 = 0x22334422;
states[1].nameLen = -1;
+ r.s = states[1];
filenames[1] = String8("bytes_of_padding3");
- snapshot.add(filenames[1], states[1]);
+ snapshot.add(filenames[1], r);
states[2].modTime_sec = 0x33221144;
states[2].modTime_nsec = 0xdeadbeef;
states[2].size = 0x11223344;
states[2].crc32 = 0x01122334;
states[2].nameLen = 0;
+ r.s = states[2];
filenames[2] = String8("bytes_of_padding_2");
- snapshot.add(filenames[2], states[2]);
+ snapshot.add(filenames[2], r);
states[3].modTime_sec = 0x33221144;
states[3].modTime_nsec = 0xdeadbeef;
states[3].size = 0x11223344;
states[3].crc32 = 0x01122334;
states[3].nameLen = 0;
+ r.s = states[3];
filenames[3] = String8("bytes_of_padding__1");
- snapshot.add(filenames[3], states[3]);
+ snapshot.add(filenames[3], r);
err = write_snapshot_file(fd, snapshot);
@@ -982,6 +998,14 @@ backup_helper_test_files()
write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
char const* files_before[] = {
+ SCRATCH_DIR "data/b",
+ SCRATCH_DIR "data/c",
+ SCRATCH_DIR "data/d",
+ SCRATCH_DIR "data/e",
+ SCRATCH_DIR "data/f"
+ };
+
+ char const* keys_before[] = {
"data/b",
"data/c",
"data/d",
@@ -1004,7 +1028,7 @@ backup_helper_test_files()
{
BackupDataWriter dataStream(dataStreamFD);
- err = back_up_files(-1, &dataStream, newSnapshotFD, SCRATCH_DIR, files_before, 5);
+ err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
if (err != 0) {
return err;
}
@@ -1035,6 +1059,15 @@ backup_helper_test_files()
unlink(SCRATCH_DIR "data/f");
char const* files_after[] = {
+ SCRATCH_DIR "data/a", // added
+ SCRATCH_DIR "data/b", // same
+ SCRATCH_DIR "data/c", // different mod time
+ SCRATCH_DIR "data/d", // different size (same mod time)
+ SCRATCH_DIR "data/e", // different contents (same mod time, same size)
+ SCRATCH_DIR "data/g" // added
+ };
+
+ char const* keys_after[] = {
"data/a", // added
"data/b", // same
"data/c", // different mod time
@@ -1064,8 +1097,7 @@ backup_helper_test_files()
{
BackupDataWriter dataStream(dataStreamFD);
- err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, SCRATCH_DIR,
- files_after, 6);
+ err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
if (err != 0) {
return err;
}
@@ -1078,6 +1110,109 @@ backup_helper_test_files()
return 0;
}
+int
+backup_helper_test_null_base()
+{
+ int err;
+ int oldSnapshotFD;
+ int dataStreamFD;
+ int newSnapshotFD;
+
+ system("rm -r " SCRATCH_DIR);
+ mkdir(SCRATCH_DIR, 0777);
+ mkdir(SCRATCH_DIR "data", 0777);
+
+ write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
+
+ char const* files[] = {
+ SCRATCH_DIR "data/a",
+ };
+
+ char const* keys[] = {
+ "a",
+ };
+
+ dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
+ if (dataStreamFD == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
+ newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
+ if (newSnapshotFD == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
+ {
+ BackupDataWriter dataStream(dataStreamFD);
+
+ err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ close(dataStreamFD);
+ close(newSnapshotFD);
+
+ return 0;
+}
+
+int
+backup_helper_test_missing_file()
+{
+ int err;
+ int oldSnapshotFD;
+ int dataStreamFD;
+ int newSnapshotFD;
+
+ system("rm -r " SCRATCH_DIR);
+ mkdir(SCRATCH_DIR, 0777);
+ mkdir(SCRATCH_DIR "data", 0777);
+
+ write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
+
+ char const* files[] = {
+ SCRATCH_DIR "data/a",
+ SCRATCH_DIR "data/b",
+ SCRATCH_DIR "data/c",
+ };
+
+ char const* keys[] = {
+ "a",
+ "b",
+ "c",
+ };
+
+ dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
+ if (dataStreamFD == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
+ newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
+ if (newSnapshotFD == -1) {
+ fprintf(stderr, "error creating: %s\n", strerror(errno));
+ return errno;
+ }
+
+ {
+ BackupDataWriter dataStream(dataStreamFD);
+
+ err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ close(dataStreamFD);
+ close(newSnapshotFD);
+
+ return 0;
+}
+
+
#endif // TEST_BACKUP_HELPERS
}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 725fbf9..9698553 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -410,6 +410,10 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
* Someday we might use this for network location injection to aid the GPS
*/
public void updateLocation(Location location) {
+ if (location.hasAccuracy()) {
+ native_inject_location(location.getLatitude(), location.getLongitude(),
+ location.getAccuracy());
+ }
}
/**
@@ -1210,7 +1214,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
// mask[0] is ephemeris mask and mask[1] is almanac mask
private native int native_read_sv_status(int[] svs, float[] snrs,
float[] elevations, float[] azimuths, int[] masks);
-
+ private native void native_inject_location(double latitude, double longitude, float accuracy);
+
// XTRA Support
private native void native_inject_time(long time, long timeReference, int uncertainty);
private native boolean native_supports_xtra();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 881de4d..937baad 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -163,6 +163,9 @@ public class AudioService extends IAudioService.Stub {
*/
private int mRingerMode;
+ /** @see System#MODE_RINGER_STREAMS_AFFECTED */
+ private int mRingerModeAffectedStreams;
+
/** @see System#MUTE_STREAMS_AFFECTED */
private int mMuteAffectedStreams;
@@ -286,6 +289,10 @@ public class AudioService extends IAudioService.Stub {
mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
+ mRingerModeAffectedStreams = Settings.System.getInt(cr,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ ((1 << AudioManager.STREAM_RING)|(1 << AudioManager.STREAM_NOTIFICATION)|(1 << AudioManager.STREAM_SYSTEM)));
+
mMuteAffectedStreams = System.getInt(cr,
System.MUTE_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
@@ -399,7 +406,7 @@ public class AudioService extends IAudioService.Stub {
ensureValidStreamType(streamType);
syncRingerAndNotificationStreamVolume(streamType, index, false);
- setStreamVolumeInt(streamType, index, false);
+ setStreamVolumeInt(streamType, index, false, true);
// UI, etc.
mVolumePanel.postVolumeChanged(streamType, flags);
@@ -437,7 +444,7 @@ public class AudioService extends IAudioService.Stub {
}
if (streamType == AudioManager.STREAM_RING) {
// One-off to sync notification volume to ringer volume
- setStreamVolumeInt(AudioManager.STREAM_NOTIFICATION, index, force);
+ setStreamVolumeInt(AudioManager.STREAM_NOTIFICATION, index, force, true);
}
}
}
@@ -451,10 +458,11 @@ public class AudioService extends IAudioService.Stub {
* @param index Desired volume index of the stream
* @param force If true, set the volume even if the desired volume is same
* as the current volume.
+ * @param lastAudible If true, stores new index as last audible one
*/
- private void setStreamVolumeInt(int streamType, int index, boolean force) {
+ private void setStreamVolumeInt(int streamType, int index, boolean force, boolean lastAudible) {
VolumeStreamState streamState = mStreamStates[streamType];
- if (streamState.setIndex(index) || force) {
+ if (streamState.setIndex(index, lastAudible) || force) {
// Post message to set system volume (it in turn will post a message
// to persist). Do not change volume if stream is muted.
if (streamState.muteCount() == 0) {
@@ -517,13 +525,20 @@ public class AudioService extends IAudioService.Stub {
if (!isStreamAffectedByRingerMode(streamType)) continue;
// Bring back last audible volume
setStreamVolumeInt(streamType, mStreamStates[streamType].mLastAudibleIndex,
- false);
+ false, false);
}
} else {
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- if (!isStreamAffectedByRingerMode(streamType)) continue;
- // Either silent or vibrate, either way volume is 0
- setStreamVolumeInt(streamType, 0, false);
+ if (isStreamAffectedByRingerMode(streamType)) {
+ // Either silent or vibrate, either way volume is 0
+ setStreamVolumeInt(streamType, 0, false, false);
+ } else {
+ // restore stream volume in the case the stream changed from affected
+ // to non affected by ringer mode. Does not arm to do it for streams that
+ // are not affected as well.
+ setStreamVolumeInt(streamType, mStreamStates[streamType].mLastAudibleIndex,
+ false, false);
+ }
}
}
@@ -621,7 +636,7 @@ public class AudioService extends IAudioService.Stub {
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int index = mStreamStates[streamType].mIndex;
syncRingerAndNotificationStreamVolume(streamType, index, true);
- setStreamVolumeInt(streamType, index, true);
+ setStreamVolumeInt(streamType, index, true, true);
}
}
@@ -653,7 +668,7 @@ public class AudioService extends IAudioService.Stub {
mSpeakerIsOn = true;
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
incallMask = AudioSystem.ROUTE_ALL;
- } else if (mSpeakerIsOn) {
+ } else if (routes == 0 && mSpeakerIsOn) {
mSpeakerIsOn = false;
if (mBluetoothScoIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
@@ -680,7 +695,7 @@ public class AudioService extends IAudioService.Stub {
// should not affect A2DP routing
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- } else if (mBluetoothScoIsConnected) {
+ } else if (routes == 0 && mBluetoothScoIsConnected) {
mBluetoothScoIsConnected = false;
if (mHeadsetIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
@@ -724,7 +739,7 @@ public class AudioService extends IAudioService.Stub {
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
}
- } else if (mHeadsetIsConnected) {
+ } else if (routes == 0 && mHeadsetIsConnected) {
mHeadsetIsConnected = false;
// do not act upon headset disconnection if bluetooth SCO is connected to match phone app behavior
if (!mBluetoothScoIsConnected) {
@@ -757,7 +772,7 @@ public class AudioService extends IAudioService.Stub {
// so there is no need to disable other routes.
ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
- } else if (mBluetoothA2dpIsConnected) {
+ } else if (routes == 0 && mBluetoothA2dpIsConnected) {
mBluetoothA2dpIsConnected = false;
mRoutes[AudioSystem.MODE_RINGTONE] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
mRoutes[AudioSystem.MODE_NORMAL] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
@@ -791,7 +806,7 @@ public class AudioService extends IAudioService.Stub {
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int index = mStreamStates[streamType].mIndex;
syncRingerAndNotificationStreamVolume(streamType, index, true);
- setStreamVolumeInt(streamType, index, true);
+ setStreamVolumeInt(streamType, index, true, true);
}
}
}
@@ -941,9 +956,7 @@ public class AudioService extends IAudioService.Stub {
}
public boolean isStreamAffectedByRingerMode(int streamType) {
- int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
- Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
- return (ringerModeAffectedStreams & (1 << streamType)) != 0;
+ return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
}
public boolean isStreamAffectedByMute(int streamType) {
@@ -1095,15 +1108,15 @@ public class AudioService extends IAudioService.Stub {
}
public boolean adjustIndex(int deltaIndex) {
- return setIndex(mIndex + deltaIndex);
+ return setIndex(mIndex + deltaIndex, true);
}
- public boolean setIndex(int index) {
+ public boolean setIndex(int index, boolean lastAudible) {
int oldIndex = mIndex;
mIndex = getValidIndex(index);
if (oldIndex != mIndex) {
- if (mIndex > 0) {
+ if (lastAudible) {
mLastAudibleIndex = mIndex;
}
return true;
@@ -1153,7 +1166,7 @@ public class AudioService extends IAudioService.Stub {
mDeathHandlers.add(this);
// If the stream is not yet muted by any client, set lvel to 0
if (muteCount() == 0) {
- setIndex(0);
+ setIndex(0, false);
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, mStreamType, SENDMSG_NOOP, 0, 0,
VolumeStreamState.this, 0);
}
@@ -1180,7 +1193,7 @@ public class AudioService extends IAudioService.Stub {
// If the stream is not mut any more, restore it's volume if
// ringer mode allows it
if (!isStreamAffectedByRingerMode(mStreamType) || mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
- setIndex(mLastAudibleIndex);
+ setIndex(mLastAudibleIndex, false);
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, mStreamType, SENDMSG_NOOP, 0, 0,
VolumeStreamState.this, 0);
}
@@ -1405,6 +1418,10 @@ public class AudioService extends IAudioService.Stub {
public void onChange(boolean selfChange) {
super.onChange(selfChange);
+ mRingerModeAffectedStreams = Settings.System.getInt(mContentResolver,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ 0);
+
/*
* Ensure all stream types that should be affected by ringer mode
* are in the proper state.
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index d3743e6..3b46d69 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -58,7 +58,7 @@ import java.lang.ref.WeakReference;
* MediaPlayer object driven by the supported playback control operations.
* The ovals represent the states a MediaPlayer object may reside
* in. The arcs represent the playback control operations that drive the object
- * state transition. There are two types of arcs. The arcs with a single arrow
+ * state transition. There are two types of arcs. The arcs with a single arrow
* head represent synchronous method calls, while those with
* a double arrow head represent asynchronous method calls.</p>
*
@@ -69,42 +69,42 @@ import java.lang.ref.WeakReference;
* <p>From this state diagram, one can see that a MediaPlayer object has the
* following states:</p>
* <ul>
- * <li>When a MediaPlayer object is just created using <code>new</code> or
- * after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
- * {@link #release()} is called, it is in the <em>End</em> state. Between these
- * two states is the life cycle of the MediaPlayer object.
+ * <li>When a MediaPlayer object is just created using <code>new</code> or
+ * after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
+ * {@link #release()} is called, it is in the <em>End</em> state. Between these
+ * two states is the life cycle of the MediaPlayer object.
* <ul>
- * <li>There is a subtle but important difference between a newly constructed
- * MediaPlayer object and the MediaPlayer object after {@link #reset()}
- * is called. It is a programming error to invoke methods such
- * as {@link #getCurrentPosition()},
- * {@link #getDuration()}, {@link #getVideoHeight()},
+ * <li>There is a subtle but important difference between a newly constructed
+ * MediaPlayer object and the MediaPlayer object after {@link #reset()}
+ * is called. It is a programming error to invoke methods such
+ * as {@link #getCurrentPosition()},
+ * {@link #getDuration()}, {@link #getVideoHeight()},
* {@link #getVideoWidth()}, {@link #setAudioStreamType(int)},
* {@link #setLooping(boolean)},
- * {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
- * {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or
- * {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
- * methods is called right after a MediaPlayer object is constructed,
- * the user supplied callback method OnErrorListener.onError() won't be
+ * {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
+ * {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or
+ * {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
+ * methods is called right after a MediaPlayer object is constructed,
+ * the user supplied callback method OnErrorListener.onError() won't be
* called by the internal player engine and the object state remains
- * unchanged; but if these methods are called right after {@link #reset()},
+ * unchanged; but if these methods are called right after {@link #reset()},
* the user supplied callback method OnErrorListener.onError() will be
- * invoked by the internal player engine and the object will be
+ * invoked by the internal player engine and the object will be
* transfered to the <em>Error</em> state. </li>
- * <li>It is also recommended that once
- * a MediaPlayer object is no longer being used, call {@link #release()} immediately
- * so that resources used by the internal player engine associated with the
+ * <li>It is also recommended that once
+ * a MediaPlayer object is no longer being used, call {@link #release()} immediately
+ * so that resources used by the internal player engine associated with the
* MediaPlayer object can be released immediately. Resource may include
- * singleton resources such as hardware acceleration components and
+ * singleton resources such as hardware acceleration components and
* failure to call {@link #release()} may cause subsequent instances of
* MediaPlayer objects to fallback to software implementations or fail
* altogether. Once the MediaPlayer
- * object is in the <em>End</em> state, it can no longer be used and
+ * object is in the <em>End</em> state, it can no longer be used and
* there is no way to bring it back to any other state. </li>
- * <li>Furthermore,
- * the MediaPlayer objects created using <code>new</code> is in the
- * <em>Idle</em> state, while those created with one
- * of the overloaded convenient <code>create</code> methods are <em>NOT</em>
+ * <li>Furthermore,
+ * the MediaPlayer objects created using <code>new</code> is in the
+ * <em>Idle</em> state, while those created with one
+ * of the overloaded convenient <code>create</code> methods are <em>NOT</em>
* in the <em>Idle</em> state. In fact, the objects are in the <em>Prepared</em>
* state if the creation using <code>create</code> method is successful.
* </li>
@@ -114,23 +114,23 @@ import java.lang.ref.WeakReference;
* reasons, such as unsupported audio/video format, poorly interleaved
* audio/video, resolution too high, streaming timeout, and the like.
* Thus, error reporting and recovery is an important concern under
- * these circumstances. Sometimes, due to programming errors, invoking a playback
+ * these circumstances. Sometimes, due to programming errors, invoking a playback
* control operation in an invalid state may also occur. Under all these
* error conditions, the internal player engine invokes a user supplied
* OnErrorListener.onError() method if an OnErrorListener has been
* registered beforehand via
* {@link #setOnErrorListener(android.media.MediaPlayer.OnErrorListener)}.
* <ul>
- * <li>It is important to note that once an error occurs, the
- * MediaPlayer object enters the <em>Error</em> state (except as noted
+ * <li>It is important to note that once an error occurs, the
+ * MediaPlayer object enters the <em>Error</em> state (except as noted
* above), even if an error listener has not been registered by the application.</li>
* <li>In order to reuse a MediaPlayer object that is in the <em>
- * Error</em> state and recover from the error,
+ * Error</em> state and recover from the error,
* {@link #reset()} can be called to restore the object to its <em>Idle</em>
* state.</li>
- * <li>It is good programming practice to have your application
- * register a OnErrorListener to look out for error notifications from
- * the internal player engine.</li>
+ * <li>It is good programming practice to have your application
+ * register a OnErrorListener to look out for error notifications from
+ * the internal player engine.</li>
* <li>IlleglStateException is
* thrown to prevent programming errors such as calling {@link #prepare()},
* {@link #prepareAsync()}, or one of the overloaded <code>setDataSource
@@ -141,28 +141,28 @@ import java.lang.ref.WeakReference;
* {@link #setDataSource(FileDescriptor)}, or
* {@link #setDataSource(String)}, or
* {@link #setDataSource(Context, Uri)}, or
- * {@link #setDataSource(FileDescriptor, long, long)} transfers a
+ * {@link #setDataSource(FileDescriptor, long, long)} transfers a
* MediaPlayer object in the <em>Idle</em> state to the
* <em>Initialized</em> state.
* <ul>
- * <li>An IllegalStateException is thrown if
+ * <li>An IllegalStateException is thrown if
* setDataSource() is called in any other state.</li>
- * <li>It is good programming
- * practice to always look out for <code>IllegalArgumentException</code>
+ * <li>It is good programming
+ * practice to always look out for <code>IllegalArgumentException</code>
* and <code>IOException</code> that may be thrown from the overloaded
* <code>setDataSource</code> methods.</li>
* </ul>
* </li>
* <li>A MediaPlayer object must first enter the <em>Prepared</em> state
- * before playback can be started.
+ * before playback can be started.
* <ul>
* <li>There are two ways (synchronous vs.
* asynchronous) that the <em>Prepared</em> state can be reached:
* either a call to {@link #prepare()} (synchronous) which
* transfers the object to the <em>Prepared</em> state once the method call
* returns, or a call to {@link #prepareAsync()} (asynchronous) which
- * first transfers the object to the <em>Preparing</em> state after the
- * call returns (which occurs almost right way) while the internal
+ * first transfers the object to the <em>Preparing</em> state after the
+ * call returns (which occurs almost right way) while the internal
* player engine continues working on the rest of preparation work
* until the preparation work completes. When the preparation completes or when {@link #prepare()} call returns,
* the internal player engine then calls a user supplied callback method,
@@ -173,22 +173,22 @@ import java.lang.ref.WeakReference;
* the <em>Preparing</em> state is a transient state, and the behavior
* of calling any method with side effect while a MediaPlayer object is
* in the <em>Preparing</em> state is undefined.</li>
- * <li>An IllegalStateException is
- * thrown if {@link #prepare()} or {@link #prepareAsync()} is called in
- * any other state.</li>
- * <li>While in the <em>Prepared</em> state, properties
- * such as audio/sound volume, screenOnWhilePlaying, looping can be
+ * <li>An IllegalStateException is
+ * thrown if {@link #prepare()} or {@link #prepareAsync()} is called in
+ * any other state.</li>
+ * <li>While in the <em>Prepared</em> state, properties
+ * such as audio/sound volume, screenOnWhilePlaying, looping can be
* adjusted by invoking the corresponding set methods.</li>
* </ul>
* </li>
- * <li>To start the playback, {@link #start()} must be called. After
+ * <li>To start the playback, {@link #start()} must be called. After
* {@link #start()} returns successfully, the MediaPlayer object is in the
- * <em>Started</em> state. {@link #isPlaying()} can be called to test
+ * <em>Started</em> state. {@link #isPlaying()} can be called to test
* whether the MediaPlayer object is in the <em>Started</em> state.
* <ul>
* <li>While in the <em>Started</em> state, the internal player engine calls
* a user supplied OnBufferingUpdateListener.onBufferingUpdate() callback
- * method if a OnBufferingUpdateListener has been registered beforehand
+ * method if a OnBufferingUpdateListener has been registered beforehand
* via {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}.
* This callback allows applications to keep track of the buffering status
* while streaming audio/video.</li>
@@ -197,44 +197,44 @@ import java.lang.ref.WeakReference;
* </ul>
* </li>
* <li>Playback can be paused and stopped, and the current playback position
- * can be adjusted. Playback can be paused via {@link #pause()}. When the call to
+ * can be adjusted. Playback can be paused via {@link #pause()}. When the call to
* {@link #pause()} returns, the MediaPlayer object enters the
- * <em>Paused</em> state. Note that the transition from the <em>Started</em>
- * state to the <em>Paused</em> state and vice versa happens
- * asynchronously in the player engine. It may take some time before
- * the state is updated in calls to {@link #isPlaying()}, and it can be
+ * <em>Paused</em> state. Note that the transition from the <em>Started</em>
+ * state to the <em>Paused</em> state and vice versa happens
+ * asynchronously in the player engine. It may take some time before
+ * the state is updated in calls to {@link #isPlaying()}, and it can be
* a number of seconds in the case of streamed content.
* <ul>
- * <li>Calling {@link #start()} to resume playback for a paused
+ * <li>Calling {@link #start()} to resume playback for a paused
* MediaPlayer object, and the resumed playback
- * position is the same as where it was paused. When the call to
+ * position is the same as where it was paused. When the call to
* {@link #start()} returns, the paused MediaPlayer object goes back to
* the <em>Started</em> state.</li>
* <li>Calling {@link #pause()} has no effect on
* a MediaPlayer object that is already in the <em>Paused</em> state.</li>
* </ul>
* </li>
- * <li>Calling {@link #stop()} stops playback and causes a
+ * <li>Calling {@link #stop()} stops playback and causes a
* MediaPlayer in the <em>Started</em>, <em>Paused</em>, <em>Prepared
- * </em> or <em>PlaybackCompleted</em> state to enter the
+ * </em> or <em>PlaybackCompleted</em> state to enter the
* <em>Stopped</em> state.
* <ul>
- * <li>Once in the <em>Stopped</em> state, playback cannot be started
+ * <li>Once in the <em>Stopped</em> state, playback cannot be started
* until {@link #prepare()} or {@link #prepareAsync()} are called to set
* the MediaPlayer object to the <em>Prepared</em> state again.</li>
- * <li>Calling {@link #stop()} has no effect on a MediaPlayer
+ * <li>Calling {@link #stop()} has no effect on a MediaPlayer
* object that is already in the <em>Stopped</em> state.</li>
* </ul>
* </li>
- * <li>The playback position can be adjusted with a call to
- * {@link #seekTo(int)}.
+ * <li>The playback position can be adjusted with a call to
+ * {@link #seekTo(int)}.
* <ul>
* <li>Although the asynchronuous {@link #seekTo(int)}
* call returns right way, the actual seek operation may take a while to
- * finish, especially for audio/video being streamed. When the actual
- * seek operation completes, the internal player engine calls a user
+ * finish, especially for audio/video being streamed. When the actual
+ * seek operation completes, the internal player engine calls a user
* supplied OnSeekComplete.onSeekComplete() if an OnSeekCompleteListener
- * has been registered beforehand via
+ * has been registered beforehand via
* {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
* <li>Please
* note that {@link #seekTo(int)} can also be called in the other states,
@@ -242,7 +242,7 @@ import java.lang.ref.WeakReference;
* </em> state.</li>
* <li>Furthermore, the actual current playback position
* can be retrieved with a call to {@link #getCurrentPosition()}, which
- * is helpful for applications such as a Music player that need to keep
+ * is helpful for applications such as a Music player that need to keep
* track of the playback progress.</li>
* </ul>
* </li>
@@ -272,7 +272,7 @@ import java.lang.ref.WeakReference;
* <td>Invalid States </p></td>
* <td>Comments </p></td></tr>
* <tr><td>getCurrentPosition </p></td>
- * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
* PlaybackCompleted} </p></td>
* <td>{Error}</p></td>
* <td>Successful invoke of this method in a valid state does not change the
@@ -282,45 +282,45 @@ import java.lang.ref.WeakReference;
* <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
* <td>{Idle, Initialized, Error} </p></td>
* <td>Successful invoke of this method in a valid state does not change the
- * state. Calling this method in an invalid state transfers the object
+ * state. Calling this method in an invalid state transfers the object
* to the <em>Error</em> state. </p></td></tr>
* <tr><td>getVideoHeight </p></td>
- * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
* <td>Successful invoke of this method in a valid state does not change the
- * state. Calling this method in an invalid state transfers the object
+ * state. Calling this method in an invalid state transfers the object
* to the <em>Error</em> state. </p></td></tr>
* <tr><td>getVideoWidth </p></td>
* <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
- * <td>Successful invoke of this method in a valid state does not change
- * the state. Calling this method in an invalid state transfers the
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an invalid state transfers the
* object to the <em>Error</em> state. </p></td></tr>
* <tr><td>isPlaying </p></td>
- * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
* <td>Successful invoke of this method in a valid state does not change
- * the state. Calling this method in an invalid state transfers the
+ * the state. Calling this method in an invalid state transfers the
* object to the <em>Error</em> state. </p></td></tr>
* <tr><td>pause </p></td>
* <td>{Started, Paused}</p></td>
* <td>{Idle, Initialized, Prepared, Stopped, PlaybackCompleted, Error}</p></td>
- * <td>Successful invoke of this method in a valid state transfers the
- * object to the <em>Paused</em> state. Calling this method in an
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Paused</em> state. Calling this method in an
* invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
* <tr><td>prepare </p></td>
* <td>{Initialized, Stopped} </p></td>
* <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- * <td>Successful invoke of this method in a valid state transfers the
- * object to the <em>Prepared</em> state. Calling this method in an
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Prepared</em> state. Calling this method in an
* invalid state throws an IllegalStateException.</p></td></tr>
* <tr><td>prepareAsync </p></td>
* <td>{Initialized, Stopped} </p></td>
* <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- * <td>Successful invoke of this method in a valid state transfers the
+ * <td>Successful invoke of this method in a valid state transfers the
* object to the <em>Preparing</em> state. Calling this method in an
* invalid state throws an IllegalStateException.</p></td></tr>
* <tr><td>release </p></td>
@@ -328,18 +328,18 @@ import java.lang.ref.WeakReference;
* <td>{} </p></td>
* <td>After {@link #release()}, the object is no longer available. </p></td></tr>
* <tr><td>reset </p></td>
- * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ * <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
* PlaybackCompleted, Error}</p></td>
* <td>{}</p></td>
* <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
* <tr><td>seekTo </p></td>
* <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
* <td>{Idle, Initialized, Stopped, Error}</p></td>
- * <td>Successful invoke of this method in a valid state does not change
- * the state. Calling this method in an invalid state transfers the
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an invalid state transfers the
* object to the <em>Error</em> state. </p></td></tr>
* <tr><td>setAudioStreamType </p></td>
- * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
* <td>Successful invoke of this method does not change the state.</p></td></tr>
@@ -347,8 +347,8 @@ import java.lang.ref.WeakReference;
* <td>{Idle} </p></td>
* <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
* Error} </p></td>
- * <td>Successful invoke of this method in a valid state transfers the
- * object to the <em>Initialized</em> state. Calling this method in an
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Initialized</em> state. Calling this method in an
* invalid state throws an IllegalStateException.</p></td></tr>
* <tr><td>setDisplay </p></td>
* <td>any </p></td>
@@ -356,11 +356,11 @@ import java.lang.ref.WeakReference;
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setLooping </p></td>
- * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
- * <td>Successful invoke of this method in a valid state does not change
- * the state. Calling this method in an
+ * <td>Successful invoke of this method in a valid state does not change
+ * the state. Calling this method in an
* invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
* <tr><td>isLooping </p></td>
* <td>any </p></td>
@@ -398,7 +398,7 @@ import java.lang.ref.WeakReference;
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setVolume </p></td>
- * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ * <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
* <td>Successful invoke of this method does not change the state.
@@ -410,14 +410,14 @@ import java.lang.ref.WeakReference;
* <tr><td>start </p></td>
* <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
* <td>{Idle, Initialized, Stopped, Error}</p></td>
- * <td>Successful invoke of this method in a valid state transfers the
- * object to the <em>Started</em> state. Calling this method in an
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Started</em> state. Calling this method in an
* invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
* <tr><td>stop </p></td>
* <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
* <td>{Idle, Initialized, Error}</p></td>
- * <td>Successful invoke of this method in a valid state transfers the
- * object to the <em>Stopped</em> state. Calling this method in an
+ * <td>Successful invoke of this method in a valid state transfers the
+ * object to the <em>Stopped</em> state. Calling this method in an
* invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
* </table>
*
@@ -429,13 +429,13 @@ import java.lang.ref.WeakReference;
*
*/
public class MediaPlayer
-{
+{
static {
System.loadLibrary("media_jni");
}
-
+
private final static String TAG = "MediaPlayer";
-
+
private int mNativeContext; // accessed by native methods
private int mListenerContext; // accessed by native methods
private Surface mSurface; // accessed by native methods
@@ -444,16 +444,16 @@ public class MediaPlayer
private PowerManager.WakeLock mWakeLock = null;
private boolean mScreenOnWhilePlaying;
private boolean mStayAwake;
-
+
/**
- * Default constructor. Consider using one of the create() methods for
+ * Default constructor. Consider using one of the create() methods for
* synchronously instantiating a MediaPlayer from a Uri or resource.
* <p>When done with the MediaPlayer, you should call {@link #release()},
* to free the resources. If not released, too many MediaPlayer instances may
* result in an exception.</p>
*/
public MediaPlayer() {
-
+
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
@@ -473,12 +473,12 @@ public class MediaPlayer
* Update the MediaPlayer ISurface. Call after updating mSurface.
*/
private native void _setVideoSurface();
-
+
/**
* Sets the SurfaceHolder to use for displaying the video portion of the media.
* This call is optional. Not calling it when playing back a video will
* result in only the audio track being played.
- *
+ *
* @param sh the SurfaceHolder to use for video display
*/
public void setDisplay(SurfaceHolder sh) {
@@ -498,29 +498,29 @@ public class MediaPlayer
* <p>When done with the MediaPlayer, you should call {@link #release()},
* to free the resources. If not released, too many MediaPlayer instances will
* result in an exception.</p>
- *
- * @param context the Context to use
+ *
+ * @param context the Context to use
* @param uri the Uri from which to get the datasource
* @return a MediaPlayer object, or null if creation failed
*/
public static MediaPlayer create(Context context, Uri uri) {
return create (context, uri, null);
}
-
+
/**
* Convenience method to create a MediaPlayer for a given Uri.
* On success, {@link #prepare()} will already have been called and must not be called again.
* <p>When done with the MediaPlayer, you should call {@link #release()},
* to free the resources. If not released, too many MediaPlayer instances will
* result in an exception.</p>
- *
- * @param context the Context to use
+ *
+ * @param context the Context to use
* @param uri the Uri from which to get the datasource
* @param holder the SurfaceHolder to use for displaying the video
* @return a MediaPlayer object, or null if creation failed
*/
public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder) {
-
+
try {
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(context, uri);
@@ -549,9 +549,9 @@ public class MediaPlayer
* <p>When done with the MediaPlayer, you should call {@link #release()},
* to free the resources. If not released, too many MediaPlayer instances will
* result in an exception.</p>
- *
- * @param context the Context to use
- * @param resid the raw resource id (<var>R.raw.&lt;something></var>) for
+ *
+ * @param context the Context to use
+ * @param resid the raw resource id (<var>R.raw.&lt;something></var>) for
* the resource to use as the datasource
* @return a MediaPlayer object, or null if creation failed
*/
@@ -577,17 +577,17 @@ public class MediaPlayer
}
return null;
}
-
+
/**
* Sets the data source as a content Uri.
- *
+ *
* @param context the Context to use when resolving the Uri
* @param uri the Content URI of the data you want to play
* @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(Context context, Uri uri)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
-
+
String scheme = uri.getScheme();
if(scheme == null || scheme.equals("file")) {
setDataSource(uri.getPath());
@@ -617,13 +617,14 @@ public class MediaPlayer
fd.close();
}
}
+ Log.d(TAG, "Couldn't open file on client side, trying server side");
setDataSource(uri.toString());
return;
}
/**
* Sets the data source (file-path or http/rtsp URL) to use.
- *
+ *
* @param path the path of the file, or the http/rtsp URL of the stream you want to play
* @throws IllegalStateException if it is called in an invalid state
*/
@@ -632,57 +633,57 @@ public class MediaPlayer
/**
* Sets the data source (FileDescriptor) to use. It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
- *
+ *
* @param fd the FileDescriptor for the file you want to play
* @throws IllegalStateException if it is called in an invalid state
*/
- public void setDataSource(FileDescriptor fd)
+ public void setDataSource(FileDescriptor fd)
throws IOException, IllegalArgumentException, IllegalStateException {
// intentionally less than LONG_MAX
setDataSource(fd, 0, 0x7ffffffffffffffL);
}
-
+
/**
* Sets the data source (FileDescriptor) to use. It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
- *
+ *
* @param fd the FileDescriptor for the file you want to play
* @param offset the offset into the file where the data to be played starts, in bytes
* @param length the length in bytes of the data to be played
* @throws IllegalStateException if it is called in an invalid state
*/
- public native void setDataSource(FileDescriptor fd, long offset, long length)
+ public native void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException;
/**
* Prepares the player for playback, synchronously.
- *
+ *
* After setting the datasource and the display surface, you need to either
* call prepare() or prepareAsync(). For files, it is OK to call prepare(),
* which blocks until MediaPlayer is ready for playback.
- *
+ *
* @throws IllegalStateException if it is called in an invalid state
*/
public native void prepare() throws IOException, IllegalStateException;
-
+
/**
* Prepares the player for playback, asynchronously.
- *
+ *
* After setting the datasource and the display surface, you need to either
* call prepare() or prepareAsync(). For streams, you should call prepareAsync(),
* which returns immediately, rather than blocking until enough data has been
* buffered.
- *
+ *
* @throws IllegalStateException if it is called in an invalid state
*/
public native void prepareAsync() throws IllegalStateException;
-
+
/**
* Starts or resumes playback. If playback had previously been paused,
* playback will continue from where it was paused. If playback had
* been stopped, or never started before, playback will start at the
* beginning.
- *
+ *
* @throws IllegalStateException if it is called in an invalid state
*/
public void start() throws IllegalStateException {
@@ -691,10 +692,10 @@ public class MediaPlayer
}
private native void _start() throws IllegalStateException;
-
+
/**
- * Stops playback after playback has been stopped or paused.
- *
+ * Stops playback after playback has been stopped or paused.
+ *
* @throws IllegalStateException if the internal player engine has not been
* initialized.
*/
@@ -704,10 +705,10 @@ public class MediaPlayer
}
private native void _stop() throws IllegalStateException;
-
+
/**
* Pauses playback. Call start() to resume.
- *
+ *
* @throws IllegalStateException if the internal player engine has not been
* initialized.
*/
@@ -717,20 +718,20 @@ public class MediaPlayer
}
private native void _pause() throws IllegalStateException;
-
+
/**
* Set the low-level power management behavior for this MediaPlayer. This
* can be used when the MediaPlayer is not playing through a SurfaceHolder
* set with {@link #setDisplay(SurfaceHolder)} and thus can use the
* high-level {@link #setScreenOnWhilePlaying(boolean)} feature.
- *
+ *
* <p>This function has the MediaPlayer access the low-level power manager
* service to control the device's power usage while playing is occurring.
* The parameter is a combination of {@link android.os.PowerManager} wake flags.
* Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
* permission.
* By default, no attempt is made to keep the device awake during playback.
- *
+ *
* @param context the Context to use
* @param mode the power/wake mode to set
* @see android.os.PowerManager
@@ -752,14 +753,14 @@ public class MediaPlayer
mWakeLock.acquire();
}
}
-
+
/**
* Control whether we should use the attached SurfaceHolder to keep the
* screen on while video playback is occurring. This is the preferred
* method over {@link #setWakeMode} where possible, since it doesn't
* require that the application have permission for low-level wake lock
* access.
- *
+ *
* @param screenOn Supply true to keep the screen on, false to allow it
* to turn off.
*/
@@ -769,7 +770,7 @@ public class MediaPlayer
updateSurfaceScreenOn();
}
}
-
+
private void stayAwake(boolean awake) {
if (mWakeLock != null) {
if (awake && !mWakeLock.isHeld()) {
@@ -781,61 +782,61 @@ public class MediaPlayer
mStayAwake = awake;
updateSurfaceScreenOn();
}
-
+
private void updateSurfaceScreenOn() {
if (mSurfaceHolder != null) {
mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
}
}
-
+
/**
* Returns the width of the video.
- *
+ *
* @return the width of the video, or 0 if there is no video,
* no display surface was set, or prepare()/prepareAsync()
* have not completed yet
*/
public native int getVideoWidth();
-
+
/**
* Returns the height of the video.
- *
+ *
* @return the height of the video, or 0 if there is no video,
* no display surface was set, or prepare()/prepareAsync()
* have not completed yet
*/
public native int getVideoHeight();
-
+
/**
* Checks whether the MediaPlayer is playing.
- *
+ *
* @return true if currently playing, false otherwise
*/
public native boolean isPlaying();
-
+
/**
* Seeks to specified time position.
- *
+ *
* @param msec the offset in milliseconds from the start to seek to
* @throws IllegalStateException if the internal player engine has not been
* initialized
*/
public native void seekTo(int msec) throws IllegalStateException;
-
+
/**
* Gets the current playback position.
- *
+ *
* @return the current position in milliseconds
*/
public native int getCurrentPosition();
-
+
/**
* Gets the duration of the file.
- *
+ *
* @return the duration in milliseconds
*/
public native int getDuration();
-
+
/**
* Releases resources associated with this MediaPlayer object.
* It is considered good practice to call this method when you're
@@ -855,7 +856,7 @@ public class MediaPlayer
}
private native void _release();
-
+
/**
* Resets the MediaPlayer to its uninitialized state. After calling
* this method, you will have to initialize it again by setting the
@@ -867,13 +868,13 @@ public class MediaPlayer
// make sure none of the listeners get called anymore
mEventHandler.removeCallbacksAndMessages(null);
}
-
+
private native void _reset();
-
+
/**
* Sets the audio stream type for this MediaPlayer. See {@link AudioManager}
* for a list of stream types.
- *
+ *
* @param streamtype the audio stream type
* @see android.media.AudioManager
*/
@@ -881,20 +882,20 @@ public class MediaPlayer
/**
* Sets the player to be looping or non-looping.
- *
+ *
* @param looping whether to loop or not
*/
public native void setLooping(boolean looping);
/**
* Checks whether the MediaPlayer is looping or non-looping.
- *
+ *
* @return true if the MediaPlayer is currently looping, false otherwise
*/
public native boolean isLooping();
/**
- * Sets the volume on this player.
+ * Sets the volume on this player.
* This API is recommended for balancing the output of audio streams
* within an application. Unless you are writing an application to
* control user settings, this API should be used in preference to
@@ -913,7 +914,7 @@ public class MediaPlayer
* @hide
*/
public native Bitmap getFrameAt(int msec) throws IllegalStateException;
-
+
private native final void native_setup(Object mediaplayer_this);
private native final void native_finalize();
@Override
@@ -1036,7 +1037,7 @@ public class MediaPlayer
{
/**
* Called when the media file is ready for playback.
- *
+ *
* @param mp the MediaPlayer that is ready for playback
*/
void onPrepared(MediaPlayer mp);
@@ -1063,7 +1064,7 @@ public class MediaPlayer
{
/**
* Called when the end of a media source is reached during playback.
- *
+ *
* @param mp the MediaPlayer that reached the end of the file
*/
void onCompletion(MediaPlayer mp);
@@ -1090,14 +1091,14 @@ public class MediaPlayer
{
/**
* Called to update status in buffering a media stream.
- *
+ *
* @param mp the MediaPlayer the update pertains to
* @param percent the percentage (0-100) of the buffer
* that has been filled thus far
*/
void onBufferingUpdate(MediaPlayer mp, int percent);
}
-
+
/**
* Register a callback to be invoked when the status of a network
* stream's buffer has changed.
@@ -1110,7 +1111,7 @@ public class MediaPlayer
}
private OnBufferingUpdateListener mOnBufferingUpdateListener;
-
+
/**
* Interface definition of a callback to be invoked indicating
* the completion of a seek operation.
@@ -1119,23 +1120,23 @@ public class MediaPlayer
{
/**
* Called to indicate the completion of a seek operation.
- *
+ *
* @param mp the MediaPlayer that issued the seek operation
*/
public void onSeekComplete(MediaPlayer mp);
}
-
+
/**
* Register a callback to be invoked when a seek operation has been
* completed.
- *
+ *
* @param listener the callback that will be run
*/
public void setOnSeekCompleteListener(OnSeekCompleteListener listener)
{
mOnSeekCompleteListener = listener;
}
-
+
private OnSeekCompleteListener mOnSeekCompleteListener;
/**
@@ -1146,25 +1147,25 @@ public class MediaPlayer
{
/**
* Called to indicate the video size
- *
+ *
* @param mp the MediaPlayer associated with this callback
* @param width the width of the video
* @param height the height of the video
*/
public void onVideoSizeChanged(MediaPlayer mp, int width, int height);
}
-
+
/**
* Register a callback to be invoked when the video size is
* known or updated.
- *
+ *
* @param listener the callback that will be run
*/
public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener)
{
mOnVideoSizeChangedListener = listener;
}
-
+
private OnVideoSizeChangedListener mOnVideoSizeChangedListener;
/* Do not change these values without updating their counterparts
@@ -1176,11 +1177,11 @@ public class MediaPlayer
public static final int MEDIA_ERROR_UNKNOWN = 1;
/** Media server died. In this case, the application must release the
- * MediaPlayer object and instantiate a new one.
+ * MediaPlayer object and instantiate a new one.
* @see android.media.MediaPlayer.OnErrorListener
*/
public static final int MEDIA_ERROR_SERVER_DIED = 100;
-
+
/** The video is streamed and its container is not valid for progressive
* playback i.e the video's index (e.g moov atom) is not at the start of the
* file.
@@ -1197,7 +1198,7 @@ public class MediaPlayer
{
/**
* Called to indicate an error.
- *
+ *
* @param mp the MediaPlayer the error pertains to
* @param what the type of error that has occurred:
* <ul>
@@ -1212,11 +1213,11 @@ public class MediaPlayer
*/
boolean onError(MediaPlayer mp, int what, int extra);
}
-
+
/**
* Register a callback to be invoked when an error has happened
* during an asynchronous operation.
- *
+ *
* @param listener the callback that will be run
*/
public void setOnErrorListener(OnErrorListener listener)
@@ -1261,7 +1262,7 @@ public class MediaPlayer
{
/**
* Called to indicate an info or a warning.
- *
+ *
* @param mp the MediaPlayer the info pertains to.
* @param what the type of info or warning.
* <ul>
@@ -1281,7 +1282,7 @@ public class MediaPlayer
/**
* Register a callback to be invoked when an info/warning is available.
- *
+ *
* @param listener the callback that will be run
*/
public void setOnInfoListener(OnInfoListener listener)
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 44f21c8..be4b489 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -164,8 +164,19 @@ public class MediaRecorder
public static final int THREE_GPP = 1;
/** MPEG4 media file format*/
public static final int MPEG_4 = 2;
- /** Raw AMR file format */
+
+ /** The following formats are audio only .aac or .amr formats **/
+ /** @deprecated Deprecated in favor of AMR_NB */
+ /** @todo change link when AMR_NB is exposed. Deprecated in favor of {@link MediaRecorder.OutputFormat#AMR_NB} */
public static final int RAW_AMR = 3;
+ /** @hide AMR NB file format */
+ public static final int AMR_NB = 3;
+ /** @hide AMR WB file format */
+ public static final int AMR_WB = 4;
+ /** @hide AAC ADIF file format */
+ public static final int AAC_ADIF = 5;
+ /** @hide AAC ADTS file format */
+ public static final int AAC_ADTS = 6;
};
/**
@@ -180,7 +191,14 @@ public class MediaRecorder
public static final int DEFAULT = 0;
/** AMR (Narrowband) audio codec */
public static final int AMR_NB = 1;
- //public static final AAC = 2; currently unsupported
+ /** @hide AMR (Wideband) audio codec */
+ public static final int AMR_WB = 2;
+ /** @hide AAC audio codec */
+ public static final int AAC = 3;
+ /** @hide enhanced AAC audio codec */
+ public static final int AAC_PLUS = 4;
+ /** @hide enhanced AAC plus audio codec */
+ public static final int EAAC_PLUS = 5;
}
/**
@@ -198,6 +216,46 @@ public class MediaRecorder
public static final int MPEG_4_SP = 3;
}
+
+ /**
+ * @hide Defines the audio sampling rate. This must be set before
+ * setAudioEncoder() or it will be ignored.
+ * This parameter is used with
+ * {@link MediaRecorder#setParameters(String)}.
+ */
+ public final class AudioParamSamplingRate {
+ /* Do not change these values without updating their counterparts
+ * in include/media/mediarecorder.h!
+ */
+ private AudioParamSamplingRate() {}
+ public static final String AUDIO_PARAM_SAMPLING_RATE_KEY = "audio-param-sampling-rate=";
+ }
+
+ /**
+ * @hide Defines the audio number of channels. This must be set before
+ * setAudioEncoder() or it will be ignored.
+ * This parameter is used with
+ * {@link MediaRecorder#setParameters(String)}.
+ */
+ public final class AudioParamChannels {
+ /* Do not change these values without updating their counterparts
+ * in include/media/mediarecorder.h!
+ */
+ private AudioParamChannels() {}
+ public static final String AUDIO_PARAM_NUMBER_OF_CHANNELS = "audio-param-number-of-channels=";
+ }
+
+ /**
+ * @hide Defines the audio encoding bitrate. This must be set before
+ * setAudioEncoder() or it will be ignored.
+ * This parameter is used with
+ * {@link MediaRecorder#setParameters(String)}.
+ */
+ public final class AudioParamEncodingBitrate{
+ private AudioParamEncodingBitrate() {}
+ public static final String AUDIO_PARAM_ENCODING_BITRATE = "audio-param-encoding-bitrate=";
+ }
+
/**
* Sets the audio source to be used for recording. If this method is not
* called, the output file will not contain an audio track. The source needs
@@ -332,6 +390,16 @@ public class MediaRecorder
throws IllegalStateException;
/**
+ * @hide Sets a parameter in the author engine.
+ *
+ * @param params the parameter to set.
+ * @see android.media.MediaRecorder.AudioParamSamplingRate
+ * @see android.media.MediaRecorder.AudioParamChannels
+ * @see android.media.MediaRecorder.AudioParamEncodingBitrate
+ */
+ public native void setParameters(String params);
+
+ /**
* Pass in the file descriptor of the file to be written. Call this after
* setOutputFormat() but before prepare().
*
@@ -448,7 +516,7 @@ public class MediaRecorder
{
/**
* Called when an error occurs while recording.
- *
+ *
* @param mr the MediaRecorder that encountered the error
* @param what the type of error that has occurred:
* <ul>
@@ -494,7 +562,7 @@ public class MediaRecorder
{
/**
* Called when an error occurs while recording.
- *
+ *
* @param mr the MediaRecorder that encountered the error
* @param what the type of error that has occurred:
* <ul>
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 5abe451..6317fe2 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -125,8 +125,8 @@ static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaP
return old;
}
-// If exception is NULL and opStatus is not OK, this method sends an error
-// event to the client application; otherwise, if exception is not NULL and
+// If exception is NULL and opStatus is not OK, this method sends an error
+// event to the client application; otherwise, if exception is not NULL and
// opStatus is not OK, this method throws the given exception to the client
// application.
static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
@@ -203,7 +203,7 @@ static void setVideoSurface(const sp<MediaPlayer>& mp, JNIEnv *env, jobject thiz
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL) {
const sp<Surface>& native_surface = get_surface(env, surface);
- LOGV("prepare: surface=%p (id=%d)",
+ LOGV("prepare: surface=%p (id=%d)",
native_surface.get(), native_surface->ID());
mp->setVideoSurface(native_surface);
}
@@ -243,7 +243,7 @@ android_media_MediaPlayer_prepareAsync(JNIEnv *env, jobject thiz)
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL) {
const sp<Surface>& native_surface = get_surface(env, surface);
- LOGV("prepareAsync: surface=%p (id=%d)",
+ LOGV("prepareAsync: surface=%p (id=%d)",
native_surface.get(), native_surface->ID());
mp->setVideoSurface(native_surface);
}
@@ -271,7 +271,7 @@ android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
- process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
+ process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
}
static void
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 7561af1..7bfeb83 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -165,7 +165,7 @@ static void
android_media_MediaRecorder_setVideoSource(JNIEnv *env, jobject thiz, jint vs)
{
LOGV("setVideoSource(%d)", vs);
- if (vs < VIDEO_SOURCE_DEFAULT || vs > VIDEO_SOURCE_CAMERA) {
+ if (vs < VIDEO_SOURCE_DEFAULT || vs >= VIDEO_SOURCE_LIST_END) {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video source");
return;
}
@@ -177,10 +177,11 @@ static void
android_media_MediaRecorder_setAudioSource(JNIEnv *env, jobject thiz, jint as)
{
LOGV("setAudioSource(%d)", as);
- if (as < AUDIO_SOURCE_DEFAULT || as > AUDIO_SOURCE_MAX) {
+ if (as < AUDIO_SOURCE_DEFAULT || as >= AUDIO_SOURCE_LIST_END) {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio source");
return;
}
+
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
process_media_recorder_call(env, mr->setAudioSource(as), "java/lang/RuntimeException", "setAudioSource failed.");
}
@@ -201,7 +202,7 @@ static void
android_media_MediaRecorder_setVideoEncoder(JNIEnv *env, jobject thiz, jint ve)
{
LOGV("setVideoEncoder(%d)", ve);
- if (ve < VIDEO_ENCODER_DEFAULT || ve > VIDEO_ENCODER_MPEG_4_SP) {
+ if (ve < VIDEO_ENCODER_DEFAULT || ve >= VIDEO_ENCODER_LIST_END) {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video encoder");
return;
}
@@ -213,7 +214,7 @@ static void
android_media_MediaRecorder_setAudioEncoder(JNIEnv *env, jobject thiz, jint ae)
{
LOGV("setAudioEncoder(%d)", ae);
- if (ae < AUDIO_ENCODER_DEFAULT || ae > AUDIO_ENCODER_AMR_NB) {
+ if (ae < AUDIO_ENCODER_DEFAULT || ae >= AUDIO_ENCODER_LIST_END) {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio encoder");
return;
}
@@ -222,6 +223,29 @@ android_media_MediaRecorder_setAudioEncoder(JNIEnv *env, jobject thiz, jint ae)
}
static void
+android_media_MediaRecorder_setParameters(JNIEnv *env, jobject thiz, jstring params)
+{
+ LOGV("setParameters()");
+ if (params == NULL)
+ {
+ LOGE("Invalid or empty params string. This parameter will be ignored.");
+ return;
+ }
+
+ sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+
+ const char* params8 = env->GetStringUTFChars(params, NULL);
+ if (params8 == NULL)
+ {
+ LOGE("Failed to covert jstring to String8. This parameter will be ignored.");
+ return;
+ }
+
+ process_media_recorder_call(env, mr->setParameters(String8(params8)), "java/lang/RuntimeException", "setParameter failed.");
+ env->ReleaseStringUTFChars(params,params8);
+}
+
+static void
android_media_MediaRecorder_setOutputFileFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
{
LOGV("setOutputFile");
@@ -384,6 +408,7 @@ static JNINativeMethod gMethods[] = {
{"setOutputFormat", "(I)V", (void *)android_media_MediaRecorder_setOutputFormat},
{"setVideoEncoder", "(I)V", (void *)android_media_MediaRecorder_setVideoEncoder},
{"setAudioEncoder", "(I)V", (void *)android_media_MediaRecorder_setAudioEncoder},
+ {"setParameters", "(Ljava/lang/String;)V", (void *)android_media_MediaRecorder_setParameters},
{"_setOutputFile", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaRecorder_setOutputFileFD},
{"setVideoSize", "(II)V", (void *)android_media_MediaRecorder_setVideoSize},
{"setVideoFrameRate", "(I)V", (void *)android_media_MediaRecorder_setVideoFrameRate},
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 84efc2a..a79d4f7 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -189,4 +189,3 @@ status_t BnMediaPlayerService::onTransact(
// ----------------------------------------------------------------------------
}; // namespace android
-
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 0f3eb70..220c998 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -503,7 +503,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2)
// TODO: In the future, we might be on the same thread if the app is
// running in the same process as the media server. In that case,
// this will deadlock.
- //
+ //
// The threadId hack below works around this for the care of prepare
// and seekTo within the same process.
// FIXME: Remember, this is a hack, it's not even a hack that is applied
@@ -511,7 +511,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2)
if (mLockThreadId != getThreadId()) {
mLock.lock();
locked = true;
- }
+ }
if (mPlayer == 0) {
LOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 0a5df0d..6b63931 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -180,7 +180,7 @@ status_t MediaRecorder::setOutputFormat(int of)
LOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
return INVALID_OPERATION;
}
- if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_RAW_AMR) {
+ if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START) { //first non-video output format
LOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
return INVALID_OPERATION;
}
@@ -345,7 +345,7 @@ status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
}
if (!mIsVideoSourceSet) {
LOGE("try to set video frame rate without setting video source first");
- return INVALID_OPERATION;
+ return INVALID_OPERATION;
}
status_t ret = mMediaRecorder->setVideoFrameRate(frames_per_second);
@@ -475,7 +475,7 @@ status_t MediaRecorder::stop()
mCurrentState = MEDIA_RECORDER_ERROR;
return ret;
}
-
+
// FIXME:
// stop and reset are semantically different.
// We treat them the same for now, and will change this in the future.
@@ -492,7 +492,7 @@ status_t MediaRecorder::reset()
LOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
}
-
+
doCleanUp();
status_t ret = UNKNOWN_ERROR;
switch(mCurrentState) {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index e01bd53..ea42f53 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -80,7 +80,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("MIDI getDuration", duratoinWithinTolerence);
}
- @Suppress
@MediumTest
public void testWMA9GetDuration() throws Exception {
int duration = CodecTest.getDuration(MediaNames.WMA9);
@@ -122,7 +121,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("MIDI GetCurrentPosition", currentPosition);
}
- @Suppress
@LargeTest
public void testWMA9GetCurrentPosition() throws Exception {
boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.WMA9);
@@ -160,7 +158,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("MIDI Pause", isPaused);
}
- @Suppress
@LargeTest
public void testWMA9Pause() throws Exception {
boolean isPaused = CodecTest.pause(MediaNames.WMA9);
@@ -232,7 +229,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("MIDI setLooping", isLoop);
}
- @Suppress
@LargeTest
public void testWMA9SetLooping() throws Exception {
boolean isLoop = CodecTest.setLooping(MediaNames.WMA9);
@@ -271,7 +267,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("MIDI seekTo", isLoop);
}
- @Suppress
@LargeTest
public void testWMA9SeekTo() throws Exception {
boolean isLoop = CodecTest.seekTo(MediaNames.WMA9);
@@ -310,7 +305,7 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
boolean isEnd = CodecTest.seekToEnd(MediaNames.MIDI);
assertTrue("MIDI seekToEnd", isEnd);
}
-
+
@Suppress
@LargeTest
public void testWMA9SeekToEnd() throws Exception {
@@ -388,7 +383,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("H264AMR SeekTo", isSeek);
}
- @Suppress
@LargeTest
public void testVideoWMVSeekTo() throws Exception {
boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WMV);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 2ff0c9d..1b98f75 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -347,6 +347,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File h263MemoryOut = new File(H263_VIDEO_PLAYBACK_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(h263MemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
mediaStressPlayback(MediaNames.VIDEO_HIGHRES_H263);
getMemoryWriteToLog(output);
@@ -365,6 +366,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File h264MemoryOut = new File(H264_VIDEO_PLAYBACK_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(h264MemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
mediaStressPlayback(MediaNames.VIDEO_H264_AMR);
getMemoryWriteToLog(output);
@@ -383,6 +385,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File wmvMemoryOut = new File(WMV_VIDEO_PLAYBACK_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(wmvMemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
mediaStressPlayback(MediaNames.VIDEO_WMV);
getMemoryWriteToLog(output);
@@ -401,6 +404,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File videoH263RecordOnlyMemoryOut = new File(H263_VIDEO_ONLY_RECORD_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(videoH263RecordOnlyMemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.H263,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true);
@@ -420,6 +424,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File videoMp4RecordOnlyMemoryOut = new File(MP4_VIDEO_ONLY_RECORD_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(videoMp4RecordOnlyMemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true);
@@ -440,6 +445,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File videoRecordAudioMemoryOut = new File(H263_VIDEO_AUDIO_RECORD_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(videoRecordAudioMemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.H263,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, false);
@@ -459,6 +465,7 @@ public class MediaPlayerPerformance extends ActivityInstrumentationTestCase<Medi
File audioOnlyMemoryOut = new File(AUDIO_ONLY_RECORD_MEMOUT);
Writer output = new BufferedWriter(new FileWriter(audioOnlyMemoryOut));
+ getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressAudioRecord(MediaNames.RECORDER_OUTPUT);
getMemoryWriteToLog(output);
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 4e365ef..36b6ea0 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -19,6 +19,12 @@
package com.google.android.gles_jni;
+import android.app.ActivityThread;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.os.Build;
+import android.util.Log;
+
import java.nio.Buffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL10Ext;
@@ -43,9 +49,30 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack {
public GLImpl() {
}
- public void glGetPointerv(int pname, java.nio.Buffer[] params) {
- throw new UnsupportedOperationException("glGetPointerv");
- }
+ public void glGetPointerv(int pname, java.nio.Buffer[] params) {
+ throw new UnsupportedOperationException("glGetPointerv");
+ }
+
+ private static boolean allowIndirectBuffers(String appName) {
+ boolean result = false;
+ int version = 0;
+ IPackageManager pm = ActivityThread.getPackageManager();
+ try {
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0);
+ if (applicationInfo != null) {
+ version = applicationInfo.targetSdkVersion;
+ }
+ } catch (android.os.RemoteException e) {
+ // ignore
+ }
+ Log.e("OpenGLES", String.format(
+ "Application %s (SDK target %d) called a GL11 Pointer method with an indirect Buffer.",
+ appName, version));
+ if (version <= Build.VERSION_CODES.CUPCAKE) {
+ result = true;
+ }
+ return result;
+ }
// C function void glActiveTexture ( GLenum texture )
diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen
index 011a6ed..9bff0b2 100755
--- a/opengl/tools/glgen/gen
+++ b/opengl/tools/glgen/gen
@@ -4,14 +4,31 @@ set -e
rm -rf out generated
mkdir out
+
+# Create dummy Java files for Android APIs that are used by the code we generate.
+# This allows us to test the generated code without building the rest of Android.
+
mkdir -p out/javax/microedition/khronos/opengles
mkdir -p out/com/google/android/gles_jni
+mkdir -p out/android/app
mkdir -p out/android/graphics
mkdir -p out/android/opengl
+mkdir -p out/android/content
+mkdir -p out/android/content/pm
+mkdir -p out/android/os
+mkdir -p out/android/util
echo "package android.graphics;" > out/android/graphics/Canvas.java
echo "public interface Canvas {}" >> out/android/graphics/Canvas.java
+echo "package android.app; import android.content.pm.IPackageManager; public class ActivityThread { public static final ActivityThread currentActivityThread() { return null; } public static final String currentPackageName(){ return null; } public static IPackageManager getPackageManager() { return null;} }" > out/android/app/ActivityThread.java
+# echo "package android.content; import android.content.pm.PackageManager; public interface Context { public PackageManager getPackageManager(); }" > out/android/content/Context.java
+echo "package android.content.pm; public class ApplicationInfo {public int targetSdkVersion;}" > out/android/content/pm/ApplicationInfo.java
+echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java
+echo "package android.os; public class Build {public static class VERSION_CODES { public static final int CUPCAKE = 3;}; }" > out/android/os/Build.java
+echo "package android.os; public class RemoteException extends Exception {}" > out/android/os/RemoteException.java
+echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java
+
GLFILE=out/javax/microedition/khronos/opengles/GL.java
cp stubs/jsr239/GLHeader.java-if $GLFILE
diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
index 4896acb..4494643 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
+++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
@@ -44,9 +44,11 @@ static jclass OOMEClass;
static jclass UOEClass;
static jclass IAEClass;
static jclass AIOOBEClass;
+static jclass G11ImplClass;
static jmethodID getBasePointerID;
static jmethodID getBaseArrayID;
static jmethodID getBaseArrayOffsetID;
+static jmethodID allowIndirectBuffersID;
static jfieldID positionID;
static jfieldID limitID;
static jfieldID elementSizeShiftID;
@@ -62,13 +64,17 @@ nativeClassInitBuffer(JNIEnv *_env)
jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
+ jclass g11impClassLocal = _env->FindClass("com/google/android/gles_jni/GLImpl");
+ G11ImplClass = (jclass) _env->NewGlobalRef(g11impClassLocal);
+
getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
"getBasePointer", "(Ljava/nio/Buffer;)J");
getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
"getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
"getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
-
+ allowIndirectBuffersID = _env->GetStaticMethodID(g11impClassLocal,
+ "allowIndirectBuffers", "(Ljava/lang/String;)Z");
positionID = _env->GetFieldID(bufferClass, "position", "I");
limitID = _env->GetFieldID(bufferClass, "limit", "I");
elementSizeShiftID =
@@ -118,6 +124,9 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
*array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
getBaseArrayID, buffer);
+ if (*array == NULL) {
+ return (void*) NULL;
+ }
offset = _env->CallStaticIntMethod(nioAccessClass,
getBaseArrayOffsetID, buffer);
data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
@@ -132,17 +141,43 @@ releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
commit ? 0 : JNI_ABORT);
}
+extern "C" {
+extern char* __progname;
+}
+
+static bool
+allowIndirectBuffers(JNIEnv *_env) {
+ static jint sIndirectBufferCompatability;
+ if (sIndirectBufferCompatability == 0) {
+ jobject appName = _env->NewStringUTF(::__progname);
+ sIndirectBufferCompatability = _env->CallStaticBooleanMethod(G11ImplClass, allowIndirectBuffersID, appName) ? 2 : 1;
+ }
+ return sIndirectBufferCompatability == 2;
+}
+
static void *
getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
- char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (!buffer) {
+ return NULL;
+ }
+ void* buf = _env->GetDirectBufferAddress(buffer);
if (buf) {
jint position = _env->GetIntField(buffer, positionID);
jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
- buf += position << elementSizeShift;
+ buf = ((char*) buf) + (position << elementSizeShift);
} else {
- _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ if (allowIndirectBuffers(_env)) {
+ jarray array = 0;
+ jint remaining;
+ buf = getPointer(_env, buffer, &array, &remaining);
+ if (array) {
+ releasePointer(_env, array, buf, 0);
+ }
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
}
- return (void*) buf;
+ return buf;
}
static int
diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
index db3a41c..fe60c5d 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
+++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
@@ -18,6 +18,12 @@
package com.google.android.gles_jni;
+import android.app.ActivityThread;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.os.Build;
+import android.util.Log;
+
import java.nio.Buffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL10Ext;
@@ -42,7 +48,28 @@ public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack {
public GLImpl() {
}
- public void glGetPointerv(int pname, java.nio.Buffer[] params) {
- throw new UnsupportedOperationException("glGetPointerv");
- }
+ public void glGetPointerv(int pname, java.nio.Buffer[] params) {
+ throw new UnsupportedOperationException("glGetPointerv");
+ }
+
+ private static boolean allowIndirectBuffers(String appName) {
+ boolean result = false;
+ int version = 0;
+ IPackageManager pm = ActivityThread.getPackageManager();
+ try {
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0);
+ if (applicationInfo != null) {
+ version = applicationInfo.targetSdkVersion;
+ }
+ } catch (android.os.RemoteException e) {
+ // ignore
+ }
+ Log.e("OpenGLES", String.format(
+ "Application %s (SDK target %d) called a GL11 Pointer method with an indirect Buffer.",
+ appName, version));
+ if (version <= Build.VERSION_CODES.CUPCAKE) {
+ result = true;
+ }
+ return result;
+ }
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 4abc337..16c66a6 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -2,12 +2,6 @@
package="com.android.providers.settings"
android:sharedUserId="android.uid.system">
- <!-- Permission to write Gservices in SettingsProvider -->
- <permission android:name="android.permission.WRITE_GSERVICES"
- android:label="@string/permlab_writeGservices"
- android:description="@string/permdesc_writeGservices"
- android:protectionLevel="signature" />
-
<application android:allowClearUserData="false"
android:label="Settings Storage"
android:icon="@drawable/ic_launcher_settings">
diff --git a/packages/SettingsProvider/res/values/strings.xml b/packages/SettingsProvider/res/values/strings.xml
deleted file mode 100644
index 8a00091..0000000
--- a/packages/SettingsProvider/res/values/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
- * Copyright (c) 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<resources>
- <string name="permlab_writeGservices">Write Gservices settings.</string>
- <string name="permdesc_writeGservices">Allows the application to
- change the settings in Gservices.</string>
-</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 57f8147..f861400 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -609,10 +609,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
R.bool.def_accelerometer_rotation);
- // Default date format based on build
- loadSetting(stmt, Settings.System.DATE_FORMAT,
- SystemProperties.get("ro.com.android.dateformat",
- "MM-dd-yyyy"));
stmt.close();
}
diff --git a/packages/TtsService/Android.mk b/packages/TtsService/Android.mk
new file mode 100644
index 0000000..2737fb4
--- /dev/null
+++ b/packages/TtsService/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+
+LOCAL_PACKAGE_NAME := TtsService
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/TtsService/AndroidManifest.xml b/packages/TtsService/AndroidManifest.xml
new file mode 100755
index 0000000..1dc25c6
--- /dev/null
+++ b/packages/TtsService/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.tts">
+ <application android:label="TTS Service">
+ <service android:enabled="true"
+ android:name=".TtsService"
+ android:label="TTS Service">
+ <intent-filter>
+ <action android:name="android.intent.action.USE_TTS"/>
+ <category android:name="android.intent.category.TTS"/>
+ </intent-filter>
+ </service>
+ </application>
+ <uses-permission android:name="android.permission.INTERNET"/>
+</manifest>
diff --git a/packages/TtsService/MODULE_LICENSE_APACHE2 b/packages/TtsService/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/TtsService/MODULE_LICENSE_APACHE2
diff --git a/packages/TtsService/NOTICE b/packages/TtsService/NOTICE
new file mode 100644
index 0000000..64aaa8d
--- /dev/null
+++ b/packages/TtsService/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2009, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/tts/jni/Android.mk b/packages/TtsService/jni/Android.mk
index 665d6d2..665d6d2 100755
--- a/tts/jni/Android.mk
+++ b/packages/TtsService/jni/Android.mk
diff --git a/tts/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index d8f1bf3..582e6219 100755..100644
--- a/tts/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -32,6 +32,7 @@
#define DEFAULT_TTS_RATE 16000
#define DEFAULT_TTS_FORMAT AudioSystem::PCM_16_BIT
#define DEFAULT_TTS_NB_CHANNELS 1
+#define DEFAULT_TTS_BUFFERSIZE 1024
#define USAGEMODE_PLAY_IMMEDIATELY 0
#define USAGEMODE_WRITE_TO_FILE 1
@@ -64,6 +65,8 @@ class SynthProxyJniStorage {
uint32_t mSampleRate;
AudioSystem::audio_format mAudFormat;
int mNbChannels;
+ int8_t * mBuffer;
+ size_t mBufferSize;
SynthProxyJniStorage() {
//tts_class = NULL;
@@ -73,6 +76,8 @@ class SynthProxyJniStorage {
mSampleRate = DEFAULT_TTS_RATE;
mAudFormat = DEFAULT_TTS_FORMAT;
mNbChannels = DEFAULT_TTS_NB_CHANNELS;
+ mBufferSize = DEFAULT_TTS_BUFFERSIZE;
+ mBuffer = new int8_t[mBufferSize];
}
~SynthProxyJniStorage() {
@@ -81,6 +86,7 @@ class SynthProxyJniStorage {
mNativeSynthInterface->shutdown();
mNativeSynthInterface = NULL;
}
+ delete mBuffer;
}
void killAudio() {
@@ -159,23 +165,27 @@ void prepAudioTrack(SynthProxyJniStorage* pJniData,
* Callback from TTS engine.
* Directly speaks using AudioTrack or write to file
*/
-static void ttsSynthDoneCB(void * userdata, uint32_t rate,
+static tts_callback_status ttsSynthDoneCB(void *& userdata, uint32_t rate,
AudioSystem::audio_format format, int channel,
- int8_t *wav, size_t bufferSize) {
+ int8_t *&wav, size_t &bufferSize, tts_synth_status status) {
LOGI("ttsSynthDoneCallback: %d bytes", bufferSize);
+ if (userdata == NULL){
+ LOGE("userdata == NULL");
+ return TTS_CALLBACK_HALT;
+ }
afterSynthData_t* pForAfter = (afterSynthData_t*)userdata;
+ SynthProxyJniStorage* pJniData = (SynthProxyJniStorage*)(pForAfter->jniStorage);
if (pForAfter->usageMode == USAGEMODE_PLAY_IMMEDIATELY){
LOGI("Direct speech");
if (wav == NULL) {
+ delete pForAfter;
LOGI("Null: speech has completed");
}
if (bufferSize > 0) {
- SynthProxyJniStorage* pJniData =
- (SynthProxyJniStorage*)(pForAfter->jniStorage);
prepAudioTrack(pJniData, rate, format, channel);
if (pJniData->mAudioOut) {
pJniData->mAudioOut->write(wav, bufferSize);
@@ -187,6 +197,7 @@ static void ttsSynthDoneCB(void * userdata, uint32_t rate,
} else if (pForAfter->usageMode == USAGEMODE_WRITE_TO_FILE) {
LOGI("Save to file");
if (wav == NULL) {
+ delete pForAfter;
LOGI("Null: speech has completed");
}
if (bufferSize > 0){
@@ -195,10 +206,17 @@ static void ttsSynthDoneCB(void * userdata, uint32_t rate,
}
// TODO update to call back into the SynthProxy class through the
// javaTTSFields.synthProxyMethodPost methode to notify
- // playback has completed
+ // playback has completed if the synthesis is done, i.e.
+ // if status == TTS_SYNTH_DONE
+ //delete pForAfter;
+
+ // we don't update the wav (output) parameter as we'll let the next callback
+ // write at the same location, we've consumed the data already, but we need
+ // to update bufferSize to let the TTS engine know how much it can write the
+ // next time it calls this function.
+ bufferSize = pJniData->mBufferSize;
- delete pForAfter;
- return;
+ return TTS_CALLBACK_CONTINUE;
}
@@ -223,7 +241,9 @@ android_tts_SynthProxy_native_setup(JNIEnv *env, jobject thiz,
} else {
TtsEngine *(*get_TtsEngine)() =
reinterpret_cast<TtsEngine* (*)()>(dlsym(engine_lib_handle, "getTtsEngine"));
+
pJniStorage->mNativeSynthInterface = (*get_TtsEngine)();
+
if (pJniStorage->mNativeSynthInterface) {
pJniStorage->mNativeSynthInterface->init(ttsSynthDoneCB);
}
@@ -323,7 +343,7 @@ android_tts_SynthProxy_synthesizeToFile(JNIEnv *env, jobject thiz, jint jniData,
// TODO check return codes
if (pSynthData->mNativeSynthInterface) {
- pSynthData->mNativeSynthInterface->synthesizeText(textNativeString,
+ pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer, pSynthData->mBufferSize,
(void *)pForAfter);
}
@@ -395,7 +415,7 @@ android_tts_SynthProxy_speak(JNIEnv *env, jobject thiz, jint jniData,
if (pSynthData->mNativeSynthInterface) {
const char *textNativeString = env->GetStringUTFChars(textJavaString, 0);
- pSynthData->mNativeSynthInterface->synthesizeText(textNativeString,
+ pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer, pSynthData->mBufferSize,
(void *)pForAfter);
env->ReleaseStringUTFChars(textJavaString, textNativeString);
}
@@ -442,6 +462,7 @@ static void
android_tts_SynthProxy_playAudioBuffer(JNIEnv *env, jobject thiz, jint jniData,
int bufferPointer, int bufferSize)
{
+LOGI("android_tts_SynthProxy_playAudioBuffer");
if (jniData == 0) {
LOGE("android_tts_SynthProxy_playAudioBuffer(): invalid JNI data");
return;
diff --git a/tts/java/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index e065f40..e065f40 100755
--- a/tts/java/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
diff --git a/tts/java/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index d317181..8a64113 100755
--- a/tts/java/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -15,14 +15,14 @@
*/
package android.tts;
-import android.tts.ITts.Stub;
+import android.speech.tts.ITts.Stub;
+import android.speech.tts.ITtsCallback;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
@@ -92,7 +92,7 @@ public class TtsService extends Service implements OnCompletionListener {
private static final String CATEGORY = "android.intent.category.TTS";
private static final String PKGNAME = "android.tts";
- final RemoteCallbackList<ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
+ final RemoteCallbackList<android.speech.tts.ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
private Boolean mIsSpeaking;
private ArrayList<SpeechItem> mSpeechQueue;
@@ -106,7 +106,6 @@ public class TtsService extends Service implements OnCompletionListener {
private final ReentrantLock speechQueueLock = new ReentrantLock();
private final ReentrantLock synthesizerLock = new ReentrantLock();
- // TODO support multiple SpeechSynthesis objects
private SynthProxy nativeSynth;
@Override
@@ -114,15 +113,12 @@ public class TtsService extends Service implements OnCompletionListener {
super.onCreate();
Log.i("TTS", "TTS starting");
-
// TODO: Make this work when the settings are done in the main Settings
// app.
prefs = PreferenceManager.getDefaultSharedPreferences(this);
- // TODO: This should be changed to work by requesting the path
- // from the default engine.
- nativeSynth = new SynthProxy(prefs.getString("engine_pref", ""));
-
+ String soLibPath = "/system/lib/libttspico.so";
+ nativeSynth = new SynthProxy(soLibPath);
mSelf = this;
mIsSpeaking = false;
@@ -170,35 +166,6 @@ public class TtsService extends Service implements OnCompletionListener {
nativeSynth.setLanguage(lang);
}
- private void setEngine(String engineName, String[] requestedLanguages,
- int strictness) {
- // TODO: Implement engine selection code here.
- Intent engineIntent = new Intent(
- "android.intent.action.START_TTS_ENGINE");
- if (engineName != null) {
- engineIntent.addCategory("android.intent.action.tts_engine."
- + engineName);
- }
- for (int i = 0; i < requestedLanguages.length; i++) {
- engineIntent.addCategory("android.intent.action.tts_lang."
- + requestedLanguages[i]);
- }
- ResolveInfo[] enginesArray = new ResolveInfo[0];
- PackageManager pm = getPackageManager();
- enginesArray = pm.queryIntentActivities(engineIntent, 0).toArray(
- enginesArray);
- }
-
- private void setEngine(Intent engineIntent) {
- // TODO: Implement engine selection code here.
- }
-
- private int getEngineStatus() {
- // TODO: Proposal - add a sanity check method that
- // TTS engine plugins must implement.
- return 0;
- }
-
/**
* Adds a sound resource to the TTS.
*
@@ -436,8 +403,7 @@ public class TtsService extends Service implements OnCompletionListener {
if (sr == null) {
if (currentSpeechItem.mType == SpeechItem.SPEECH) {
// TODO: Split text up into smaller chunks before accepting
- // them
- // for processing.
+ // them for processing.
speakInternalOnly(currentSpeechItem.mText,
currentSpeechItem.mParams);
} else {
@@ -563,7 +529,7 @@ public class TtsService extends Service implements OnCompletionListener {
return null;
}
- private final ITts.Stub mBinder = new Stub() {
+ private final android.speech.tts.ITts.Stub mBinder = new Stub() {
public void registerCallback(ITtsCallback cb) {
if (cb != null)
@@ -576,30 +542,6 @@ public class TtsService extends Service implements OnCompletionListener {
}
/**
- * Gives a hint about the type of engine that is preferred.
- *
- * @param selectedEngine
- * The TTS engine that should be used
- */
- public void setEngine(String engineName, String[] supportedLanguages,
- int strictness) {
- mSelf.setEngine(engineName, supportedLanguages, strictness);
- }
-
- /**
- * Specifies exactly what the engine has to support. Will always be
- * considered "strict"; can be used for implementing
- * optional/experimental features that are not supported by all engines.
- *
- * @param engineIntent
- * An intent that specifies exactly what the engine has to
- * support.
- */
- public void setEngineWithIntent(Intent engineIntent) {
- mSelf.setEngine(engineIntent);
- }
-
- /**
* Speaks the given text using the specified queueing mode and
* parameters.
*
@@ -658,7 +600,6 @@ public class TtsService extends Service implements OnCompletionListener {
mSelf.playSilence(duration, queueMode, speakingParams);
}
-
/**
* Stops all speech output and removes any utterances still in the
* queue.
@@ -741,16 +682,18 @@ public class TtsService extends Service implements OnCompletionListener {
mSelf.setSpeechRate(speechRate);
}
- // TODO: Fix comment about language
/**
* Sets the speech rate for the TTS. Note that this will only have an
* effect on synthesized speech; it will not affect pre-recorded speech.
*
* @param language
- * The language to be used. The languages are specified by
- * their IETF language tags as defined by BCP 47. This is the
- * same standard used for the lang attribute in HTML. See:
- * http://en.wikipedia.org/wiki/IETF_language_tag
+ * Language values are based on the Android conventions for
+ * localization as described in the Android platform
+ * documentation on internationalization. This implies that
+ * language data is specified in the format xx-rYY, where xx
+ * is a two letter ISO 639-1 language code in lowercase and
+ * rYY is a two letter ISO 3166-1-alpha-2 language code in
+ * uppercase preceded by a lowercase "r".
*/
public void setLanguage(String language) {
mSelf.setLanguage(language);
diff --git a/packages/VpnServices/Android.mk b/packages/VpnServices/Android.mk
new file mode 100644
index 0000000..eb27ed5
--- /dev/null
+++ b/packages/VpnServices/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES :=
+
+LOCAL_PACKAGE_NAME := VpnServices
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/VpnServices/AndroidManifest.xml b/packages/VpnServices/AndroidManifest.xml
new file mode 100644
index 0000000..e48b2da
--- /dev/null
+++ b/packages/VpnServices/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.vpn"
+ android:sharedUserId="android.uid.system"
+ >
+ <application android:label="VPN Services">
+
+ <service android:name=".VpnServiceBinder" android:process=":remote">
+ <intent-filter>
+ <!-- These are the interfaces supported by the service, which
+ you can bind to. -->
+ <action android:name="android.net.vpn.IVpnService" />
+ <!-- This is an action code you can use to select the service
+ without explicitly supplying the implementation class. -->
+ <action android:name="android.net.vpn.SERVICE" />
+ </intent-filter>
+ </service>
+
+ </application>
+
+ <uses-permission android:name="android.permission.INTERNET"></uses-permission>
+</manifest>
diff --git a/packages/VpnServices/MODULE_LICENSE_APACHE2 b/packages/VpnServices/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/VpnServices/MODULE_LICENSE_APACHE2
diff --git a/packages/VpnServices/NOTICE b/packages/VpnServices/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/VpnServices/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/packages/VpnServices/res/drawable/vpn_connected.png
new file mode 100644
index 0000000..65fc6db
--- /dev/null
+++ b/packages/VpnServices/res/drawable/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/packages/VpnServices/res/drawable/vpn_disconnected.png
new file mode 100644
index 0000000..2440c69
--- /dev/null
+++ b/packages/VpnServices/res/drawable/vpn_disconnected.png
Binary files differ
diff --git a/packages/VpnServices/res/values/strings.xml b/packages/VpnServices/res/values/strings.xml
new file mode 100755
index 0000000..892850a
--- /dev/null
+++ b/packages/VpnServices/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="vpn_notification_title">%s VPN %s</string>
+ <string name="vpn_notification_connected">connected</string>
+ <string name="vpn_notification_disconnected">disconnected</string>
+ <string name="vpn_notification_connected_message">Up time: %s</string>
+</resources>
+
diff --git a/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
new file mode 100644
index 0000000..a12db8c
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/AndroidServiceProxy.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Proxy to start, stop and interact with an Android service defined in init.rc.
+ * The android service is expected to accept connection through Unix domain
+ * socket. When the proxy successfully starts the service, it will establish a
+ * socket connection with the service. The socket serves two purposes: (1) send
+ * commands to the service; (2) for the proxy to know whether the service is
+ * alive.
+ *
+ * After the service receives commands from the proxy, it should return either
+ * 0 if the service will close the socket (and the proxy will re-establish
+ * another connection immediately after), or 1 if the socket is remained alive.
+ */
+public class AndroidServiceProxy extends ProcessProxy {
+ private static final int WAITING_TIME = 15; // sec
+
+ private static final String SVC_STATE_CMD_PREFIX = "init.svc.";
+ private static final String SVC_START_CMD = "ctl.start";
+ private static final String SVC_STOP_CMD = "ctl.stop";
+ private static final String SVC_STATE_RUNNING = "running";
+ private static final String SVC_STATE_STOPPED = "stopped";
+
+ private static final int END_OF_ARGUMENTS = 255;
+
+ private String mServiceName;
+ private String mSocketName;
+ private LocalSocket mKeepaliveSocket;
+ private boolean mControlSocketInUse;
+ private Integer mSocketResult = null;
+ private String mTag;
+
+ /**
+ * Creates a proxy with the service name.
+ * @param serviceName the service name
+ */
+ public AndroidServiceProxy(String serviceName) {
+ mServiceName = serviceName;
+ mSocketName = serviceName;
+ mTag = "SProxy_" + serviceName;
+ }
+
+ @Override
+ public String getName() {
+ return "Service " + mServiceName;
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (isRunning()) setResultAndCloseControlSocket(-1);
+ SystemProperties.set(SVC_STOP_CMD, mServiceName);
+ }
+
+ /**
+ * Sends a command with arguments to the service through the control socket.
+ * Each argument is sent as a C-style zero-terminated string.
+ */
+ public void sendCommand(String ...args) throws IOException {
+ OutputStream out = getControlSocketOutput();
+ for (String arg : args) outputString(out, arg);
+ checkSocketResult();
+ }
+
+ /**
+ * Sends a command with arguments to the service through the control socket.
+ */
+ public void sendCommand2(String ...args) throws IOException {
+ OutputStream out = getControlSocketOutput();
+ for (String arg : args) outputString2(out, arg);
+ out.write(END_OF_ARGUMENTS);
+ out.flush();
+ checkSocketResult();
+ }
+
+ /**
+ * {@inheritDoc}
+ * The method returns when the service exits.
+ */
+ @Override
+ protected void performTask() throws IOException {
+ String svc = mServiceName;
+ Log.d(mTag, "+++++ Execute: " + svc);
+ SystemProperties.set(SVC_START_CMD, svc);
+
+ boolean success = blockUntil(SVC_STATE_RUNNING, WAITING_TIME);
+
+ if (success) {
+ Log.d(mTag, "----- Running: " + svc + ", create keepalive socket");
+ LocalSocket s = mKeepaliveSocket = createServiceSocket();
+ setState(ProcessState.RUNNING);
+
+ if (s == null) {
+ // no socket connection, stop hosting the service
+ stop();
+ return;
+ }
+ try {
+ for (;;) {
+ InputStream in = s.getInputStream();
+ int data = in.read();
+ if (data >= 0) {
+ Log.d(mTag, "got data from keepalive socket: " + data);
+
+ if (data == 0) {
+ // re-establish the connection:
+ // synchronized here so that checkSocketResult() returns
+ // when new mKeepaliveSocket is available for next cmd
+ synchronized (this) {
+ setResultAndCloseControlSocket((byte) data);
+ s = mKeepaliveSocket = createServiceSocket();
+ }
+ } else {
+ // keep the socket
+ setSocketResult(data);
+ }
+ } else {
+ // service is gone
+ if (mControlSocketInUse) setSocketResult(-1);
+ break;
+ }
+ }
+ Log.d(mTag, "keepalive connection closed");
+ } catch (IOException e) {
+ Log.d(mTag, "keepalive socket broken: " + e.getMessage());
+ }
+
+ // Wait 5 seconds for the service to exit
+ success = blockUntil(SVC_STATE_STOPPED, 5);
+ Log.d(mTag, "stopping " + svc + ", success? " + success);
+ } else {
+ setState(ProcessState.STOPPED);
+ throw new IOException("cannot start service: " + svc);
+ }
+ }
+
+ private LocalSocket createServiceSocket() throws IOException {
+ LocalSocket s = new LocalSocket();
+ LocalSocketAddress a = new LocalSocketAddress(mSocketName,
+ LocalSocketAddress.Namespace.RESERVED);
+
+ // try a few times in case the service has not listen()ed
+ IOException excp = null;
+ for (int i = 0; i < 10; i++) {
+ try {
+ s.connect(a);
+ return s;
+ } catch (IOException e) {
+ Log.d(mTag, "service not yet listen()ing; try again");
+ excp = e;
+ sleep(500);
+ }
+ }
+ throw excp;
+ }
+
+ private OutputStream getControlSocketOutput() throws IOException {
+ if (mKeepaliveSocket != null) {
+ mControlSocketInUse = true;
+ mSocketResult = null;
+ return mKeepaliveSocket.getOutputStream();
+ } else {
+ throw new IOException("no control socket available");
+ }
+ }
+
+ private synchronized void checkSocketResult() throws IOException {
+ try {
+ // will be notified when the result comes back from service
+ if (mSocketResult == null) wait();
+ } catch (InterruptedException e) {
+ Log.d(mTag, "checkSocketResult(): " + e);
+ } finally {
+ mControlSocketInUse = false;
+ if ((mSocketResult == null) || (mSocketResult < 0)) {
+ throw new IOException("socket error, result from service: "
+ + mSocketResult);
+ }
+ }
+ }
+
+ private synchronized void setSocketResult(int result) {
+ if (mControlSocketInUse) {
+ mSocketResult = result;
+ notifyAll();
+ }
+ }
+
+ private void setResultAndCloseControlSocket(int result) {
+ setSocketResult(result);
+ try {
+ mKeepaliveSocket.shutdownInput();
+ mKeepaliveSocket.shutdownOutput();
+ mKeepaliveSocket.close();
+ } catch (IOException e) {
+ Log.e(mTag, "close keepalive socket", e);
+ } finally {
+ mKeepaliveSocket = null;
+ }
+ }
+
+ /**
+ * Waits for the process to be in the expected state. The method returns
+ * false if after the specified duration (in seconds), the process is still
+ * not in the expected state.
+ */
+ private boolean blockUntil(String expectedState, int waitTime) {
+ String cmd = SVC_STATE_CMD_PREFIX + mServiceName;
+ int sleepTime = 200; // ms
+ int n = waitTime * 1000 / sleepTime;
+ for (int i = 0; i < n; i++) {
+ if (expectedState.equals(SystemProperties.get(cmd))) {
+ Log.d(mTag, mServiceName + " is " + expectedState + " after "
+ + (i * sleepTime) + " msec");
+ break;
+ }
+ sleep(sleepTime);
+ }
+ return expectedState.equals(SystemProperties.get(cmd));
+ }
+
+ private void outputString(OutputStream out, String s) throws IOException {
+ out.write(s.getBytes());
+ out.write(0);
+ out.flush();
+ }
+
+ private void outputString2(OutputStream out, String s) throws IOException {
+ byte[] bytes = s.getBytes();
+ out.write(bytes.length);
+ out.write(bytes);
+ out.flush();
+ }
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
new file mode 100644
index 0000000..ce56921
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.net.vpn.L2tpIpsecProfile;
+import android.security.Keystore;
+
+import java.io.IOException;
+
+/**
+ * The service that manages the L2TP-over-IPSec VPN connection.
+ */
+class L2tpIpsecService extends VpnService<L2tpIpsecProfile> {
+ private static final String IPSEC_SERVICE = "racoon";
+ private static final String L2TP_SERVICE = "mtpd";
+
+ @Override
+ protected void connect(String serverIp, String username, String password)
+ throws IOException {
+ String hostIp = getHostIp();
+
+ // IPSEC
+ AndroidServiceProxy ipsecService = startService(IPSEC_SERVICE);
+ ipsecService.sendCommand(
+ String.format("SETKEY %s %s", hostIp, serverIp));
+ ipsecService.sendCommand(String.format("SET_CERTS %s %s %s %s",
+ serverIp, getCaCertPath(), getUserCertPath(),
+ getUserkeyPath()));
+
+ // L2TP
+ AndroidServiceProxy l2tpService = startService(L2TP_SERVICE);
+ l2tpService.sendCommand2("l2tp", serverIp, "1701", "",
+ "file", getPppOptionFilePath(),
+ "name", username,
+ "password", password);
+ }
+
+ private String getCaCertPath() {
+ return Keystore.getInstance().getCertificate(
+ getProfile().getCaCertificate());
+ }
+
+ private String getUserCertPath() {
+ return Keystore.getInstance().getCertificate(
+ getProfile().getUserCertificate());
+ }
+
+ private String getUserkeyPath() {
+ return Keystore.getInstance().getUserkey(getProfile().getUserkey());
+ }
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpService.java
new file mode 100644
index 0000000..9aad7a1
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.net.vpn.L2tpProfile;
+
+import java.io.IOException;
+
+/**
+ * The service that manages the L2TP VPN connection.
+ */
+class L2tpService extends VpnService<L2tpProfile> {
+ private static final String L2TP_SERVICE = "mtpd";
+
+ @Override
+ protected void connect(String serverIp, String username, String password)
+ throws IOException {
+ String hostIp = getHostIp();
+
+ // L2TP
+ AndroidServiceProxy l2tpService = startService(L2TP_SERVICE);
+ l2tpService.sendCommand2("l2tp", serverIp, "1701", "",
+ "file", getPppOptionFilePath(),
+ "name", username,
+ "password", password);
+ }
+
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/NormalProcessProxy.java b/packages/VpnServices/src/com/android/server/vpn/NormalProcessProxy.java
new file mode 100644
index 0000000..f20d85f
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/NormalProcessProxy.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+/**
+ * Proxy to perform a command with arguments.
+ */
+public class NormalProcessProxy extends ProcessProxy {
+ private Process mProcess;
+ private String[] mArgs;
+ private String mTag;
+
+ /**
+ * Creates a proxy with the arguments.
+ * @param args the argument list with the first one being the command
+ */
+ public NormalProcessProxy(String ...args) {
+ if ((args == null) || (args.length == 0)) {
+ throw new IllegalArgumentException();
+ }
+ mArgs = args;
+ mTag = "PProxy_" + getName();
+ }
+
+ @Override
+ public String getName() {
+ return mArgs[0];
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (isStopped()) return;
+ getHostThread().interrupt();
+ // TODO: not sure how to reliably kill a process
+ mProcess.destroy();
+ setState(ProcessState.STOPPING);
+ }
+
+ @Override
+ protected void performTask() throws IOException, InterruptedException {
+ String[] args = mArgs;
+ Log.d(mTag, "+++++ Execute: " + getEntireCommand());
+ ProcessBuilder pb = new ProcessBuilder(args);
+ setState(ProcessState.RUNNING);
+ Process p = mProcess = pb.start();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ p.getInputStream()));
+ while (true) {
+ String line = reader.readLine();
+ if ((line == null) || isStopping()) break;
+ Log.d(mTag, line);
+ }
+
+ Log.d(mTag, "----- p.waitFor(): " + getName());
+ p.waitFor();
+ Log.d(mTag, "----- Done: " + getName());
+ }
+
+ private CharSequence getEntireCommand() {
+ String[] args = mArgs;
+ StringBuilder sb = new StringBuilder(args[0]);
+ for (int i = 1; i < args.length; i++) sb.append(' ').append(args[i]);
+ return sb;
+ }
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/ProcessProxy.java b/packages/VpnServices/src/com/android/server/vpn/ProcessProxy.java
new file mode 100644
index 0000000..14d7521
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/ProcessProxy.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.os.ConditionVariable;
+
+import java.io.IOException;
+
+/**
+ * A proxy class that spawns a process to accomplish a certain task.
+ */
+public abstract class ProcessProxy {
+ /**
+ * Defines the interface to call back when the process is finished or an
+ * error occurs during execution.
+ */
+ public static interface Callback {
+ /**
+ * Called when the process is finished.
+ * @param proxy the proxy that hosts the process
+ */
+ void done(ProcessProxy proxy);
+
+ /**
+ * Called when some error occurs.
+ * @param proxy the proxy that hosts the process
+ */
+ void error(ProcessProxy proxy, Throwable error);
+ }
+
+ protected enum ProcessState {
+ STOPPED, STARTING, RUNNING, STOPPING, ERROR
+ }
+
+ private ProcessState mState = ProcessState.STOPPED;
+ private ConditionVariable mLock = new ConditionVariable();
+ private Thread mThread;
+
+ /**
+ * Returns the name of the process.
+ */
+ public abstract String getName();
+
+ /**
+ * Starts the process with a callback.
+ * @param callback the callback to get notified when the process is finished
+ * or an error occurs during execution
+ * @throws IOException when the process is already running or failed to
+ * start
+ */
+ public synchronized void start(final Callback callback) throws IOException {
+ if (!isStopped()) {
+ throw new IOException("Process is already running: " + this);
+ }
+ mLock.close();
+ setState(ProcessState.STARTING);
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ performTask();
+ setState(ProcessState.STOPPED);
+ mLock.open();
+ if (callback != null) callback.done(ProcessProxy.this);
+ } catch (Throwable e) {
+ setState(ProcessState.ERROR);
+ if (callback != null) callback.error(ProcessProxy.this, e);
+ } finally {
+ mThread = null;
+ }
+ }
+ });
+ thread.setPriority(Thread.MIN_PRIORITY);
+ thread.start();
+ mThread = thread;
+ if (!waitUntilRunning()) {
+ throw new IOException("Failed to start the process: " + this);
+ }
+ }
+
+ /**
+ * Starts the process.
+ * @throws IOException when the process is already running or failed to
+ * start
+ */
+ public synchronized void start() throws IOException {
+ start(null);
+ if (!waitUntilDone()) {
+ throw new IOException("Failed to complete the process: " + this);
+ }
+ }
+
+ /**
+ * Returns the thread that hosts the process.
+ */
+ public Thread getHostThread() {
+ return mThread;
+ }
+
+ /**
+ * Blocks the current thread until the hosted process is finished.
+ *
+ * @return true if the process is finished normally; false if an error
+ * occurs
+ */
+ public boolean waitUntilDone() {
+ while (!mLock.block(1000)) {
+ if (isStopped() || isInError()) break;
+ }
+ return isStopped();
+ }
+
+ /**
+ * Blocks the current thread until the hosted process is running.
+ *
+ * @return true if the process is running normally; false if the process
+ * is in another state
+ */
+ private boolean waitUntilRunning() {
+ for (;;) {
+ if (!isStarting()) break;
+ }
+ return isRunning();
+ }
+
+ /**
+ * Stops and destroys the process.
+ */
+ public abstract void stop();
+
+ /**
+ * Checks whether the process is finished.
+ * @return true if the process is stopped
+ */
+ public boolean isStopped() {
+ return (mState == ProcessState.STOPPED);
+ }
+
+ /**
+ * Checks whether the process is being stopped.
+ * @return true if the process is being stopped
+ */
+ public boolean isStopping() {
+ return (mState == ProcessState.STOPPING);
+ }
+
+ /**
+ * Checks whether the process is being started.
+ * @return true if the process is being started
+ */
+ public boolean isStarting() {
+ return (mState == ProcessState.STARTING);
+ }
+
+ /**
+ * Checks whether the process is running.
+ * @return true if the process is running
+ */
+ public boolean isRunning() {
+ return (mState == ProcessState.RUNNING);
+ }
+
+ /**
+ * Checks whether some error has occurred and the process is stopped.
+ * @return true if some error has occurred and the process is stopped
+ */
+ public boolean isInError() {
+ return (mState == ProcessState.ERROR);
+ }
+
+ /**
+ * Performs the actual task. Subclasses must make sure that the method
+ * is blocked until the task is done or an error occurs.
+ */
+ protected abstract void performTask()
+ throws IOException, InterruptedException;
+
+ /**
+ * Sets the process state.
+ * @param state the new state to be in
+ */
+ protected void setState(ProcessState state) {
+ mState = state;
+ }
+
+ /**
+ * Makes the current thread sleep for the specified time.
+ * @param msec time to sleep in miliseconds
+ */
+ protected void sleep(int msec) {
+ try {
+ Thread.currentThread().sleep(msec);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
new file mode 100644
index 0000000..fdefe9c
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.os.FileObserver;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The service base class for managing a type of VPN connection.
+ */
+abstract class VpnService<E extends VpnProfile> {
+ private static final int NOTIFICATION_ID = 1;
+ private static final String PROFILES_ROOT = VpnManager.PROFILES_PATH + "/";
+ public static final String DEFAULT_CONFIG_PATH = "/etc";
+
+ private static final int DNS_TIMEOUT = 3000; // ms
+ private static final String DNS1 = "net.dns1";
+ private static final String DNS2 = "net.dns2";
+ private static final String REMOTE_IP = "net.ipremote";
+ private static final String DNS_DOMAIN_SUFFICES = "net.dns.search";
+ private static final String SERVER_IP = "net.vpn.server_ip";
+
+ private static final int VPN_TIMEOUT = 30000; // milliseconds
+ private static final int ONE_SECOND = 1000; // milliseconds
+ private static final int FIVE_SECOND = 5000; // milliseconds
+
+ private static final String LOGWRAPPER = "/system/bin/logwrapper";
+ private final String TAG = VpnService.class.getSimpleName();
+
+ E mProfile;
+ VpnServiceBinder mContext;
+
+ private VpnState mState = VpnState.IDLE;
+ private boolean mInError;
+
+ // connection settings
+ private String mOriginalDns1;
+ private String mOriginalDns2;
+ private String mVpnDns1 = "";
+ private String mVpnDns2 = "";
+ private String mOriginalDomainSuffices;
+ private String mHostIp;
+
+ private long mStartTime; // VPN connection start time
+
+ // monitors if the VPN connection is sucessfully established
+ private FileMonitor mConnectMonitor;
+
+ // watch dog timer; fired up if the connection cannot be established within
+ // VPN_TIMEOUT
+ private Object mWatchdog;
+
+ // for helping managing multiple Android services
+ private ServiceHelper mServiceHelper = new ServiceHelper();
+
+ // for helping showing, updating notification
+ private NotificationHelper mNotification = new NotificationHelper();
+
+ /**
+ * Establishes a VPN connection with the specified username and password.
+ */
+ protected abstract void connect(String serverIp, String username,
+ String password) throws IOException;
+
+ /**
+ * Tears down the VPN connection. The base class simply terminates all the
+ * Android services. A subclass may need to do some clean-up before that.
+ */
+ protected void disconnect() {
+ }
+
+ /**
+ * Starts an Android service defined in init.rc.
+ */
+ protected AndroidServiceProxy startService(String serviceName)
+ throws IOException {
+ return mServiceHelper.startService(serviceName);
+ }
+
+ protected String getPppOptionFilePath() throws IOException {
+ String subpath = getProfileSubpath("/ppp/peers");
+ String[] kids = new File(subpath).list();
+ if ((kids == null) || (kids.length == 0)) {
+ throw new IOException("no option file found in " + subpath);
+ }
+ if (kids.length > 1) {
+ Log.w(TAG, "more than one option file found in " + subpath
+ + ", arbitrarily choose " + kids[0]);
+ }
+ return subpath + "/" + kids[0];
+ }
+
+ /**
+ * Returns the VPN profile associated with the connection.
+ */
+ protected E getProfile() {
+ return mProfile;
+ }
+
+ /**
+ * Returns the profile path where configuration files reside.
+ */
+ protected String getProfilePath() throws IOException {
+ String path = PROFILES_ROOT + mProfile.getId();
+ File dir = new File(path);
+ if (!dir.exists()) throw new IOException("Profile dir does not exist");
+ return path;
+ }
+
+ /**
+ * Returns the path where default configuration files reside.
+ */
+ protected String getDefaultConfigPath() throws IOException {
+ return DEFAULT_CONFIG_PATH;
+ }
+
+ /**
+ * Returns the host IP for establishing the VPN connection.
+ */
+ protected String getHostIp() throws IOException {
+ if (mHostIp == null) mHostIp = reallyGetHostIp();
+ return mHostIp;
+ }
+
+ /**
+ * Returns the IP of the specified host name.
+ */
+ protected String getIp(String hostName) throws IOException {
+ InetAddress iaddr = InetAddress.getByName(hostName);
+ byte[] aa = iaddr.getAddress();
+ StringBuilder sb = new StringBuilder().append(byteToInt(aa[0]));
+ for (int i = 1; i < aa.length; i++) {
+ sb.append(".").append(byteToInt(aa[i]));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns the path of the script file that is executed when the VPN
+ * connection is established.
+ */
+ protected String getConnectMonitorFile() {
+ return "/etc/ppp/ip-up";
+ }
+
+ /**
+ * Sets the system property. The method is blocked until the value is
+ * settled in.
+ * @param name the name of the property
+ * @param value the value of the property
+ * @throws IOException if it fails to set the property within 2 seconds
+ */
+ protected void setSystemProperty(String name, String value)
+ throws IOException {
+ SystemProperties.set(name, value);
+ for (int i = 0; i < 5; i++) {
+ String v = SystemProperties.get(name);
+ if (v.equals(value)) {
+ return;
+ } else {
+ Log.d(TAG, "sys_prop: wait for " + name + " to settle in");
+ sleep(400);
+ }
+ }
+ throw new IOException("Failed to set system property: " + name);
+ }
+
+ void setContext(VpnServiceBinder context, E profile) {
+ mContext = context;
+ mProfile = profile;
+ }
+
+ VpnState getState() {
+ return mState;
+ }
+
+ synchronized void onConnect(String username, String password)
+ throws IOException {
+ mState = VpnState.CONNECTING;
+ broadcastConnectivity(VpnState.CONNECTING);
+
+ String serverIp = getIp(getProfile().getServerName());
+ setSystemProperty(SERVER_IP, serverIp);
+ onBeforeConnect();
+
+ connect(serverIp, username, password);
+ }
+
+ synchronized void onDisconnect(boolean cleanUpServices) {
+ try {
+ mState = VpnState.DISCONNECTING;
+ broadcastConnectivity(VpnState.DISCONNECTING);
+ mNotification.showDisconnect();
+
+ // subclass implementation
+ if (cleanUpServices) disconnect();
+
+ mServiceHelper.stop();
+ } catch (Throwable e) {
+ Log.e(TAG, "onError()", e);
+ onFinalCleanUp();
+ }
+ }
+
+ synchronized void onError() {
+ // error may occur during or after connection setup
+ // and it may be due to one or all services gone
+ mInError = true;
+ switch (mState) {
+ case CONNECTED:
+ onDisconnect(true);
+ break;
+
+ case CONNECTING:
+ onDisconnect(false);
+ break;
+ }
+ }
+
+ private void createConnectMonitor() {
+ mConnectMonitor = new FileMonitor(getConnectMonitorFile(),
+ new Runnable() {
+ public void run() {
+ onConnectMonitorTriggered();
+ }
+ });
+ }
+
+ private void onBeforeConnect() {
+ mNotification.disableNotification();
+
+ createConnectMonitor();
+ mConnectMonitor.startWatching();
+ saveOriginalDnsProperties();
+
+ mWatchdog = startTimer(VPN_TIMEOUT, new Runnable() {
+ public void run() {
+ synchronized (VpnService.this) {
+ if (mState == VpnState.CONNECTING) {
+ Log.d(TAG, " watchdog timer is fired !!");
+ onError();
+ }
+ }
+ }
+ });
+ }
+
+ private synchronized void onConnectMonitorTriggered() {
+ Log.d(TAG, "onConnectMonitorTriggered()");
+
+ stopTimer(mWatchdog);
+ mConnectMonitor.stopWatching();
+ saveVpnDnsProperties();
+ saveAndSetDomainSuffices();
+ startConnectivityMonitor();
+
+ mState = VpnState.CONNECTED;
+ broadcastConnectivity(VpnState.CONNECTED);
+ }
+
+ private synchronized void onFinalCleanUp() {
+ Log.d(TAG, "onFinalCleanUp()");
+
+ if (mState == VpnState.IDLE) return;
+
+ // keep the notification when error occurs
+ if (!mInError) mNotification.disableNotification();
+
+ restoreOriginalDnsProperties();
+ restoreOriginalDomainSuffices();
+ if (mConnectMonitor != null) mConnectMonitor.stopWatching();
+ if (mWatchdog != null) stopTimer(mWatchdog);
+ mState = VpnState.IDLE;
+ broadcastConnectivity(VpnState.IDLE);
+
+ // stop the service itself
+ mContext.stopSelf();
+ }
+
+ private synchronized void onOneServiceGone() {
+ switch (mState) {
+ case IDLE:
+ case DISCONNECTING:
+ break;
+
+ default:
+ onError();
+ }
+ }
+
+ private synchronized void onAllServicesGone() {
+ switch (mState) {
+ case IDLE:
+ break;
+
+ case DISCONNECTING:
+ // daemons are gone; now clean up everything
+ onFinalCleanUp();
+ break;
+
+ default:
+ onError();
+ }
+ }
+
+ private void saveOriginalDnsProperties() {
+ mOriginalDns1 = SystemProperties.get(DNS1);
+ mOriginalDns2 = SystemProperties.get(DNS2);
+ Log.d(TAG, String.format("save original dns prop: %s, %s",
+ mOriginalDns1, mOriginalDns2));
+ }
+
+ private void restoreOriginalDnsProperties() {
+ // restore only if they are not overridden
+ if (mVpnDns1.equals(SystemProperties.get(DNS1))) {
+ Log.d(TAG, String.format("restore original dns prop: %s --> %s",
+ SystemProperties.get(DNS1), mOriginalDns1));
+ Log.d(TAG, String.format("restore original dns prop: %s --> %s",
+ SystemProperties.get(DNS2), mOriginalDns2));
+ SystemProperties.set(DNS1, mOriginalDns1);
+ SystemProperties.set(DNS2, mOriginalDns2);
+ }
+ }
+
+ private void saveVpnDnsProperties() {
+ mVpnDns1 = mVpnDns2 = "";
+ for (int i = 0; i < 10; i++) {
+ mVpnDns1 = SystemProperties.get(DNS1);
+ mVpnDns2 = SystemProperties.get(DNS2);
+ if (mVpnDns1.equals(mOriginalDns1)) {
+ Log.d(TAG, "wait for vpn dns to settle in..." + i);
+ sleep(500);
+ } else {
+ Log.d(TAG, String.format("save vpn dns prop: %s, %s",
+ mVpnDns1, mVpnDns2));
+ return;
+ }
+ }
+ Log.e(TAG, "saveVpnDnsProperties(): DNS not updated??");
+ }
+
+ private void restoreVpnDnsProperties() {
+ if (isNullOrEmpty(mVpnDns1) && isNullOrEmpty(mVpnDns2)) {
+ return;
+ }
+ Log.d(TAG, String.format("restore vpn dns prop: %s --> %s",
+ SystemProperties.get(DNS1), mVpnDns1));
+ Log.d(TAG, String.format("restore vpn dns prop: %s --> %s",
+ SystemProperties.get(DNS2), mVpnDns2));
+ SystemProperties.set(DNS1, mVpnDns1);
+ SystemProperties.set(DNS2, mVpnDns2);
+ }
+
+ private void saveAndSetDomainSuffices() {
+ mOriginalDomainSuffices = SystemProperties.get(DNS_DOMAIN_SUFFICES);
+ Log.d(TAG, "save original dns search: " + mOriginalDomainSuffices);
+ String list = mProfile.getDomainSuffices();
+ if (!isNullOrEmpty(list)) {
+ SystemProperties.set(DNS_DOMAIN_SUFFICES, list);
+ }
+ }
+
+ private void restoreOriginalDomainSuffices() {
+ Log.d(TAG, "restore original dns search --> " + mOriginalDomainSuffices);
+ SystemProperties.set(DNS_DOMAIN_SUFFICES, mOriginalDomainSuffices);
+ }
+
+ private void broadcastConnectivity(VpnState s) {
+ new VpnManager(mContext).broadcastConnectivity(mProfile.getName(), s);
+ }
+
+ private void startConnectivityMonitor() {
+ mStartTime = System.currentTimeMillis();
+
+ new Thread(new Runnable() {
+ public void run() {
+ Log.d(TAG, " +++++ connectivity monitor running");
+ try {
+ for (;;) {
+ synchronized (VpnService.this) {
+ if (mState != VpnState.CONNECTED) break;
+ mNotification.update();
+ checkConnectivity();
+ VpnService.this.wait(ONE_SECOND);
+ }
+ }
+ } catch (InterruptedException e) {
+ Log.e(TAG, "connectivity monitor", e);
+ }
+ Log.d(TAG, " ----- connectivity monitor stopped");
+ }
+ }).start();
+ }
+
+ private void checkConnectivity() {
+ checkDnsProperties();
+ }
+
+ private void checkDnsProperties() {
+ String dns1 = SystemProperties.get(DNS1);
+ if (!mVpnDns1.equals(dns1)) {
+ Log.w(TAG, " @@ !!! dns being overridden");
+ onError();
+ }
+ }
+
+ private Object startTimer(final int milliseconds, final Runnable task) {
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ Log.d(TAG, "watchdog timer started");
+ Thread t = Thread.currentThread();
+ try {
+ synchronized (t) {
+ t.wait(milliseconds);
+ }
+ task.run();
+ } catch (InterruptedException e) {
+ // ignored
+ }
+ Log.d(TAG, "watchdog timer stopped");
+ }
+ });
+ thread.start();
+ return thread;
+ }
+
+ private void stopTimer(Object timer) {
+ synchronized (timer) {
+ timer.notify();
+ }
+ }
+
+ private String reallyGetHostIp() throws IOException {
+ Socket s = new Socket();
+ s.connect(new InetSocketAddress("www.google.com", 80), DNS_TIMEOUT);
+ String ipAddress = s.getLocalAddress().getHostAddress();
+ Log.d(TAG, "Host IP: " + ipAddress);
+ s.close();
+ return ipAddress;
+ }
+
+ private String getProfileSubpath(String subpath) throws IOException {
+ String path = getProfilePath() + subpath;
+ if (new File(path).exists()) {
+ return path;
+ } else {
+ Log.w(TAG, "Profile subpath does not exist: " + path
+ + ", use default one");
+ String path2 = getDefaultConfigPath() + subpath;
+ if (!new File(path2).exists()) {
+ throw new IOException("Profile subpath does not exist at "
+ + path + " or " + path2);
+ }
+ return path2;
+ }
+ }
+
+ private void sleep(int ms) {
+ try {
+ Thread.currentThread().sleep(ms);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ private static boolean isNullOrEmpty(String message) {
+ return ((message == null) || (message.length() == 0));
+ }
+
+ private static int byteToInt(byte b) {
+ return ((int) b) & 0x0FF;
+ }
+
+ private class ServiceHelper implements ProcessProxy.Callback {
+ private List<AndroidServiceProxy> mServiceList =
+ new ArrayList<AndroidServiceProxy>();
+
+ // starts an Android service
+ AndroidServiceProxy startService(String serviceName)
+ throws IOException {
+ AndroidServiceProxy service = new AndroidServiceProxy(serviceName);
+ mServiceList.add(service);
+ service.start(this);
+ return service;
+ }
+
+ // stops all the Android services
+ void stop() {
+ if (mServiceList.isEmpty()) {
+ onFinalCleanUp();
+ } else {
+ for (AndroidServiceProxy s : mServiceList) s.stop();
+ }
+ }
+
+ //@Override
+ public void done(ProcessProxy p) {
+ Log.d(TAG, "service done: " + p.getName());
+ commonCallback((AndroidServiceProxy) p);
+ }
+
+ //@Override
+ public void error(ProcessProxy p, Throwable e) {
+ Log.e(TAG, "service error: " + p.getName(), e);
+ commonCallback((AndroidServiceProxy) p);
+ }
+
+ private void commonCallback(AndroidServiceProxy service) {
+ mServiceList.remove(service);
+ onOneServiceGone();
+ if (mServiceList.isEmpty()) onAllServicesGone();
+ }
+ }
+
+ private class FileMonitor extends FileObserver {
+ private Runnable mCallback;
+
+ FileMonitor(String path, Runnable callback) {
+ super(path, CLOSE_NOWRITE);
+ mCallback = callback;
+ }
+
+ @Override
+ public void onEvent(int event, String path) {
+ if ((event & CLOSE_NOWRITE) > 0) mCallback.run();
+ }
+ }
+
+ // Helper class for showing, updating notification.
+ private class NotificationHelper {
+ void update() {
+ String title = getNotificationTitle(true);
+ Notification n = new Notification(R.drawable.vpn_connected, title,
+ mStartTime);
+ n.setLatestEventInfo(mContext, title,
+ getNotificationMessage(true), prepareNotificationIntent());
+ n.flags |= Notification.FLAG_NO_CLEAR;
+ n.flags |= Notification.FLAG_ONGOING_EVENT;
+ enableNotification(n);
+ }
+
+ void showDisconnect() {
+ String title = getNotificationTitle(false);
+ Notification n = new Notification(R.drawable.vpn_disconnected,
+ title, System.currentTimeMillis());
+ n.setLatestEventInfo(mContext, title,
+ getNotificationMessage(false), prepareNotificationIntent());
+ n.flags |= Notification.FLAG_AUTO_CANCEL;
+ disableNotification();
+ enableNotification(n);
+ }
+
+ void disableNotification() {
+ ((NotificationManager) mContext.getSystemService(
+ Context.NOTIFICATION_SERVICE)).cancel(NOTIFICATION_ID);
+ }
+
+ private void enableNotification(Notification n) {
+ ((NotificationManager) mContext.getSystemService(
+ Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, n);
+ }
+
+ private PendingIntent prepareNotificationIntent() {
+ return PendingIntent.getActivity(mContext, 0,
+ new VpnManager(mContext).createSettingsActivityIntent(), 0);
+ }
+
+ private String getNotificationTitle(boolean connected) {
+ String connectedOrNot = connected
+ ? mContext.getString(R.string.vpn_notification_connected)
+ : mContext.getString(
+ R.string.vpn_notification_disconnected);
+ return String.format(
+ mContext.getString(R.string.vpn_notification_title),
+ mProfile.getName(), connectedOrNot);
+ }
+
+ private String getTimeFormat(long duration) {
+ long hours = duration / 3600;
+ StringBuilder sb = new StringBuilder();
+ if (hours > 0) sb.append(hours).append(':');
+ sb.append(String.format("%02d:%02d", (duration % 3600 / 60),
+ (duration % 60)));
+ return sb.toString();
+ }
+
+ private String getNotificationMessage(boolean connected) {
+ if (connected) {
+ long time = (System.currentTimeMillis() - mStartTime) / 1000;
+ return String.format(mContext.getString(
+ R.string.vpn_notification_connected_message),
+ getTimeFormat(time));
+ } else {
+ return "";
+ }
+ }
+ }
+}
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
new file mode 100644
index 0000000..7195ea6
--- /dev/null
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.app.Service;
+import android.content.Intent;
+import android.net.vpn.IVpnService;
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * The service class for managing a VPN connection. It implements the
+ * {@link IVpnService} binder interface.
+ */
+public class VpnServiceBinder extends Service {
+ private final String TAG = VpnServiceBinder.class.getSimpleName();
+
+ // The actual implementation is delegated to the VpnService class.
+ private VpnService<? extends VpnProfile> mService;
+
+ private final IBinder mBinder = new IVpnService.Stub() {
+ public boolean connect(VpnProfile p, String username, String password) {
+ return VpnServiceBinder.this.connect(p, username, password);
+ }
+
+ public void disconnect() {
+ if (mService != null) mService.onDisconnect(true);
+ }
+
+ public void checkStatus(VpnProfile p) {
+ VpnServiceBinder.this.checkStatus(p);
+ }
+ };
+
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ private synchronized boolean connect(
+ VpnProfile p, String username, String password) {
+ if (mService != null) return false;
+ try {
+ mService = createService(p);
+ mService.onConnect(username, password);
+ return true;
+ } catch (Throwable e) {
+ Log.e(TAG, "connect()", e);
+ if (mService != null) mService.onError();
+ return false;
+ }
+ }
+
+ private synchronized void checkStatus(VpnProfile p) {
+ if (mService == null) broadcastConnectivity(p.getName(), VpnState.IDLE);
+
+ if (!p.getName().equals(mService.mProfile.getName())) {
+ broadcastConnectivity(p.getName(), VpnState.IDLE);
+ } else {
+ broadcastConnectivity(p.getName(), mService.getState());
+ }
+ }
+
+ private VpnService<? extends VpnProfile> createService(VpnProfile p) {
+ switch (p.getType()) {
+ case L2TP_IPSEC:
+ L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
+ l2tpIpsec.setContext(this, (L2tpIpsecProfile) p);
+ return l2tpIpsec;
+
+ case L2TP:
+ L2tpService l2tp = new L2tpService();
+ l2tp.setContext(this, (L2tpProfile) p);
+ return l2tp;
+
+ default:
+ return null;
+ }
+ }
+
+ private void broadcastConnectivity(String name, VpnState s) {
+ new VpnManager(this).broadcastConnectivity(name, s);
+ }
+}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 5770a77..2f964ba 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -25,6 +25,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
@@ -41,16 +43,21 @@ import android.util.Log;
import android.util.SparseArray;
import android.backup.IBackupManager;
+import android.backup.IRestoreSession;
import android.backup.BackupManager;
+import android.backup.RestoreSet;
-import com.android.internal.backup.AdbTransport;
+import com.android.internal.backup.LocalTransport;
import com.android.internal.backup.GoogleTransport;
import com.android.internal.backup.IBackupTransport;
+import java.io.EOFException;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.PrintWriter;
+import java.io.RandomAccessFile;
import java.lang.String;
import java.util.ArrayList;
import java.util.HashMap;
@@ -67,7 +74,11 @@ class BackupManagerService extends IBackupManager.Stub {
private static final int MSG_RUN_BACKUP = 1;
private static final int MSG_RUN_FULL_BACKUP = 2;
-
+ private static final int MSG_RUN_RESTORE = 3;
+
+ // Timeout interval for deciding that a bind or clear-data has taken too long
+ static final long TIMEOUT_INTERVAL = 10 * 1000;
+
private Context mContext;
private PackageManager mPackageManager;
private final IActivityManager mActivityManager;
@@ -105,10 +116,17 @@ class BackupManagerService extends IBackupManager.Stub {
private IBackupAgent mConnectedAgent;
private volatile boolean mConnecting;
+ // A similar synchronicity mechanism around clearing apps' data for restore
+ private final Object mClearDataLock = new Object();
+ private volatile boolean mClearingData;
+
private int mTransportId;
private File mStateDir;
private File mDataDir;
+ private File mJournalDir;
+ private File mJournal;
+ private RandomAccessFile mJournalStream;
public BackupManagerService(Context context) {
mContext = context;
@@ -119,13 +137,24 @@ class BackupManagerService extends IBackupManager.Stub {
mStateDir = new File(Environment.getDataDirectory(), "backup");
mStateDir.mkdirs();
mDataDir = Environment.getDownloadCacheDirectory();
- mTransportId = BackupManager.TRANSPORT_GOOGLE;
+
+ // Set up the backup-request journaling
+ mJournalDir = new File(mStateDir, "pending");
+ mJournalDir.mkdirs();
+ makeJournalLocked(); // okay because no other threads are running yet
+
+ //!!! TODO: default to cloud transport, not local
+ mTransportId = BackupManager.TRANSPORT_LOCAL;
// Build our mapping of uid to backup client services
synchronized (mBackupParticipants) {
addPackageParticipantsLocked(null);
}
+ // Now that we know about valid backup participants, parse any
+ // leftover journal files and schedule a new backup pass
+ parseLeftoverJournals();
+
// Register for broadcasts about package install, etc., so we can
// update the provider list.
IntentFilter filter = new IntentFilter();
@@ -135,6 +164,46 @@ class BackupManagerService extends IBackupManager.Stub {
mContext.registerReceiver(mBroadcastReceiver, filter);
}
+ private void makeJournalLocked() {
+ try {
+ mJournal = File.createTempFile("journal", null, mJournalDir);
+ mJournalStream = new RandomAccessFile(mJournal, "rwd");
+ } catch (IOException e) {
+ Log.e(TAG, "Unable to write backup journals");
+ mJournal = null;
+ mJournalStream = null;
+ }
+ }
+
+ private void parseLeftoverJournals() {
+ if (mJournal != null) {
+ File[] allJournals = mJournalDir.listFiles();
+ for (File f : allJournals) {
+ if (f.compareTo(mJournal) != 0) {
+ // This isn't the current journal, so it must be a leftover. Read
+ // out the package names mentioned there and schedule them for
+ // backup.
+ try {
+ Log.i(TAG, "Found stale backup journal, scheduling:");
+ RandomAccessFile in = new RandomAccessFile(f, "r");
+ while (true) {
+ String packageName = in.readUTF();
+ Log.i(TAG, " + " + packageName);
+ dataChanged(packageName);
+ }
+ } catch (EOFException e) {
+ // no more data; we're done
+ } catch (Exception e) {
+ // can't read it or other error; just skip it
+ } finally {
+ // close/delete the file
+ f.delete();
+ }
+ }
+ }
+ }
+ }
+
// ----- Track installation/removal of packages -----
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
@@ -149,8 +218,6 @@ class BackupManagerService extends IBackupManager.Stub {
return;
}
- // !!! TODO: this is buggy right now; we wind up with duplicate participant entries
- // after using 'adb install -r' of a participating app
String action = intent.getAction();
if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
synchronized (mBackupParticipants) {
@@ -185,7 +252,13 @@ class BackupManagerService extends IBackupManager.Stub {
switch (msg.what) {
case MSG_RUN_BACKUP:
// snapshot the pending-backup set and work on that
+ File oldJournal = mJournal;
synchronized (mQueueLock) {
+ if (mPendingBackups.size() == 0) {
+ Log.v(TAG, "Backup requested but nothing pending");
+ break;
+ }
+
if (mBackupQueue == null) {
mBackupQueue = new ArrayList<BackupRequest>();
for (BackupRequest b: mPendingBackups.values()) {
@@ -193,82 +266,37 @@ class BackupManagerService extends IBackupManager.Stub {
}
mPendingBackups = new HashMap<ApplicationInfo,BackupRequest>();
}
- // !!! TODO: start a new backup-queue journal file too
- // WARNING: If we crash after this line, anything in mPendingBackups will
- // be lost. FIX THIS.
+
+ // Start a new backup-queue journal file too
+ if (mJournalStream != null) {
+ try {
+ mJournalStream.close();
+ } catch (IOException e) {
+ // don't need to do anything
+ }
+ makeJournalLocked();
+ }
+
+ // At this point, we have started a new journal file, and the old
+ // file identity is being passed to the backup processing thread.
+ // When it completes successfully, that old journal file will be
+ // deleted. If we crash prior to that, the old journal is parsed
+ // at next boot and the journaled requests fulfilled.
}
- (new PerformBackupThread(mTransportId, mBackupQueue)).run();
+ (new PerformBackupThread(mTransportId, mBackupQueue, oldJournal)).run();
break;
case MSG_RUN_FULL_BACKUP:
break;
- }
- }
- }
- void processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport) {
- final String packageName = request.appInfo.packageName;
- Log.d(TAG, "processOneBackup doBackup() on " + packageName);
-
- try {
- // !!! TODO: get the state file dir from the transport
- File savedStateName = new File(mStateDir, packageName);
- File backupDataName = new File(mDataDir, packageName + ".data");
- File newStateName = new File(mStateDir, packageName + ".new");
-
- // In a full backup, we pass a null ParcelFileDescriptor as
- // the saved-state "file"
- ParcelFileDescriptor savedState = (request.fullBackup) ? null
- : ParcelFileDescriptor.open(savedStateName,
- ParcelFileDescriptor.MODE_READ_ONLY |
- ParcelFileDescriptor.MODE_CREATE);
-
- backupDataName.delete();
- ParcelFileDescriptor backupData =
- ParcelFileDescriptor.open(backupDataName,
- ParcelFileDescriptor.MODE_READ_WRITE |
- ParcelFileDescriptor.MODE_CREATE);
-
- newStateName.delete();
- ParcelFileDescriptor newState =
- ParcelFileDescriptor.open(newStateName,
- ParcelFileDescriptor.MODE_READ_WRITE |
- ParcelFileDescriptor.MODE_CREATE);
-
- // Run the target's backup pass
- boolean success = false;
- try {
- agent.doBackup(savedState, backupData, newState);
- success = true;
- } finally {
- if (savedState != null) {
- savedState.close();
- }
- backupData.close();
- newState.close();
- }
-
- // Now propagate the newly-backed-up data to the transport
- if (success) {
- if (DEBUG) Log.v(TAG, "doBackup() success; calling transport");
- backupData =
- ParcelFileDescriptor.open(backupDataName, ParcelFileDescriptor.MODE_READ_ONLY);
- int error = transport.performBackup(packageName, backupData);
-
- // !!! TODO: After successful transport, delete the now-stale data
- // and juggle the files so that next time the new state is passed
- //backupDataName.delete();
- newStateName.renameTo(savedStateName);
- }
- } catch (FileNotFoundException fnf) {
- Log.d(TAG, "File not found on backup: ");
- fnf.printStackTrace();
- } catch (RemoteException e) {
- Log.d(TAG, "Remote target " + request.appInfo.packageName + " threw during backup:");
- e.printStackTrace();
- } catch (Exception e) {
- Log.w(TAG, "Final exception guard in backup: ");
- e.printStackTrace();
+ case MSG_RUN_RESTORE:
+ {
+ int token = msg.arg1;
+ IBackupTransport transport = (IBackupTransport)msg.obj;
+ (new PerformRestoreThread(transport, token)).run();
+ break;
+ }
+ }
}
}
@@ -337,7 +365,14 @@ class BackupManagerService extends IBackupManager.Stub {
int uid = app.uid;
HashSet<ApplicationInfo> set = mBackupParticipants.get(uid);
if (set != null) {
- set.remove(app);
+ // Find the existing entry with the same package name, and remove it.
+ // We can't just remove(app) because the instances are different.
+ for (ApplicationInfo entry: set) {
+ if (entry.packageName.equals(app.packageName)) {
+ set.remove(entry);
+ break;
+ }
+ }
if (set.size() == 0) {
mBackupParticipants.delete(uid); }
}
@@ -352,7 +387,8 @@ class BackupManagerService extends IBackupManager.Stub {
if (N > 0) {
for (int a = N-1; a >= 0; a--) {
ApplicationInfo app = allApps.get(a);
- if (app.backupAgentName == null) {
+ if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
+ || app.backupAgentName == null) {
allApps.remove(a);
}
}
@@ -375,57 +411,126 @@ class BackupManagerService extends IBackupManager.Stub {
addPackageParticipantsLockedInner(packageName, allApps);
}
+ // Instantiate the given transport
+ private IBackupTransport createTransport(int transportID) {
+ IBackupTransport transport = null;
+ switch (transportID) {
+ case BackupManager.TRANSPORT_LOCAL:
+ if (DEBUG) Log.v(TAG, "Initializing local transport");
+ transport = new LocalTransport(mContext);
+ break;
+
+ case BackupManager.TRANSPORT_GOOGLE:
+ if (DEBUG) Log.v(TAG, "Initializing Google transport");
+ //!!! TODO: stand up the google backup transport for real here
+ transport = new GoogleTransport();
+ break;
+
+ default:
+ Log.e(TAG, "creating unknown transport " + transportID);
+ }
+ return transport;
+ }
+
+ // fire off a backup agent, blocking until it attaches or times out
+ IBackupAgent bindToAgentSynchronous(ApplicationInfo app, int mode) {
+ IBackupAgent agent = null;
+ synchronized(mAgentConnectLock) {
+ mConnecting = true;
+ mConnectedAgent = null;
+ try {
+ if (mActivityManager.bindBackupAgent(app, mode)) {
+ Log.d(TAG, "awaiting agent for " + app);
+
+ // success; wait for the agent to arrive
+ // only wait 10 seconds for the clear data to happen
+ long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+ while (mConnecting && mConnectedAgent == null
+ && (System.currentTimeMillis() < timeoutMark)) {
+ try {
+ mAgentConnectLock.wait(5000);
+ } catch (InterruptedException e) {
+ // just bail
+ return null;
+ }
+ }
+
+ // if we timed out with no connect, abort and move on
+ if (mConnecting == true) {
+ Log.w(TAG, "Timeout waiting for agent " + app);
+ return null;
+ }
+ agent = mConnectedAgent;
+ }
+ } catch (RemoteException e) {
+ // can't happen
+ }
+ }
+ return agent;
+ }
+
+ // clear an application's data, blocking until the operation completes or times out
+ void clearApplicationDataSynchronous(String packageName) {
+ ClearDataObserver observer = new ClearDataObserver();
+
+ synchronized(mClearDataLock) {
+ mClearingData = true;
+ mPackageManager.clearApplicationUserData(packageName, observer);
+
+ // only wait 10 seconds for the clear data to happen
+ long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+ while (mClearingData && (System.currentTimeMillis() < timeoutMark)) {
+ try {
+ mClearDataLock.wait(5000);
+ } catch (InterruptedException e) {
+ // won't happen, but still.
+ mClearingData = false;
+ }
+ }
+ }
+ }
+
+ class ClearDataObserver extends IPackageDataObserver.Stub {
+ public void onRemoveCompleted(String packageName, boolean succeeded)
+ throws android.os.RemoteException {
+ synchronized(mClearDataLock) {
+ mClearingData = false;
+ notifyAll();
+ }
+ }
+ }
+
// ----- Back up a set of applications via a worker thread -----
class PerformBackupThread extends Thread {
private static final String TAG = "PerformBackupThread";
int mTransport;
ArrayList<BackupRequest> mQueue;
+ File mJournal;
- public PerformBackupThread(int transportId, ArrayList<BackupRequest> queue) {
+ public PerformBackupThread(int transportId, ArrayList<BackupRequest> queue,
+ File journal) {
mTransport = transportId;
mQueue = queue;
+ mJournal = journal;
}
@Override
public void run() {
- /*
- * 1. start up the current transport
- * 2. for each item in the queue:
- * 2a. bind the agent [wait for async attach]
- * 2b. set up the files and call doBackup()
- * 2c. unbind the agent
- * 3. tear down the transport
- * 4. done!
- */
if (DEBUG) Log.v(TAG, "Beginning backup of " + mQueue.size() + " targets");
// stand up the current transport
- IBackupTransport transport = null;
- switch (mTransport) {
- case BackupManager.TRANSPORT_ADB:
- if (DEBUG) Log.v(TAG, "Initializing adb transport");
- transport = new AdbTransport();
- break;
-
- case BackupManager.TRANSPORT_GOOGLE:
- if (DEBUG) Log.v(TAG, "Initializing Google transport");
- //!!! TODO: stand up the google backup transport here
- transport = new GoogleTransport();
- break;
-
- default:
- Log.e(TAG, "Perform backup with unknown transport " + mTransport);
- // !!! TODO: re-enqueue the backup queue for later?
+ IBackupTransport transport = createTransport(mTransport);
+ if (transport == null) {
return;
}
+ // start up the transport
try {
transport.startSession();
} catch (Exception e) {
- Log.e(TAG, "Error starting backup session");
+ Log.e(TAG, "Error session transport");
e.printStackTrace();
- // !!! TODO: re-enqueue the backup queue for later?
return;
}
@@ -439,66 +544,305 @@ class BackupManagerService extends IBackupManager.Stub {
Log.e(TAG, "Error ending transport");
e.printStackTrace();
}
+
+ if (!mJournal.delete()) {
+ Log.e(TAG, "Unable to remove backup journal file " + mJournal.getAbsolutePath());
+ }
}
private void doQueuedBackups(IBackupTransport transport) {
for (BackupRequest request : mQueue) {
- Log.d(TAG, "starting agent for " + request);
- // !!! TODO: need to handle the restore case?
+ Log.d(TAG, "starting agent for backup of " + request);
IBackupAgent agent = null;
int mode = (request.fullBackup)
? IApplicationThread.BACKUP_MODE_FULL
: IApplicationThread.BACKUP_MODE_INCREMENTAL;
try {
- synchronized(mAgentConnectLock) {
- mConnecting = true;
- mConnectedAgent = null;
- if (mActivityManager.bindBackupAgent(request.appInfo, mode)) {
- Log.d(TAG, "awaiting agent for " + request);
-
- // success; wait for the agent to arrive
- while (mConnecting && mConnectedAgent == null) {
- try {
- mAgentConnectLock.wait(10000);
- } catch (InterruptedException e) {
- // just retry
- continue;
- }
- }
+ agent = bindToAgentSynchronous(request.appInfo, mode);
+ if (agent != null) {
+ processOneBackup(request, agent, transport);
+ }
+
+ // unbind even on timeout, just in case
+ mActivityManager.unbindBackupAgent(request.appInfo);
+ } catch (SecurityException ex) {
+ // Try for the next one.
+ Log.d(TAG, "error in bind/backup", ex);
+ } catch (RemoteException e) {
+ Log.v(TAG, "bind/backup threw");
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ void processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport) {
+ final String packageName = request.appInfo.packageName;
+ Log.d(TAG, "processOneBackup doBackup() on " + packageName);
+
+ try {
+ // Look up the package info & signatures. This is first so that if it
+ // throws an exception, there's no file setup yet that would need to
+ // be unraveled.
+ PackageInfo packInfo = mPackageManager.getPackageInfo(packageName,
+ PackageManager.GET_SIGNATURES);
+
+ // !!! TODO: get the state file dir from the transport
+ File savedStateName = new File(mStateDir, packageName);
+ File backupDataName = new File(mDataDir, packageName + ".data");
+ File newStateName = new File(mStateDir, packageName + ".new");
+
+ // In a full backup, we pass a null ParcelFileDescriptor as
+ // the saved-state "file"
+ ParcelFileDescriptor savedState = (request.fullBackup) ? null
+ : ParcelFileDescriptor.open(savedStateName,
+ ParcelFileDescriptor.MODE_READ_ONLY |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ backupDataName.delete();
+ ParcelFileDescriptor backupData =
+ ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ newStateName.delete();
+ ParcelFileDescriptor newState =
+ ParcelFileDescriptor.open(newStateName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ // Run the target's backup pass
+ boolean success = false;
+ try {
+ agent.doBackup(savedState, backupData, newState);
+ success = true;
+ } finally {
+ if (savedState != null) {
+ savedState.close();
+ }
+ backupData.close();
+ newState.close();
+ }
+
+ // Now propagate the newly-backed-up data to the transport
+ if (success) {
+ if (DEBUG) Log.v(TAG, "doBackup() success; calling transport");
+ backupData =
+ ParcelFileDescriptor.open(backupDataName, ParcelFileDescriptor.MODE_READ_ONLY);
+ int error = transport.performBackup(packInfo, backupData);
+
+ // !!! TODO: After successful transport, delete the now-stale data
+ // and juggle the files so that next time the new state is passed
+ //backupDataName.delete();
+ newStateName.renameTo(savedStateName);
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Package not found on backup: " + packageName);
+ } catch (FileNotFoundException fnf) {
+ Log.w(TAG, "File not found on backup: ");
+ fnf.printStackTrace();
+ } catch (RemoteException e) {
+ Log.d(TAG, "Remote target " + request.appInfo.packageName + " threw during backup:");
+ e.printStackTrace();
+ } catch (Exception e) {
+ Log.w(TAG, "Final exception guard in backup: ");
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+ // ----- Restore handling -----
+
+ // Is the given package restorable on this device? Returns the on-device app's
+ // ApplicationInfo struct if it is; null if not.
+ //
+ // !!! TODO: also consider signatures
+ PackageInfo isRestorable(PackageInfo packageInfo) {
+ if (packageInfo.packageName != null) {
+ try {
+ PackageInfo app = mPackageManager.getPackageInfo(packageInfo.packageName,
+ PackageManager.GET_SIGNATURES);
+ if ((app.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
+ return app;
+ }
+ } catch (Exception e) {
+ // doesn't exist on this device, or other error -- just ignore it.
+ }
+ }
+ return null;
+ }
+
+ class PerformRestoreThread extends Thread {
+ private IBackupTransport mTransport;
+ private int mToken;
+ private RestoreSet mImage;
+
+ PerformRestoreThread(IBackupTransport transport, int restoreSetToken) {
+ mTransport = transport;
+ mToken = restoreSetToken;
+ }
+
+ @Override
+ public void run() {
+ /**
+ * Restore sequence:
+ *
+ * 1. start up the transport session
+ * 2. get the restore set description for our identity
+ * 3. for each app in the restore set:
+ * 3.a. if it's restorable on this device, add it to the restore queue
+ * 4. for each app in the restore queue:
+ * 4.a. clear the app data
+ * 4.b. get the restore data for the app from the transport
+ * 4.c. launch the backup agent for the app
+ * 4.d. agent.doRestore() with the data from the server
+ * 4.e. unbind the agent [and kill the app?]
+ * 5. shut down the transport
+ */
+
+ int err = -1;
+ try {
+ err = mTransport.startSession();
+ } catch (Exception e) {
+ Log.e(TAG, "Error starting transport for restore");
+ e.printStackTrace();
+ }
+
+ if (err == 0) {
+ // build the set of apps to restore
+ try {
+ RestoreSet[] images = mTransport.getAvailableRestoreSets();
+ if (images.length > 0) {
+ // !!! TODO: pick out the set for this token
+ mImage = images[0];
- // if we timed out with no connect, abort and move on
- if (mConnecting == true) {
- Log.w(TAG, "Timeout waiting for agent " + request);
- continue;
+ // build the set of apps we will attempt to restore
+ PackageInfo[] packages = mTransport.getAppSet(mImage.token);
+ HashSet<PackageInfo> appsToRestore = new HashSet<PackageInfo>();
+ for (PackageInfo pkg: packages) {
+ // get the real PackageManager idea of the package
+ PackageInfo app = isRestorable(pkg);
+ if (app != null) {
+ appsToRestore.add(app);
}
- agent = mConnectedAgent;
}
+
+ // now run the restore queue
+ doQueuedRestores(appsToRestore);
}
} catch (RemoteException e) {
- // can't happen; activity manager is local
+ // can't happen; transports run locally
+ }
+
+ // done; shut down the transport
+ try {
+ mTransport.endSession();
+ } catch (Exception e) {
+ Log.e(TAG, "Error ending transport for restore");
+ e.printStackTrace();
+ }
+ }
+
+ // even if the initial session startup failed, report that we're done here
+ }
+
+ // restore each app in the queue
+ void doQueuedRestores(HashSet<PackageInfo> appsToRestore) {
+ for (PackageInfo app : appsToRestore) {
+ Log.d(TAG, "starting agent for restore of " + app);
+
+ try {
+ // Remove the app's data first
+ clearApplicationDataSynchronous(app.packageName);
+
+ // Now perform the restore into the clean app
+ IBackupAgent agent = bindToAgentSynchronous(app.applicationInfo,
+ IApplicationThread.BACKUP_MODE_RESTORE);
+ if (agent != null) {
+ processOneRestore(app, agent);
+ }
+
+ // unbind even on timeout, just in case
+ mActivityManager.unbindBackupAgent(app.applicationInfo);
} catch (SecurityException ex) {
// Try for the next one.
Log.d(TAG, "error in bind", ex);
+ } catch (RemoteException e) {
+ // can't happen
}
- // successful bind? run the backup for this agent
- if (agent != null) {
- processOneBackup(request, agent, transport);
- }
+ }
+ }
+
+ // Do the guts of a restore of one application, derived from the 'mImage'
+ // restore set via the 'mTransport' transport.
+ void processOneRestore(PackageInfo app, IBackupAgent agent) {
+ // !!! TODO: actually run the restore through mTransport
+ final String packageName = app.packageName;
- // send the unbind even on timeout, just in case
+ // !!! TODO: get the dirs from the transport
+ File backupDataName = new File(mDataDir, packageName + ".restore");
+ backupDataName.delete();
+ try {
+ ParcelFileDescriptor backupData =
+ ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ // Run the transport's restore pass
+ // Run the target's backup pass
+ int err = -1;
try {
- mActivityManager.unbindBackupAgent(request.appInfo);
+ err = mTransport.getRestoreData(mImage.token, app, backupData);
} catch (RemoteException e) {
// can't happen
+ } finally {
+ backupData.close();
+ }
+
+ // Okay, we have the data. Now have the agent do the restore.
+ File newStateName = new File(mStateDir, packageName + ".new");
+ ParcelFileDescriptor newState =
+ ParcelFileDescriptor.open(newStateName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ backupData = ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+
+ boolean success = false;
+ try {
+ agent.doRestore(backupData, newState);
+ success = true;
+ } catch (Exception e) {
+ Log.e(TAG, "Restore failed for " + packageName);
+ e.printStackTrace();
+ } finally {
+ newState.close();
+ backupData.close();
+ }
+
+ // if everything went okay, remember the recorded state now
+ if (success) {
+ File savedStateName = new File(mStateDir, packageName);
+ newStateName.renameTo(savedStateName);
}
+ } catch (FileNotFoundException fnfe) {
+ Log.v(TAG, "Couldn't open file for restore: " + fnfe);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Unable to process restore file: " + ioe);
+ } catch (Exception e) {
+ Log.e(TAG, "Final exception guard in restore:");
+ e.printStackTrace();
}
}
}
+
// ----- IBackupManager binder interface -----
-
+
public void dataChanged(String packageName) throws RemoteException {
// Record that we need a backup pass for the caller. Since multiple callers
// may share a uid, we need to note all candidates within that uid and schedule
@@ -518,7 +862,9 @@ class BackupManagerService extends IBackupManager.Stub {
// one already there, then overwrite it, but no harm done.
BackupRequest req = new BackupRequest(app, false);
mPendingBackups.put(app, req);
- // !!! TODO: write to the pending-backup journal file in case of crash
+
+ // Journal this request in case of crash
+ writeToJournalLocked(packageName);
}
}
@@ -535,27 +881,41 @@ class BackupManagerService extends IBackupManager.Stub {
mBackupHandler.removeMessages(MSG_RUN_BACKUP);
mBackupHandler.sendEmptyMessageDelayed(MSG_RUN_BACKUP, COLLECTION_INTERVAL);
}
+ } else {
+ Log.w(TAG, "dataChanged but no participant pkg " + packageName);
}
}
- // Schedule a backup pass for a given package. This method will schedule a
- // full backup even for apps that do not declare an android:backupAgent, so
- // use with care.
- public void scheduleFullBackup(String packageName) throws RemoteException {
- mContext.enforceCallingPermission("android.permission.BACKUP", "scheduleFullBackup");
-
- if (DEBUG) Log.v(TAG, "Scheduling immediate full backup for " + packageName);
- synchronized (mQueueLock) {
+ private void writeToJournalLocked(String str) {
+ if (mJournalStream != null) {
try {
- ApplicationInfo app = mPackageManager.getApplicationInfo(packageName, 0);
- mPendingBackups.put(app, new BackupRequest(app, true));
- mBackupHandler.sendEmptyMessage(MSG_RUN_FULL_BACKUP);
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Could not find app for " + packageName + " to schedule full backup");
+ mJournalStream.writeUTF(str);
+ } catch (IOException e) {
+ Log.e(TAG, "Error writing to backup journal");
+ mJournalStream = null;
+ mJournal = null;
}
}
}
+ // Run a backup pass immediately for any applications that have declared
+ // that they have pending updates.
+ public void backupNow() throws RemoteException {
+ mContext.enforceCallingPermission("android.permission.BACKUP", "tryBackupNow");
+
+ if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass");
+ synchronized (mQueueLock) {
+ mBackupHandler.removeMessages(MSG_RUN_BACKUP);
+ mBackupHandler.sendEmptyMessage(MSG_RUN_BACKUP);
+ }
+ }
+
+ // Report the currently active transport
+ public int getCurrentTransport() {
+ mContext.enforceCallingPermission("android.permission.BACKUP", "selectBackupTransport");
+ return mTransportId;
+ }
+
// Select which transport to use for the next backup operation
public int selectBackupTransport(int transportId) {
mContext.enforceCallingPermission("android.permission.BACKUP", "selectBackupTransport");
@@ -599,6 +959,60 @@ class BackupManagerService extends IBackupManager.Stub {
}
}
+ // Hand off a restore session
+ public IRestoreSession beginRestoreSession(int transportID) {
+ mContext.enforceCallingPermission("android.permission.BACKUP", "beginRestoreSession");
+ return null;
+ }
+
+ // ----- Restore session -----
+
+ class RestoreSession extends IRestoreSession.Stub {
+ private IBackupTransport mRestoreTransport = null;
+ RestoreSet[] mRestoreSets = null;
+
+ RestoreSession(int transportID) {
+ mRestoreTransport = createTransport(transportID);
+ }
+
+ // --- Binder interface ---
+ public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
+ mContext.enforceCallingPermission("android.permission.BACKUP",
+ "getAvailableRestoreSets");
+
+ synchronized(this) {
+ if (mRestoreSets == null) {
+ mRestoreSets = mRestoreTransport.getAvailableRestoreSets();
+ }
+ return mRestoreSets;
+ }
+ }
+
+ public int performRestore(int token) throws android.os.RemoteException {
+ mContext.enforceCallingPermission("android.permission.BACKUP", "performRestore");
+
+ if (mRestoreSets != null) {
+ for (int i = 0; i < mRestoreSets.length; i++) {
+ if (token == mRestoreSets[i].token) {
+ Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE,
+ mRestoreTransport);
+ msg.arg1 = token;
+ mBackupHandler.sendMessage(msg);
+ return 0;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public void endRestoreSession() throws android.os.RemoteException {
+ mContext.enforceCallingPermission("android.permission.BACKUP",
+ "endRestoreSession");
+
+ mRestoreTransport.endSession();
+ mRestoreTransport = null;
+ }
+ }
@Override
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 147a085..fc37290 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -65,15 +65,12 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
-import android.util.Config;
import android.util.Log;
import android.util.PrintWriterPrinter;
-import android.util.SparseIntArray;
import com.android.internal.location.GpsLocationProvider;
import com.android.internal.location.LocationProviderProxy;
import com.android.internal.location.MockProvider;
-import com.android.server.am.BatteryStatsService;
/**
* The service class that manages LocationProviders and issues location
@@ -772,8 +769,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {
if (deadReceivers == null) {
deadReceivers = new ArrayList<Receiver>();
- deadReceivers.add(record.mReceiver);
}
+ deadReceivers.add(record.mReceiver);
}
listeners++;
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index dcc3ed5..d98738a 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -58,6 +58,8 @@ import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -259,6 +261,7 @@ class PackageManagerService extends IPackageManager.Stub {
final ResolveInfo mResolveInfo = new ResolveInfo();
ComponentName mResolveComponentName;
PackageParser.Package mPlatformPackage;
+ private boolean mCompatibilityModeEnabled = true;
public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
@@ -509,7 +512,7 @@ class PackageManagerService extends IPackageManager.Stub {
} // synchronized (mPackages)
} // synchronized (mInstallLock)
}
-
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -885,7 +888,11 @@ class PackageManagerService extends IPackageManager.Stub {
+ ": " + p);
if (p != null) {
// Note: isEnabledLP() does not apply here - always return info
- return PackageParser.generateApplicationInfo(p, flags);
+ ApplicationInfo appInfo = PackageParser.generateApplicationInfo(p, flags);
+ if (!mCompatibilityModeEnabled) {
+ appInfo.disableCompatibilityMode();
+ }
+ return appInfo;
}
if ("android".equals(packageName)||"system".equals(packageName)) {
return mAndroidApplication;
@@ -952,10 +959,35 @@ class PackageManagerService extends IPackageManager.Stub {
public ActivityInfo getActivityInfo(ComponentName component, int flags) {
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
- if (Config.LOGV) Log.v(
- TAG, "getActivityInfo " + component + ": " + a);
+
+ if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLP(a.info, flags)) {
- return PackageParser.generateActivityInfo(a, flags);
+ ActivityInfo ainfo = PackageParser.generateActivityInfo(a, flags);
+ if (ainfo != null && (flags & PackageManager.GET_EXPANDABLE) != 0) {
+ ApplicationInfo appInfo = getApplicationInfo(component.getPackageName(),
+ PackageManager.GET_EXPANDABLE | PackageManager.GET_SUPPORTS_DENSITIES);
+ if (appInfo != null && !appInfo.expandable) {
+ // Check if the screen size is same as what the application expect.
+ CompatibilityInfo info = new CompatibilityInfo(appInfo);
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setTo(mMetrics);
+ int orientation = mMetrics.widthPixels > mMetrics.heightPixels ?
+ Configuration.ORIENTATION_LANDSCAPE :
+ Configuration.ORIENTATION_PORTRAIT;
+ metrics.updateMetrics(info, orientation);
+ if (!info.mExpandable) {
+ // Don't allow an app that cannot expand to handle rotation.
+ ainfo.configChanges &= ~ ActivityInfo.CONFIG_ORIENTATION;
+ } else {
+ appInfo.expandable = true;
+ }
+ if (DEBUG_SETTINGS) {
+ Log.d(TAG, "component=" + component +
+ ", expandable:" + appInfo.expandable);
+ }
+ }
+ }
+ return ainfo;
}
if (mResolveComponentName.equals(component)) {
return mResolveActivity;
@@ -4712,6 +4744,14 @@ class PackageManagerService extends IPackageManager.Stub {
public void systemReady() {
mSystemReady = true;
+
+ // Read the compatibilty setting when the system is ready.
+ mCompatibilityModeEnabled = android.provider.Settings.System.getInt(
+ mContext.getContentResolver(),
+ android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
+ if (DEBUG_SETTINGS) {
+ Log.d(TAG, "compatibility mode:" + mCompatibilityModeEnabled);
+ }
}
public boolean isSafeMode() {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c82b49a..36fc5bb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -173,7 +173,7 @@ class ServerThread extends Thread {
bluetooth = new BluetoothDeviceService(context);
bluetooth.init();
ServiceManager.addService(Context.BLUETOOTH_SERVICE, bluetooth);
- bluetoothA2dp = new BluetoothA2dpService(context);
+ bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
bluetoothA2dp);
@@ -414,19 +414,19 @@ public class SystemServer
public static final int FACTORY_TEST_OFF = 0;
public static final int FACTORY_TEST_LOW_LEVEL = 1;
public static final int FACTORY_TEST_HIGH_LEVEL = 2;
-
- /**
- * This method is called from Zygote to initialize the system. This will cause the native
+
+ /**
+ * This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
- */
+ */
native public static void init1(String[] args);
public static void main(String[] args) {
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
-
+
System.loadLibrary("android_servers");
init1(args);
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5bded50..969fbfe 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1060,6 +1060,83 @@ public class WifiService extends IWifiManager.Stub {
break setVariables;
}
+ if ((config.eap != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.eapVarName,
+ config.eap)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set eap: "+
+ config.eap);
+ }
+ break setVariables;
+ }
+
+ if ((config.identity != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.identityVarName,
+ config.identity)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set identity: "+
+ config.identity);
+ }
+ break setVariables;
+ }
+
+ if ((config.anonymousIdentity != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.anonymousIdentityVarName,
+ config.anonymousIdentity)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set anonymousIdentity: "+
+ config.anonymousIdentity);
+ }
+ break setVariables;
+ }
+
+ if ((config.clientCert != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.clientCertVarName,
+ config.clientCert)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set clientCert: "+
+ config.clientCert);
+ }
+ break setVariables;
+ }
+
+ if ((config.caCert != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.caCertVarName,
+ config.caCert)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set caCert: "+
+ config.caCert);
+ }
+ break setVariables;
+ }
+
+ if ((config.privateKey != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.privateKeyVarName,
+ config.privateKey)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set privateKey: "+
+ config.privateKey);
+ }
+ break setVariables;
+ }
+
+ if ((config.privateKeyPasswd != null) && !WifiNative.setNetworkVariableCommand(
+ netId,
+ WifiConfiguration.privateKeyPasswdVarName,
+ config.privateKeyPasswd)) {
+ if (DBG) {
+ Log.d(TAG, config.SSID + ": failed to set privateKeyPasswd: "+
+ config.privateKeyPasswd);
+ }
+ break setVariables;
+ }
+
return netId;
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 4561e1a..975c8209 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -140,12 +140,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
static final boolean PROFILE_ORIENTATION = false;
static final boolean BLUR = true;
static final boolean localLOGV = DEBUG;
-
+
static final int LOG_WM_NO_SURFACE_MEMORY = 31000;
-
+
/** How long to wait for first key repeat, in milliseconds */
static final int KEY_REPEAT_FIRST_DELAY = 750;
-
+
/** How long to wait for subsequent key repeats, in milliseconds */
static final int KEY_REPEAT_DELAY = 50;
@@ -153,16 +153,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* for multiple windows of the same type and Z-ordering adjustment
* with TYPE_LAYER_OFFSET. */
static final int TYPE_LAYER_MULTIPLIER = 10000;
-
+
/** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
* or below others in the same layer. */
static final int TYPE_LAYER_OFFSET = 1000;
-
+
/** How much to increment the layer for each window, to reserve room
* for effect surfaces between them.
*/
static final int WINDOW_LAYER_MULTIPLIER = 5;
-
+
/** The maximum length we will accept for a loaded animation duration:
* this is 10 seconds.
*/
@@ -176,21 +176,25 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
/** Adjustment to time to perform a dim, to make it more dramatic.
*/
static final int DIM_DURATION_MULTIPLIER = 6;
+
+ static final int INJECT_FAILED = 0;
+ static final int INJECT_SUCCEEDED = 1;
+ static final int INJECT_NO_PERMISSION = -1;
static final int UPDATE_FOCUS_NORMAL = 0;
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
-
+
/** The minimum time between dispatching touch events. */
int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
// Last touch event time
long mLastTouchEventTime = 0;
-
+
// Last touch event type
int mLastTouchEventType = OTHER_EVENT;
-
+
// Time to wait before calling useractivity again. This saves CPU usage
// when we get a flood of touch events.
static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
@@ -198,10 +202,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Last time we call user activity
long mLastUserActivityCallTime = 0;
- // Last time we updated battery stats
+ // Last time we updated battery stats
long mLastBatteryStatsCallTime = 0;
-
+
private static final String SYSTEM_SECURE = "ro.secure";
+ private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
/**
* Condition waited on by {@link #reenableKeyguard} to know the call to
@@ -227,20 +232,20 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
final Context mContext;
final boolean mHaveInputMethods;
-
+
final boolean mLimitedAlphaCompositing;
-
+
final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
final IActivityManager mActivityManager;
-
+
final IBatteryStats mBatteryStats;
-
+
/**
* All currently active sessions with clients.
*/
final HashSet<Session> mSessions = new HashSet<Session>();
-
+
/**
* Mapping from an IWindow IBinder to the server's Window object.
* This is also used as the lock for all of our state.
@@ -258,7 +263,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* over them.
*/
final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
-
+
/**
* Window tokens that are in the process of exiting, but still
* on screen for animations.
@@ -317,9 +322,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* list or contain windows that need to be force removed.
*/
ArrayList<WindowState> mForceRemoves;
-
+
IInputMethodManager mInputMethodManager;
-
+
SurfaceSession mFxSession;
Surface mDimSurface;
boolean mDimShown;
@@ -329,9 +334,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
long mLastDimAnimTime;
Surface mBlurSurface;
boolean mBlurShown;
-
+
int mTransactionSequence = 0;
-
+
final float[] mTmpFloats = new float[9];
boolean mSafeMode;
@@ -343,7 +348,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int mLastRotationFlags;
ArrayList<IRotationWatcher> mRotationWatchers
= new ArrayList<IRotationWatcher>();
-
+
boolean mLayoutNeeded = true;
boolean mAnimationPending = false;
boolean mDisplayFrozen = false;
@@ -355,7 +360,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// perform a rotation animation when turning off shows the lock screen which
// changes the orientation.
PowerManager.WakeLock mScreenFrozenLock;
-
+
// State management of app transitions. When we are preparing for a
// transition, mNextAppTransition will be the kind of transition to
// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
@@ -368,40 +373,40 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean mSkipAppTransitionAnimation = false;
final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
-
+
//flag to detect fat touch events
boolean mFatTouch = false;
Display mDisplay;
-
+
H mH = new H();
WindowState mCurrentFocus = null;
WindowState mLastFocus = null;
-
+
// This just indicates the window the input method is on top of, not
// necessarily the window its input is going to.
WindowState mInputMethodTarget = null;
WindowState mUpcomingInputMethodTarget = null;
boolean mInputMethodTargetWaitingAnim;
int mInputMethodAnimLayerAdjustment;
-
+
WindowState mInputMethodWindow = null;
final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
AppWindowToken mFocusedApp = null;
PowerManagerService mPowerManager;
-
+
float mWindowAnimationScale = 1.0f;
float mTransitionAnimationScale = 1.0f;
-
+
final KeyWaiter mKeyWaiter = new KeyWaiter();
final KeyQ mQueue;
final InputDispatcherThread mInputThread;
// Who is holding the screen on.
Session mHoldingScreenOn;
-
+
/**
* Whether the UI is currently running in touch mode (not showing
* navigational focus because the user is directly pressing the screen).
@@ -411,14 +416,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
private ViewServer mViewServer;
final Rect mTempRect = new Rect();
-
+
final Configuration mTempConfiguration = new Configuration();
-
+
public static WindowManagerService main(Context context,
PowerManagerService pm, boolean haveInputMethods) {
WMThread thr = new WMThread(context, pm, haveInputMethods);
thr.start();
-
+
synchronized (thr) {
while (thr.mService == null) {
try {
@@ -427,17 +432,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
return thr.mService;
}
-
+
static class WMThread extends Thread {
WindowManagerService mService;
-
+
private final Context mContext;
private final PowerManagerService mPM;
private final boolean mHaveInputMethods;
-
+
public WMThread(Context context, PowerManagerService pm,
boolean haveInputMethods) {
super("WindowManager");
@@ -445,19 +450,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mPM = pm;
mHaveInputMethods = haveInputMethods;
}
-
+
public void run() {
Looper.prepare();
WindowManagerService s = new WindowManagerService(mContext, mPM,
mHaveInputMethods);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
-
+
synchronized (this) {
mService = s;
notifyAll();
}
-
+
Looper.loop();
}
}
@@ -468,7 +473,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
private final Context mContext;
private final PowerManagerService mPM;
boolean mRunning = false;
-
+
public PolicyThread(WindowManagerPolicy policy,
WindowManagerService service, Context context,
PowerManagerService pm) {
@@ -478,7 +483,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mContext = context;
mPM = pm;
}
-
+
public void run() {
Looper.prepare();
//Looper.myLooper().setMessageLogging(new LogPrinter(
@@ -486,12 +491,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
mPolicy.init(mContext, mService, mPM);
-
+
synchronized (this) {
mRunning = true;
notifyAll();
}
-
+
Looper.loop();
}
}
@@ -506,7 +511,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mHaveInputMethods = haveInputMethods;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
-
+
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -522,14 +527,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
-
+
mQueue = new KeyQ();
mInputThread = new InputDispatcherThread();
-
+
PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
thr.start();
-
+
synchronized (thr) {
while (!thr.mRunning) {
try {
@@ -538,9 +543,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
mInputThread.start();
-
+
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
}
@@ -593,12 +598,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return -1;
}
-
+
private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
final IWindow client = win.mClient;
final WindowToken token = win.mToken;
final ArrayList localmWindows = mWindows;
-
+
final int N = localmWindows.size();
final WindowState attached = win.mAttachedWindow;
int i;
@@ -623,12 +628,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
int newIdx = findIdxBasedOnAppTokens(win);
if(newIdx != -1) {
- //there is a window above this one associated with the same
- //apptoken note that the window could be a floating window
- //that was created later or a window at the top of the list of
+ //there is a window above this one associated with the same
+ //apptoken note that the window could be a floating window
+ //that was created later or a window at the top of the list of
//windows associated with this token.
localmWindows.add(newIdx+1, win);
- }
+ }
}
}
} else {
@@ -654,7 +659,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// we need to look some more.
if (pos != null) {
// Move behind any windows attached to this one.
- WindowToken atoken =
+ WindowToken atoken =
mTokenMap.get(((WindowState)pos).mClient.asBinder());
if (atoken != null) {
final int NC = atoken.windows.size();
@@ -777,12 +782,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
if (win.mAppToken != null && addToToken) {
win.mAppToken.allAppWindows.add(win);
}
}
-
+
static boolean canBeImeTarget(WindowState w) {
final int fl = w.mAttrs.flags
& (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
@@ -791,7 +796,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return false;
}
-
+
int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
final ArrayList localmWindows = mWindows;
final int N = localmWindows.size();
@@ -800,12 +805,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
while (i > 0) {
i--;
w = (WindowState)localmWindows.get(i);
-
+
//Log.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
// + Integer.toHexString(w.mAttrs.flags));
if (canBeImeTarget(w)) {
//Log.i(TAG, "Putting input method here!");
-
+
// Yet more tricksyness! If this window is a "starting"
// window, we do actually want to be on top of it, but
// it is not -really- where input will go. So if the caller
@@ -823,16 +828,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
break;
}
}
-
+
mUpcomingInputMethodTarget = w;
-
+
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Desired input method target="
+ w + " willMove=" + willMove);
-
+
if (willMove && w != null) {
final WindowState curTarget = mInputMethodTarget;
if (curTarget != null && curTarget.mAppToken != null) {
-
+
// Now some fun for dealing with window animations that
// modify the Z order. We need to look at all windows below
// the current target that are in this app, finding the highest
@@ -858,14 +863,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
pos--;
}
}
-
+
if (highestTarget != null) {
- if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition="
+ if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition="
+ mNextAppTransition + " " + highestTarget
+ " animating=" + highestTarget.isAnimating()
+ " layer=" + highestTarget.mAnimLayer
+ " new layer=" + w.mAnimLayer);
-
+
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
// If we are currently setting up for an animation,
// hold everything until we can find out what will happen.
@@ -884,7 +889,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
//Log.i(TAG, "Placing input method @" + (i+1));
if (w != null) {
if (willMove) {
@@ -911,7 +916,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return -1;
}
-
+
void addInputMethodWindowToListLocked(WindowState win) {
int pos = findDesiredInputMethodWindowIndexLocked(true);
if (pos >= 0) {
@@ -924,7 +929,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
addWindowToListInOrderLocked(win, true);
moveInputMethodDialogsLocked(pos);
}
-
+
void setInputMethodAnimLayerAdjustment(int adj) {
if (DEBUG_LAYERS) Log.v(TAG, "Setting im layer adj to " + adj);
mInputMethodAnimLayerAdjustment = adj;
@@ -951,7 +956,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ " anim layer: " + imw.mAnimLayer);
}
}
-
+
private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
int wpos = mWindows.indexOf(win);
if (wpos >= 0) {
@@ -970,7 +975,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return interestingPos;
}
-
+
private void reAddWindowToListInOrderLocked(WindowState win) {
addWindowToListInOrderLocked(win, false);
// This is a hack to get all of the child windows added as well
@@ -982,7 +987,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
reAddWindowLocked(wpos, win);
}
}
-
+
void logWindowList(String prefix) {
int N = mWindows.size();
while (N > 0) {
@@ -990,10 +995,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
}
}
-
+
void moveInputMethodDialogsLocked(int pos) {
ArrayList<WindowState> dialogs = mInputMethodDialogs;
-
+
final int N = dialogs.size();
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
for (int i=0; i<N; i++) {
@@ -1003,7 +1008,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.v(TAG, "Window list w/pos=" + pos);
logWindowList(" ");
}
-
+
if (pos >= 0) {
final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
if (pos < mWindows.size()) {
@@ -1034,25 +1039,25 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
final WindowState imWin = mInputMethodWindow;
final int DN = mInputMethodDialogs.size();
if (imWin == null && DN == 0) {
return false;
}
-
+
int imPos = findDesiredInputMethodWindowIndexLocked(true);
if (imPos >= 0) {
// In this case, the input method windows are to be placed
// immediately above the window they are targeting.
-
+
// First check to see if the input method windows are already
// located here, and contiguous.
final int N = mWindows.size();
WindowState firstImWin = imPos < N
? (WindowState)mWindows.get(imPos) : null;
-
+
// Figure out the actual input method window that should be
// at the bottom of their stack.
WindowState baseImWin = imWin != null
@@ -1061,7 +1066,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
if (cw.mSubLayer < 0) baseImWin = cw;
}
-
+
if (firstImWin == baseImWin) {
// The windows haven't moved... but are they still contiguous?
// First find the top IM window.
@@ -1085,7 +1090,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return false;
}
}
-
+
if (imWin != null) {
if (DEBUG_INPUT_METHOD) {
Log.v(TAG, "Moving IM from " + imPos);
@@ -1106,11 +1111,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
moveInputMethodDialogsLocked(imPos);
}
-
+
} else {
// In this case, the input method windows go in a fixed layer,
// because they aren't currently associated with a focus window.
-
+
if (imWin != null) {
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Moving IM from " + imPos);
tmpRemoveWindowLocked(0, imWin);
@@ -1124,20 +1129,20 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
moveInputMethodDialogsLocked(-1);;
}
-
+
}
-
+
if (needAssignLayers) {
assignLayersLocked();
}
-
+
return true;
}
-
+
void adjustInputMethodDialogsLocked() {
moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
}
-
+
public int addWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets) {
@@ -1145,11 +1150,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (res != WindowManagerImpl.ADD_OKAY) {
return res;
}
-
+
boolean reportNewConfig = false;
WindowState attachedWindow = null;
WindowState win = null;
-
+
synchronized(mWindowMap) {
// Instantiating a Display requires talking with the simulator,
// so don't do it until we know the system is mostly up and
@@ -1160,14 +1165,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.setDisplay(mDisplay);
reportNewConfig = true;
}
-
+
if (mWindowMap.containsKey(client.asBinder())) {
Log.w(TAG, "Window " + client + " is already added");
return WindowManagerImpl.ADD_DUPLICATE_ADD;
}
if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
- attachedWindow = windowForClientLocked(null, attrs.token);
+ attachedWindow = windowForClientLocked(null, attrs.token);
if (attachedWindow == null) {
Log.w(TAG, "Attempted to add window with token that is not a window: "
+ attrs.token + ". Aborting.");
@@ -1234,7 +1239,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
mPolicy.adjustWindowParamsLw(win.mAttrs);
-
+
res = mPolicy.prepareAddWindowLw(win, attrs);
if (res != WindowManagerImpl.ADD_OKAY) {
return res;
@@ -1243,9 +1248,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// From now on, no exceptions or errors allowed!
res = WindowManagerImpl.ADD_OKAY;
-
+
final long origId = Binder.clearCallingIdentity();
-
+
if (addToken) {
mTokenMap.put(attrs.token, token);
mTokenList.add(token);
@@ -1259,7 +1264,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
boolean imMayMove = true;
-
+
if (attrs.type == TYPE_INPUT_METHOD) {
mInputMethodWindow = win;
addInputMethodWindowToListLocked(win);
@@ -1272,18 +1277,18 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
addWindowToListInOrderLocked(win, true);
}
-
+
win.mEnterAnimationPending = true;
-
+
mPolicy.getContentInsetHintLw(attrs, outContentInsets);
-
+
if (mInTouchMode) {
res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
}
if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
}
-
+
boolean focusChanged = false;
if (win.canReceiveKeys()) {
if ((focusChanged=updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS))
@@ -1291,15 +1296,15 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
imMayMove = false;
}
}
-
+
if (imMayMove) {
- moveInputMethodWindowsIfNeededLocked(false);
+ moveInputMethodWindowsIfNeededLocked(false);
}
-
+
assignLayersLocked();
// Don't do layout here, the window must call
// relayout to be displayed, so we'll do it there.
-
+
//dump();
if (focusChanged) {
@@ -1323,16 +1328,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Update Orientation after adding a window, only if the window needs to be
// displayed right away
if (win.isVisibleOrAdding()) {
- if (updateOrientationFromAppTokens(null, null) != null) {
+ if (updateOrientationFromAppTokensUnchecked(null, null) != null) {
sendNewConfiguration();
}
}
}
Binder.restoreCallingIdentity(origId);
-
+
return res;
}
-
+
public void removeWindow(Session session, IWindow client) {
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client);
@@ -1342,7 +1347,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
removeWindowLocked(session, win);
}
}
-
+
public void removeWindowLocked(Session session, WindowState win) {
if (localLOGV || DEBUG_FOCUS) Log.v(
@@ -1352,7 +1357,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ ", surface=" + win.mSurface);
final long origId = Binder.clearCallingIdentity();
-
+
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Remove " + win + ": mSurface=" + win.mSurface
+ " mExiting=" + win.mExiting
@@ -1372,7 +1377,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// If we are not currently running the exit animation, we
// need to see about starting one.
if (wasVisible=win.isWinVisibleLw()) {
-
+
int transit = WindowManagerPolicy.TRANSIT_EXIT;
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
@@ -1409,17 +1414,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Binder.restoreCallingIdentity(origId);
}
-
+
private void removeWindowInnerLocked(Session session, WindowState win) {
mKeyWaiter.releasePendingPointerLocked(win.mSession);
mKeyWaiter.releasePendingTrackballLocked(win.mSession);
-
+
win.mRemoved = true;
-
+
if (mInputMethodTarget == win) {
moveInputMethodWindowsIfNeededLocked(false);
}
-
+
mPolicy.removeWindowLw(win);
win.removeLocked();
@@ -1431,7 +1436,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
mInputMethodDialogs.remove(win);
}
-
+
final WindowToken token = win.mToken;
final AppWindowToken atoken = win.mAppToken;
token.windows.remove(win);
@@ -1468,7 +1473,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mH.sendMessage(m);
}
}
-
+
if (!mInLayout) {
assignLayersLocked();
mLayoutNeeded = true;
@@ -1499,7 +1504,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
void setInsetsWindow(Session session, IWindow client,
- int touchableInsets, Rect contentInsets,
+ int touchableInsets, Rect contentInsets,
Rect visibleInsets) {
long origId = Binder.clearCallingIdentity();
try {
@@ -1518,7 +1523,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Binder.restoreCallingIdentity(origId);
}
}
-
+
public void getWindowDisplayFrame(Session session, IWindow client,
Rect outDisplayFrame) {
synchronized(mWindowMap) {
@@ -1540,7 +1545,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean inTouchMode;
Configuration newConfig = null;
long origId = Binder.clearCallingIdentity();
-
+
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client);
if (win == null) {
@@ -1552,7 +1557,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (attrs != null) {
mPolicy.adjustWindowParamsLw(attrs);
}
-
+
int attrChanges = 0;
int flagChanges = 0;
if (attrs != null) {
@@ -1584,11 +1589,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean imMayMove = (flagChanges&(
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
-
+
boolean focusMayChange = win.mViewVisibility != viewVisibility
|| ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
|| (!win.mRelayoutCalled);
-
+
win.mRelayoutCalled = true;
final int oldVisibility = win.mViewVisibility;
win.mViewVisibility = viewVisibility;
@@ -1676,17 +1681,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
//System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
}
-
+
// updateFocusedWindowLocked() already assigned layers so we only need to
// reassign them at this point if the IM window state gets shuffled
boolean assignLayers = false;
-
+
if (imMayMove) {
if (moveInputMethodWindowsIfNeededLocked(false)) {
assignLayers = true;
}
}
-
+
mLayoutNeeded = true;
win.mGivenInsetsPending = insetsPending;
if (assignLayers) {
@@ -1702,7 +1707,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
outVisibleInsets.set(win.mVisibleInsets);
if (localLOGV) Log.v(
TAG, "Relayout given client " + client.asBinder()
- + ", requestedWidth=" + requestedWidth
+ + ", requestedWidth=" + requestedWidth
+ ", requestedHeight=" + requestedHeight
+ ", viewVisibility=" + viewVisibility
+ "\nRelayout returning frame=" + outFrame
@@ -1717,9 +1722,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (newConfig != null) {
sendNewConfiguration();
}
-
+
Binder.restoreCallingIdentity(origId);
-
+
return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
| (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
}
@@ -1756,7 +1761,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return null;
}
-
+
private void applyEnterAnimationLocked(WindowState win) {
int transit = WindowManagerPolicy.TRANSIT_SHOW;
if (win.mEnterAnimationPending) {
@@ -1774,7 +1779,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// an animation of the same type, then just leave that one alone.
return true;
}
-
+
// Only apply an animation if the display isn't frozen. If it is
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
@@ -1839,7 +1844,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return null;
}
-
+
private boolean applyAnimationLocked(AppWindowToken wtoken,
WindowManager.LayoutParams lp, int transit, boolean enter) {
// Only apply an animation if the display isn't frozen. If it is
@@ -1938,7 +1943,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (Binder.getCallingPid() == Process.myPid()) {
return true;
}
-
+
if (mContext.checkCallingPermission(permission)
== PackageManager.PERMISSION_GRANTED) {
return true;
@@ -1950,7 +1955,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.w(TAG, msg);
return false;
}
-
+
AppWindowToken findAppWindowToken(IBinder token) {
WindowToken wtoken = mTokenMap.get(token);
if (wtoken == null) {
@@ -1958,13 +1963,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return wtoken.appWindowToken;
}
-
+
public void addWindowToken(IBinder token, int type) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addWindowToken()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
-
+
synchronized(mWindowMap) {
WindowToken wtoken = mTokenMap.get(token);
if (wtoken != null) {
@@ -1976,11 +1981,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mTokenList.add(wtoken);
}
}
-
+
public void removeWindowToken(IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"removeWindowToken()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
final long origId = Binder.clearCallingIdentity();
@@ -1991,17 +1996,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean delayed = false;
if (!wtoken.hidden) {
wtoken.hidden = true;
-
+
final int N = wtoken.windows.size();
boolean changed = false;
-
+
for (int i=0; i<N; i++) {
WindowState win = wtoken.windows.get(i);
if (win.isAnimating()) {
delayed = true;
}
-
+
if (win.isVisibleNow()) {
applyAnimationLocked(win,
WindowManagerPolicy.TRANSIT_EXIT, false);
@@ -2016,12 +2021,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
performLayoutAndPlaceSurfacesLocked();
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
}
-
+
if (delayed) {
mExitingTokens.add(wtoken);
}
}
-
+
} else {
Log.w(TAG, "Attempted to remove non-existing token: " + token);
}
@@ -2033,9 +2038,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int groupId, int requestedOrientation, boolean fullscreen) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
-
+
synchronized(mWindowMap) {
AppWindowToken wtoken = findAppWindowToken(token.asBinder());
if (wtoken != null) {
@@ -2050,19 +2055,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (localLOGV) Log.v(TAG, "Adding new app token: " + wtoken);
mTokenMap.put(token.asBinder(), wtoken);
mTokenList.add(wtoken);
-
+
// Application tokens start out hidden.
wtoken.hidden = true;
wtoken.hiddenRequested = true;
-
+
//dump();
}
}
-
+
public void setAppGroupId(IBinder token, int groupId) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppStartingIcon()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
@@ -2074,7 +2079,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
wtoken.groupId = groupId;
}
}
-
+
public int getOrientationFromWindowsLocked() {
int pos = mWindows.size() - 1;
while (pos >= 0) {
@@ -2098,7 +2103,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
public int getOrientationFromAppTokensLocked() {
int pos = mAppTokens.size() - 1;
int curGroup = 0;
@@ -2140,7 +2145,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// to use the orientation behind it, then just take whatever
// orientation it has and ignores whatever is under it.
lastFullscreen = wtoken.appFullscreen;
- if (lastFullscreen
+ if (lastFullscreen
&& or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
return or;
}
@@ -2157,11 +2162,25 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
public Configuration updateOrientationFromAppTokens(
Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+ if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
+ "updateOrientationFromAppTokens()")) {
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
+ }
+
Configuration config;
long ident = Binder.clearCallingIdentity();
+ config = updateOrientationFromAppTokensUnchecked(currentConfig,
+ freezeThisOneIfNeeded);
+ Binder.restoreCallingIdentity(ident);
+ return config;
+ }
+
+ Configuration updateOrientationFromAppTokensUnchecked(
+ Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
+ Configuration config;
synchronized(mWindowMap) {
config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded);
}
@@ -2169,14 +2188,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mLayoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
}
- Binder.restoreCallingIdentity(ident);
return config;
}
-
+
/*
* The orientation is computed from non-application windows first. If none of
* the non-application windows specify orientation, the orientation is computed from
- * application tokens.
+ * application tokens.
* @see android.view.IWindowManager#updateOrientationFromAppTokens(
* android.os.IBinder)
*/
@@ -2186,7 +2204,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
long ident = Binder.clearCallingIdentity();
try {
int req = computeForcedAppOrientationLocked();
-
+
if (req != mForcedAppOrientation) {
changed = true;
mForcedAppOrientation = req;
@@ -2194,7 +2212,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
//action like disabling/enabling sensors etc.,
mPolicy.setCurrentOrientationLw(req);
}
-
+
if (changed) {
changed = setRotationUncheckedLocked(
WindowManagerPolicy.USE_LAST_ROTATION,
@@ -2226,10 +2244,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} finally {
Binder.restoreCallingIdentity(ident);
}
-
+
return null;
}
-
+
int computeForcedAppOrientationLocked() {
int req = getOrientationFromWindowsLocked();
if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
@@ -2237,39 +2255,39 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return req;
}
-
+
public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppOrientation()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
-
+
synchronized(mWindowMap) {
AppWindowToken wtoken = findAppWindowToken(token.asBinder());
if (wtoken == null) {
Log.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
return;
}
-
+
wtoken.requestedOrientation = requestedOrientation;
}
}
-
+
public int getAppOrientation(IApplicationToken token) {
synchronized(mWindowMap) {
AppWindowToken wtoken = findAppWindowToken(token.asBinder());
if (wtoken == null) {
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
return wtoken.requestedOrientation;
}
}
-
+
public void setFocusedApp(IBinder token, boolean moveFocusNow) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setFocusedApp()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
@@ -2302,9 +2320,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void prepareAppTransition(int transit) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"prepareAppTransition()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
-
+
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Prepare app transition: transit=" + transit
@@ -2327,13 +2345,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public int getPendingAppTransition() {
return mNextAppTransition;
}
-
+
public void executeAppTransition() {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"executeAppTransition()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
-
+
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
@@ -2351,14 +2369,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
IBinder transferFrom, boolean createIfNeeded) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppStartingIcon()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
if (DEBUG_STARTING_WINDOW) Log.v(
TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
+ " transferFrom=" + transferFrom);
-
+
AppWindowToken wtoken = findAppWindowToken(token);
if (wtoken == null) {
Log.w(TAG, "Attempted to set icon of non-existing app token: " + token);
@@ -2371,11 +2389,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (mDisplayFrozen) {
return;
}
-
+
if (wtoken.startingData != null) {
return;
}
-
+
if (transferFrom != null) {
AppWindowToken ttoken = findAppWindowToken(transferFrom);
if (ttoken != null) {
@@ -2391,7 +2409,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
"Moving existing starting from " + ttoken
+ " to " + wtoken);
final long origId = Binder.clearCallingIdentity();
-
+
// Transfer the starting window over to the new
// token.
wtoken.startingData = ttoken.startingData;
@@ -2409,7 +2427,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
ttoken.allAppWindows.remove(startingWindow);
addWindowToListInOrderLocked(startingWindow, true);
wtoken.allAppWindows.add(startingWindow);
-
+
// Propagate other interesting state between the
// tokens. If the old token is displayed, we should
// immediately force the new one to be displayed. If
@@ -2439,7 +2457,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
wtoken.updateLayers();
ttoken.updateLayers();
}
-
+
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
mLayoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
@@ -2469,7 +2487,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (!createIfNeeded) {
return;
}
-
+
mStartingIconInTransition = true;
wtoken.startingData = new StartingData(
pkg, theme, nonLocalizedLabel,
@@ -2485,7 +2503,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void setAppWillBeHidden(IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppWillBeHidden()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
AppWindowToken wtoken;
@@ -2499,7 +2517,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
wtoken.willBeHidden = true;
}
}
-
+
boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
boolean visible, int transit, boolean performLayout) {
boolean delayed = false;
@@ -2508,7 +2526,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
wtoken.clientHidden = !visible;
wtoken.sendAppVisibilityToClients();
}
-
+
wtoken.willBeHidden = false;
if (wtoken.hidden == visible) {
final int N = wtoken.allAppWindows.size();
@@ -2516,9 +2534,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
+ " performLayout=" + performLayout);
-
+
boolean runningAppAnimation = false;
-
+
if (transit != WindowManagerPolicy.TRANSIT_NONE) {
if (wtoken.animation == sDummyAnimation) {
wtoken.animation = null;
@@ -2529,7 +2547,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
delayed = runningAppAnimation = true;
}
}
-
+
for (int i=0; i<N; i++) {
WindowState win = wtoken.allAppWindows.get(i);
if (win == wtoken.startingWindow) {
@@ -2539,7 +2557,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (win.isAnimating()) {
delayed = true;
}
-
+
//Log.i(TAG, "Window " + win + ": vis=" + win.isVisible());
//win.dump(" ");
if (visible) {
@@ -2574,11 +2592,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
swin.mPolicyVisibilityAfterAnim = false;
}
}
-
+
if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "setTokenVisibilityLocked: " + wtoken
+ ": hidden=" + wtoken.hidden + " hiddenRequested="
+ wtoken.hiddenRequested);
-
+
if (changed && performLayout) {
mLayoutNeeded = true;
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
@@ -2589,14 +2607,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (wtoken.animation != null) {
delayed = true;
}
-
+
return delayed;
}
public void setAppVisibility(IBinder token, boolean visible) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppVisibility()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
AppWindowToken wtoken;
@@ -2616,7 +2634,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ " hidden=" + wtoken.hidden
+ " hiddenRequested=" + wtoken.hiddenRequested, e);
}
-
+
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
@@ -2625,7 +2643,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return;
}
wtoken.hiddenRequested = !visible;
-
+
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Setting dummy animation on: " + wtoken);
wtoken.setDummyAnimation();
@@ -2637,7 +2655,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
wtoken.allDrawn = false;
wtoken.startingDisplayed = false;
wtoken.startingMoved = false;
-
+
if (wtoken.clientHidden) {
// In the case where we are making an app visible
// but holding off for a transition, we still need
@@ -2653,7 +2671,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return;
}
-
+
final long origId = Binder.clearCallingIdentity();
setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_NONE, true);
wtoken.updateReportedVisibilityLocked();
@@ -2694,7 +2712,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
public void startAppFreezingScreenLocked(AppWindowToken wtoken,
int configChanges) {
if (DEBUG_ORIENTATION) {
@@ -2722,11 +2740,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
public void startAppFreezingScreen(IBinder token, int configChanges) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppFreezingScreen()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
@@ -2734,7 +2752,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (DEBUG_ORIENTATION) Log.v(TAG, "Skipping set freeze of " + token);
return;
}
-
+
AppWindowToken wtoken = findAppWindowToken(token);
if (wtoken == null || wtoken.appToken == null) {
Log.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
@@ -2745,11 +2763,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Binder.restoreCallingIdentity(origId);
}
}
-
+
public void stopAppFreezingScreen(IBinder token, boolean force) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppFreezingScreen()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
@@ -2764,11 +2782,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Binder.restoreCallingIdentity(origId);
}
}
-
+
public void removeAppToken(IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"removeAppToken()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
AppWindowToken wtoken = null;
@@ -2813,7 +2831,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
Log.w(TAG, "Attempted to remove non-existing app token: " + token);
}
-
+
if (!delayed && wtoken != null) {
wtoken.updateReportedVisibilityLocked();
}
@@ -2847,13 +2865,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
}
}
-
+
void dumpWindowsLocked() {
for (int i=mWindows.size()-1; i>=0; i--) {
Log.v(TAG, " #" + i + ": " + mWindows.get(i));
}
}
-
+
private int findWindowOffsetLocked(int tokenPos) {
final int NW = mWindows.size();
@@ -2924,7 +2942,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return index;
}
-
+
private final int reAddAppWindowsLocked(int index, WindowToken token) {
final int NW = token.windows.size();
for (int i=0; i<NW; i++) {
@@ -2936,7 +2954,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void moveAppToken(int index, IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"moveAppToken()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized(mWindowMap) {
@@ -2951,7 +2969,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mAppTokens.add(index, wtoken);
if (DEBUG_REORDER) Log.v(TAG, "Moved " + token + " to " + index + ":");
if (DEBUG_REORDER) dumpAppTokensLocked();
-
+
final long origId = Binder.clearCallingIdentity();
if (DEBUG_REORDER) Log.v(TAG, "Removing windows in " + token + ":");
if (DEBUG_REORDER) dumpWindowsLocked();
@@ -3018,7 +3036,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void moveAppTokensToTop(List<IBinder> tokens) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"moveAppTokensToTop()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
final long origId = Binder.clearCallingIdentity();
@@ -3039,7 +3057,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void moveAppTokensToBottom(List<IBinder> tokens) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"moveAppTokensToBottom()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
final long origId = Binder.clearCallingIdentity();
@@ -3062,7 +3080,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// -------------------------------------------------------------
// Misc IWindowSession methods
// -------------------------------------------------------------
-
+
public void disableKeyguard(IBinder token, String tag) {
if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
!= PackageManager.PERMISSION_GRANTED) {
@@ -3116,17 +3134,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public boolean inKeyguardRestrictedInputMode() {
return mPolicy.inKeyguardRestrictedKeyInputMode();
}
-
+
static float fixScale(float scale) {
if (scale < 0) scale = 0;
else if (scale > 20) scale = 20;
return Math.abs(scale);
}
-
+
public void setAnimationScale(int which, float scale) {
if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
"setAnimationScale()")) {
- return;
+ throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
}
if (scale < 0) scale = 0;
@@ -3136,15 +3154,15 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
case 0: mWindowAnimationScale = fixScale(scale); break;
case 1: mTransitionAnimationScale = fixScale(scale); break;
}
-
+
// Persist setting
mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
}
-
+
public void setAnimationScales(float[] scales) {
if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
"setAnimationScale()")) {
- return;
+ throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
}
if (scales != null) {
@@ -3155,11 +3173,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mTransitionAnimationScale = fixScale(scales[1]);
}
}
-
+
// Persist setting
mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
}
-
+
public float getAnimationScale(int which) {
switch (which) {
case 0: return mWindowAnimationScale;
@@ -3167,63 +3185,63 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return 0;
}
-
+
public float[] getAnimationScales() {
return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
}
-
+
public int getSwitchState(int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getSwitchState()")) {
- return -1;
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
}
return KeyInputQueue.getSwitchState(sw);
}
-
+
public int getSwitchStateForDevice(int devid, int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getSwitchStateForDevice()")) {
- return -1;
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
}
return KeyInputQueue.getSwitchState(devid, sw);
}
-
+
public int getScancodeState(int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getScancodeState()")) {
- return -1;
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
}
return KeyInputQueue.getScancodeState(sw);
}
-
+
public int getScancodeStateForDevice(int devid, int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getScancodeStateForDevice()")) {
- return -1;
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
}
return KeyInputQueue.getScancodeState(devid, sw);
}
-
+
public int getKeycodeState(int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getKeycodeState()")) {
- return -1;
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
}
return KeyInputQueue.getKeycodeState(sw);
}
-
+
public int getKeycodeStateForDevice(int devid, int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getKeycodeStateForDevice()")) {
- return -1;
+ throw new SecurityException("Requires READ_INPUT_STATE permission");
}
return KeyInputQueue.getKeycodeState(devid, sw);
}
-
+
public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
return KeyInputQueue.hasKeys(keycodes, keyExists);
}
-
+
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (mSystemBooted) {
@@ -3231,10 +3249,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
mSystemBooted = true;
}
-
+
performEnableScreen();
}
-
+
public void enableScreenIfNeededLocked() {
if (mDisplayEnabled) {
return;
@@ -3244,7 +3262,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
}
-
+
public void performEnableScreen() {
synchronized(mWindowMap) {
if (mDisplayEnabled) {
@@ -3253,7 +3271,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (!mSystemBooted) {
return;
}
-
+
// Don't enable the screen until all existing windows
// have been drawn.
final int N = mWindows.size();
@@ -3263,7 +3281,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return;
}
}
-
+
mDisplayEnabled = true;
if (false) {
Log.i(TAG, "ENABLING SCREEN!");
@@ -3286,41 +3304,41 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.e(TAG, "Boot completed: SurfaceFlinger is dead!");
}
}
-
+
mPolicy.enableScreenAfterBoot();
-
+
// Make sure the last requested orientation has been applied.
setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
}
-
+
public void setInTouchMode(boolean mode) {
synchronized(mWindowMap) {
mInTouchMode = mode;
}
}
- public void setRotation(int rotation,
+ public void setRotation(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"setRotation()")) {
- return;
+ throw new SecurityException("Requires SET_ORIENTATION permission");
}
setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
}
-
+
public void setRotationUnchecked(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
if(DEBUG_ORIENTATION) Log.v(TAG,
"alwaysSendConfiguration set to "+alwaysSendConfiguration);
-
+
long origId = Binder.clearCallingIdentity();
boolean changed;
synchronized(mWindowMap) {
changed = setRotationUncheckedLocked(rotation, animFlags);
}
-
+
if (changed) {
sendNewConfiguration();
synchronized(mWindowMap) {
@@ -3331,10 +3349,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
//update configuration ignoring orientation change
sendNewConfiguration();
}
-
+
Binder.restoreCallingIdentity(origId);
}
-
+
public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
boolean changed;
if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
@@ -3348,9 +3366,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mRotation, mDisplayEnabled);
if (DEBUG_ORIENTATION) Log.v(TAG, "new rotation is set to " + rotation);
changed = mDisplayEnabled && mRotation != rotation;
-
+
if (changed) {
- if (DEBUG_ORIENTATION) Log.v(TAG,
+ if (DEBUG_ORIENTATION) Log.v(TAG,
"Rotation changed to " + rotation
+ " from " + mRotation
+ " (forceApp=" + mForcedAppOrientation
@@ -3379,10 +3397,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
} //end if changed
-
+
return changed;
}
-
+
public int getRotation() {
return mRotation;
}
@@ -3401,7 +3419,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
};
-
+
synchronized (mWindowMap) {
try {
watcher.asBinder().linkToDeath(dr, 0);
@@ -3409,7 +3427,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} catch (RemoteException e) {
// Client died, no cleanup needed.
}
-
+
return mRotation;
}
}
@@ -3425,7 +3443,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
*/
public boolean startViewServer(int port) {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3442,7 +3460,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
try {
return mViewServer.start();
} catch (IOException e) {
- Log.w(TAG, "View server did not start");
+ Log.w(TAG, "View server did not start");
}
}
return false;
@@ -3457,6 +3475,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return false;
}
+ private boolean isSystemSecure() {
+ return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
+ "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+ }
+
/**
* Stops the view server if it exists.
*
@@ -3466,7 +3489,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* @see com.android.server.ViewServer
*/
public boolean stopViewServer() {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3488,7 +3511,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* @see com.android.server.ViewServer
*/
public boolean isViewServerRunning() {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3509,7 +3532,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* @return False if an error occured, true otherwise.
*/
boolean viewServerListWindows(Socket client) {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3576,7 +3599,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* not indicate whether the command itself was successful.
*/
boolean viewServerWindowCommand(Socket client, String command, String parameters) {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3666,13 +3689,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} catch (RemoteException e) {
}
}
-
+
public Configuration computeNewConfiguration() {
synchronized (mWindowMap) {
return computeNewConfigurationLocked();
}
}
-
+
Configuration computeNewConfigurationLocked() {
Configuration config = new Configuration();
if (!computeNewConfigurationLocked(config)) {
@@ -3693,7 +3716,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return config;
}
-
+
boolean computeNewConfigurationLocked(Configuration config) {
if (mDisplay == null) {
return false;
@@ -3713,7 +3736,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mPolicy.adjustConfigurationLw(config);
return true;
}
-
+
// -------------------------------------------------------------
// Input Events and Focus Management
// -------------------------------------------------------------
@@ -3777,7 +3800,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
/**
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
- private boolean dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
+ private int dispatchPointer(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
if (DEBUG_INPUT || WindowManagerPolicy.WATCH_POINTER) Log.v(TAG,
"dispatchPointer " + ev);
@@ -3793,7 +3816,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
int action = ev.getAction();
-
+
if (action == MotionEvent.ACTION_UP) {
// let go of our target
mKeyWaiter.mMotionTarget = null;
@@ -3815,18 +3838,18 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.recycleEvent(qev);
}
ev.recycle();
- return false;
+ return INJECT_FAILED;
}
if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
if (qev != null) {
mQueue.recycleEvent(qev);
}
ev.recycle();
- return true;
+ return INJECT_SUCCEEDED;
}
-
+
WindowState target = (WindowState)targetObj;
-
+
final long eventTime = ev.getEventTime();
final long eventTimeNano = ev.getEventTimeNano();
@@ -3843,7 +3866,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.recycleEvent(qev);
}
ev.recycle();
- return false;
+ return INJECT_NO_PERMISSION;
}
}
@@ -3851,7 +3874,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
lt.sample("4 in dispatchPointer ", System.nanoTime() - eventTimeNano);
}
- if ((target.mAttrs.flags &
+ if ((target.mAttrs.flags &
WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
//target wants to ignore fat touch events
boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
@@ -3878,7 +3901,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if(mFatTouch) {
//two cases here
//an invalid down followed by 0 or moves(valid or invalid)
- //a valid down, invalid move, more moves. want to ignore till up
+ //a valid down, invalid move, more moves. want to ignore till up
returnFlag = true;
} else if(cheekPress) {
//valid down followed by invalid moves
@@ -3897,7 +3920,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.recycleEvent(qev);
}
ev.recycle();
- return false;
+ return INJECT_FAILED;
}
} //end if target
@@ -3967,7 +3990,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mKeyWaiter.bindTargetWindowLocked(target);
}
}
-
+
// finally offset the event to the target's coordinate system and
// dispatch the event.
try {
@@ -3984,7 +4007,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (MEASURE_LATENCY) {
lt.sample("7 after svr->client ipc ", System.nanoTime() - eventTimeNano);
}
- return true;
+ return INJECT_SUCCEEDED;
} catch (android.os.RemoteException e) {
Log.i(TAG, "WINDOW DIED during motion dispatch: " + target);
mKeyWaiter.mMotionTarget = null;
@@ -3995,16 +4018,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// removed.
}
}
- return false;
+ return INJECT_FAILED;
}
-
+
/**
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
- private boolean dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
+ private int dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
if (DEBUG_INPUT) Log.v(
TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
-
+
Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
ev, false, false);
if (focusObj == null) {
@@ -4013,18 +4036,18 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.recycleEvent(qev);
}
ev.recycle();
- return false;
+ return INJECT_FAILED;
}
if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
if (qev != null) {
mQueue.recycleEvent(qev);
}
ev.recycle();
- return true;
+ return INJECT_SUCCEEDED;
}
-
+
WindowState focus = (WindowState)focusObj;
-
+
if (uid != 0 && uid != focus.mSession.mUid) {
if (mContext.checkPermission(
android.Manifest.permission.INJECT_EVENTS, pid, uid)
@@ -4036,12 +4059,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.recycleEvent(qev);
}
ev.recycle();
- return false;
+ return INJECT_NO_PERMISSION;
}
}
-
+
final long eventTime = ev.getEventTime();
-
+
synchronized(mWindowMap) {
if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
mKeyWaiter.bindTargetWindowLocked(focus,
@@ -4053,10 +4076,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mKeyWaiter.bindTargetWindowLocked(focus);
}
}
-
+
try {
focus.mClient.dispatchTrackball(ev, eventTime);
- return true;
+ return INJECT_SUCCEEDED;
} catch (android.os.RemoteException e) {
Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
try {
@@ -4066,28 +4089,28 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// removed.
}
}
-
- return false;
+
+ return INJECT_FAILED;
}
-
+
/**
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
- private boolean dispatchKey(KeyEvent event, int pid, int uid) {
+ private int dispatchKey(KeyEvent event, int pid, int uid) {
if (DEBUG_INPUT) Log.v(TAG, "Dispatch key: " + event);
Object focusObj = mKeyWaiter.waitForNextEventTarget(event, null,
null, false, false);
if (focusObj == null) {
Log.w(TAG, "No focus window, dropping: " + event);
- return false;
+ return INJECT_FAILED;
}
if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
- return true;
+ return INJECT_SUCCEEDED;
}
-
+
WindowState focus = (WindowState)focusObj;
-
+
if (DEBUG_INPUT) Log.v(
TAG, "Dispatching to " + focus + ": " + event);
@@ -4098,10 +4121,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.w(TAG, "Permission denied: injecting key event from pid "
+ pid + " uid " + uid + " to window " + focus
+ " owned by uid " + focus.mSession.mUid);
- return false;
+ return INJECT_NO_PERMISSION;
}
}
-
+
synchronized(mWindowMap) {
mKeyWaiter.bindTargetWindowLocked(focus);
}
@@ -4109,14 +4132,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// NOSHIP extra state logging
mKeyWaiter.recordDispatchState(event, focus);
// END NOSHIP
-
+
try {
if (DEBUG_INPUT || DEBUG_FOCUS) {
Log.v(TAG, "Delivering key " + event.getKeyCode()
+ " to " + focus);
}
focus.mClient.dispatchKey(event);
- return true;
+ return INJECT_SUCCEEDED;
} catch (android.os.RemoteException e) {
Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
try {
@@ -4126,14 +4149,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// removed.
}
}
-
- return false;
+
+ return INJECT_FAILED;
}
-
+
public void pauseKeyDispatching(IBinder _token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"pauseKeyDispatching()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized (mWindowMap) {
@@ -4147,7 +4170,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void resumeKeyDispatching(IBinder _token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"resumeKeyDispatching()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized (mWindowMap) {
@@ -4161,18 +4184,18 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public void setEventDispatching(boolean enabled) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"resumeKeyDispatching()")) {
- return;
+ throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
synchronized (mWindowMap) {
mKeyWaiter.setEventDispatchingLocked(enabled);
}
}
-
+
/**
* Injects a keystroke event into the UI.
- *
- * @param ev A motion event describing the keystroke action. (Be sure to use
+ *
+ * @param ev A motion event describing the keystroke action. (Be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.)
* @param sync If true, wait for the event to be completed before returning to the caller.
* @return Returns true if event was dispatched, false if it was dropped for any reason
@@ -4194,47 +4217,68 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM);
- boolean result = dispatchKey(newEvent, Binder.getCallingPid(), Binder.getCallingUid());
+ int result = dispatchKey(newEvent, Binder.getCallingPid(), Binder.getCallingUid());
if (sync) {
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
}
- return result;
+ switch (result) {
+ case INJECT_NO_PERMISSION:
+ throw new SecurityException(
+ "Injecting to another application requires INJECT_EVENT permission");
+ case INJECT_SUCCEEDED:
+ return true;
+ }
+ return false;
}
/**
* Inject a pointer (touch) event into the UI.
- *
- * @param ev A motion event describing the pointer (touch) action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
+ *
+ * @param ev A motion event describing the pointer (touch) action. (As noted in
+ * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.)
* @param sync If true, wait for the event to be completed before returning to the caller.
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
- boolean result = dispatchPointer(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
+ int result = dispatchPointer(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
if (sync) {
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
}
- return result;
+ switch (result) {
+ case INJECT_NO_PERMISSION:
+ throw new SecurityException(
+ "Injecting to another application requires INJECT_EVENT permission");
+ case INJECT_SUCCEEDED:
+ return true;
+ }
+ return false;
}
-
+
/**
* Inject a trackball (navigation device) event into the UI.
- *
- * @param ev A motion event describing the trackball action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
+ *
+ * @param ev A motion event describing the trackball action. (As noted in
+ * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.)
* @param sync If true, wait for the event to be completed before returning to the caller.
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
- boolean result = dispatchTrackball(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
+ int result = dispatchTrackball(null, ev, Binder.getCallingPid(), Binder.getCallingUid());
if (sync) {
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
}
- return result;
+ switch (result) {
+ case INJECT_NO_PERMISSION:
+ throw new SecurityException(
+ "Injecting to another application requires INJECT_EVENT permission");
+ case INJECT_SUCCEEDED:
+ return true;
+ }
+ return false;
}
-
+
private WindowState getFocusedWindow() {
synchronized (mWindowMap) {
return getFocusedWindowLocked();
@@ -4244,7 +4288,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
private WindowState getFocusedWindowLocked() {
return mCurrentFocus;
}
-
+
/**
* This class holds the state for dispatching key events. This state
* is protected by the KeyWaiter instance, NOT by the window lock. You
@@ -4266,7 +4310,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
private boolean wasFrozen;
private boolean focusPaused;
private WindowState curFocus;
-
+
DispatchState(KeyEvent theEvent, WindowState theFocus) {
focus = theFocus;
event = theEvent;
@@ -4288,7 +4332,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
focusPaused = theFocus.mToken.paused;
}
}
-
+
public String toString() {
return "{{" + event + " to " + focus + " @ " + time
+ " lw=" + lastWin + " lb=" + lastBinder
@@ -4307,10 +4351,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public static final int RETURN_NOTHING = 0;
public static final int RETURN_PENDING_POINTER = 1;
public static final int RETURN_PENDING_TRACKBALL = 2;
-
+
final Object SKIP_TARGET_TOKEN = new Object();
final Object CONSUMED_EVENT_TOKEN = new Object();
-
+
private WindowState mLastWin = null;
private IBinder mLastBinder = null;
private boolean mFinished = true;
@@ -4318,10 +4362,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
private boolean mEventDispatching = true;
private long mTimeToSwitch = 0;
/* package */ boolean mWasFrozen = false;
-
+
// Target of Motion events
WindowState mMotionTarget;
-
+
// Windows above the target who would like to receive an "outside"
// touch event for any down events outside of them.
WindowState mOutsideTouchTargets;
@@ -4366,9 +4410,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
targetWin = (WindowState)target;
}
-
+
AppWindowToken targetApp = null;
-
+
// Now: is it okay to send the next event to this window?
synchronized (this) {
// First: did we come here based on the last window not
@@ -4377,7 +4421,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (!targetIsNew && mLastWin == null) {
continue;
}
-
+
// We never dispatch events if not finished with the
// last one, or the display is frozen.
if (mFinished && !mDisplayFrozen) {
@@ -4396,7 +4440,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (targetIsNew && !targetWin.mToken.paused) {
return targetWin;
}
-
+
// If we didn't find a target window, and there is no
// focused app window, then just eat the events.
} else if (mFocusedApp == null) {
@@ -4406,7 +4450,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return null;
}
}
-
+
if (DEBUG_INPUT) Log.v(
TAG, "Waiting for last key in " + mLastBinder
+ " target=" + targetWin
@@ -4417,10 +4461,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ (targetWin != null ? targetWin.mToken.paused : false)
+ " mFocusedApp=" + mFocusedApp
+ " mCurrentFocus=" + mCurrentFocus);
-
+
targetApp = targetWin != null
? targetWin.mAppToken : mFocusedApp;
-
+
long curTimeout = keyDispatchingTimeout;
if (mTimeToSwitch != 0) {
long now = SystemClock.uptimeMillis();
@@ -4436,7 +4480,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
curTimeout = switchTimeout;
}
}
-
+
try {
// after that continue
// processing keys, so we don't get stuck.
@@ -4500,7 +4544,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
synchronized (this) {
if (abort && (mLastWin == targetWin || targetWin == null)) {
mFinished = true;
- if (mLastWin != null) {
+ if (mLastWin != null) {
if (DEBUG_INPUT) Log.v(TAG,
"Window " + mLastWin +
" timed out on key input");
@@ -4525,11 +4569,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
MotionEvent nextMotion, boolean isPointerEvent) {
mOutsideTouchTargets = null;
-
+
if (nextKey != null) {
// Find the target window for a normal key event.
final int keycode = nextKey.getKeyCode();
@@ -4543,23 +4587,23 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ nextKey);
return SKIP_TARGET_TOKEN;
}
-
+
// System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
-
+
WindowState focus = null;
synchronized(mWindowMap) {
focus = getFocusedWindowLocked();
}
-
+
wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
-
+
if (mPolicy.interceptKeyTi(focus,
keycode, nextKey.getMetaState(), down, repeatCount)) {
return CONSUMED_EVENT_TOKEN;
}
-
+
return focus;
-
+
} else if (!isPointerEvent) {
boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
if (!dispatch) {
@@ -4567,20 +4611,20 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ nextMotion);
return SKIP_TARGET_TOKEN;
}
-
+
WindowState focus = null;
synchronized(mWindowMap) {
focus = getFocusedWindowLocked();
}
-
+
wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
return focus;
}
-
+
if (nextMotion == null) {
return SKIP_TARGET_TOKEN;
}
-
+
boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
KeyEvent.KEYCODE_UNKNOWN);
if (!dispatch) {
@@ -4588,18 +4632,18 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ nextMotion);
return SKIP_TARGET_TOKEN;
}
-
+
// Find the target window for a pointer event.
int action = nextMotion.getAction();
final float xf = nextMotion.getX();
final float yf = nextMotion.getY();
final long eventTime = nextMotion.getEventTime();
-
+
final boolean screenWasOff = qev != null
&& (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
-
+
WindowState target = null;
-
+
synchronized(mWindowMap) {
synchronized (this) {
if (action == MotionEvent.ACTION_DOWN) {
@@ -4612,12 +4656,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ mMotionTarget);
mMotionTarget = null;
}
-
+
// ACTION_DOWN is special, because we need to lock next events to
// the window we'll land onto.
final int x = (int)xf;
final int y = (int)yf;
-
+
final ArrayList windows = mWindows;
final int N = windows.size();
WindowState topErrWindow = null;
@@ -4678,7 +4722,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
break;
}
-
+
if ((flags & WindowManager.LayoutParams
.FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
child.mNextOutsideTouch = mOutsideTouchTargets;
@@ -4695,18 +4739,18 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mMotionTarget = null;
}
}
-
+
target = mMotionTarget;
}
}
-
+
wakeupIfNeeded(target, eventType(nextMotion));
-
+
// Pointer events are a little different -- if there isn't a
// target found for any event, then just drop it.
return target != null ? target : SKIP_TARGET_TOKEN;
}
-
+
boolean checkShouldDispatchKey(int keycode) {
synchronized (this) {
if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
@@ -4720,14 +4764,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return true;
}
}
-
+
void bindTargetWindowLocked(WindowState win,
int pendingWhat, QueuedEvent pendingMotion) {
synchronized (this) {
bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
}
}
-
+
void bindTargetWindowLocked(WindowState win) {
synchronized (this) {
bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
@@ -4745,7 +4789,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
releasePendingPointerLocked(s);
s.mPendingPointerMove = pendingMotion;
s.mPendingPointerWindow = win;
- if (DEBUG_INPUT) Log.v(TAG,
+ if (DEBUG_INPUT) Log.v(TAG,
"bindTargetToWindow " + s.mPendingPointerMove);
} else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
releasePendingTrackballLocked(s);
@@ -4754,7 +4798,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
void releasePendingPointerLocked(Session s) {
if (DEBUG_INPUT) Log.v(TAG,
"releasePendingPointer " + s.mPendingPointerMove);
@@ -4763,14 +4807,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
s.mPendingPointerMove = null;
}
}
-
+
void releasePendingTrackballLocked(Session s) {
if (s.mPendingTrackballMove != null) {
mQueue.recycleEvent(s.mPendingTrackballMove);
s.mPendingTrackballMove = null;
}
}
-
+
MotionEvent finishedKey(Session session, IWindow client, boolean force,
int returnWhat) {
if (DEBUG_INPUT) Log.v(
@@ -4799,7 +4843,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
session.mPendingTrackballMove = null;
session.mPendingTrackballWindow = null;
}
-
+
if (mLastBinder == client.asBinder()) {
if (DEBUG_INPUT) Log.v(
TAG, "finishedKey: last paused="
@@ -4815,7 +4859,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
notifyAll();
}
}
-
+
if (qev != null) {
MotionEvent res = (MotionEvent)qev.event;
if (DEBUG_INPUT) Log.v(TAG,
@@ -4835,7 +4879,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
notifyAll();
}
}
-
+
void handleNewWindowLocked(WindowState newWindow) {
if (!newWindow.canReceiveKeys()) {
return;
@@ -4936,7 +4980,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
notifyAll();
}
}
-
+
void appSwitchComing() {
synchronized (this) {
// Don't wait for more than .5 seconds for app to finish
@@ -4949,13 +4993,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
notifyAll();
}
}
-
+
private final void doFinishedKeyLocked(boolean doRecycle) {
if (mLastWin != null) {
releasePendingPointerLocked(mLastWin.mSession);
releasePendingTrackballLocked(mLastWin.mSession);
}
-
+
if (mLastWin == null || !mLastWin.mToken.paused
|| !mLastWin.isVisibleLw()) {
// If the current window has been paused, we aren't -really-
@@ -4971,7 +5015,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
private class KeyQ extends KeyInputQueue
implements KeyInputQueue.FilterCallback {
PowerManager.WakeLock mHoldingScreen;
-
+
KeyQ() {
super(mContext);
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
@@ -4985,7 +5029,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (mPolicy.preprocessInputEventTq(event)) {
return true;
}
-
+
switch (event.type) {
case RawInputEvent.EV_KEY: {
// XXX begin hack
@@ -5005,11 +5049,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
// XXX end hack
-
+
boolean screenIsOff = !mPowerManager.screenIsOn();
boolean screenIsDim = !mPowerManager.screenIsBright();
int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
-
+
if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
mPowerManager.goToSleep(event.when);
}
@@ -5024,7 +5068,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mPowerManager.userActivity(event.when, false,
LocalPowerManager.BUTTON_EVENT, false);
}
-
+
if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
filterQueue(this);
@@ -5035,7 +5079,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return false;
}
}
-
+
case RawInputEvent.EV_REL: {
boolean screenIsOff = !mPowerManager.screenIsOn();
boolean screenIsDim = !mPowerManager.screenIsBright();
@@ -5052,7 +5096,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return true;
}
-
+
case RawInputEvent.EV_ABS: {
boolean screenIsOff = !mPowerManager.screenIsOn();
boolean screenIsDim = !mPowerManager.screenIsBright();
@@ -5069,7 +5113,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return true;
}
-
+
default:
return true;
}
@@ -5089,7 +5133,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return FILTER_KEEP;
}
}
-
+
/**
* Must be called with the main window manager lock held.
*/
@@ -5110,11 +5154,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mSafeMode = mPolicy.detectSafeMode();
return mSafeMode;
}
-
+
public void systemReady() {
mPolicy.systemReady();
}
-
+
private final class InputDispatcherThread extends Thread {
// Time to wait when there is nothing to do: 9999 seconds.
static final int LONG_WAIT=9999*1000;
@@ -5122,7 +5166,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public InputDispatcherThread() {
super("InputDispatcher");
}
-
+
@Override
public void run() {
while (true) {
@@ -5133,11 +5177,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
private void process() {
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
-
+
// The last key event we saw
KeyEvent lastKey = null;
@@ -5145,12 +5189,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
long lastKeyTime = SystemClock.uptimeMillis();
long nextKeyTime = lastKeyTime+LONG_WAIT;
- // How many successive repeats we generated
+ // How many successive repeats we generated
int keyRepeatCount = 0;
// Need to report that configuration has changed?
boolean configChanged = false;
-
+
while (true) {
long curTime = SystemClock.uptimeMillis();
@@ -5247,14 +5291,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mQueue.recycleEvent(ev);
break;
}
-
+
} else if (configChanged) {
configChanged = false;
sendNewConfiguration();
-
+
} else if (lastKey != null) {
curTime = SystemClock.uptimeMillis();
-
+
// Timeout occurred while key was down. If it is at or
// past the key repeat time, dispatch the repeat.
if (DEBUG_INPUT) Log.v(
@@ -5263,7 +5307,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (curTime < nextKeyTime) {
continue;
}
-
+
lastKeyTime = nextKeyTime;
nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
keyRepeatCount++;
@@ -5271,14 +5315,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
TAG, "Key repeat: count=" + keyRepeatCount
+ ", next @ " + nextKeyTime);
dispatchKey(KeyEvent.changeTimeRepeat(lastKey, curTime, keyRepeatCount), 0, 0);
-
+
} else {
curTime = SystemClock.uptimeMillis();
-
+
lastKeyTime = curTime;
nextKeyTime = curTime + LONG_WAIT;
}
-
+
} catch (Exception e) {
Log.e(TAG,
"Input thread received uncaught exception: " + e, e);
@@ -5301,14 +5345,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
SurfaceSession mSurfaceSession;
int mNumWindow = 0;
boolean mClientDead = false;
-
+
/**
* Current pointer move event being dispatched to client window... must
* hold key lock to access.
*/
QueuedEvent mPendingPointerMove;
WindowState mPendingPointerWindow;
-
+
/**
* Current trackball move event being dispatched to client window... must
* hold key lock to access.
@@ -5328,7 +5372,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
sb.append(mUid);
sb.append("}");
mStringName = sb.toString();
-
+
synchronized (mWindowMap) {
if (mInputMethodManager == null && mHaveInputMethods) {
IBinder b = ServiceManager.getService(
@@ -5359,7 +5403,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Binder.restoreCallingIdentity(ident);
}
}
-
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -5393,11 +5437,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int viewVisibility, Rect outContentInsets) {
return addWindow(this, window, attrs, viewVisibility, outContentInsets);
}
-
+
public void remove(IWindow window) {
removeWindow(this, window);
}
-
+
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
boolean insetsPending, Rect outFrame, Rect outContentInsets,
@@ -5406,21 +5450,21 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
requestedWidth, requestedHeight, viewFlags, insetsPending,
outFrame, outContentInsets, outVisibleInsets, outSurface);
}
-
+
public void setTransparentRegion(IWindow window, Region region) {
setTransparentRegionWindow(this, window, region);
}
-
+
public void setInsets(IWindow window, int touchableInsets,
Rect contentInsets, Rect visibleInsets) {
setInsetsWindow(this, window, touchableInsets, contentInsets,
visibleInsets);
}
-
+
public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
getWindowDisplayFrame(this, window, outDisplayFrame);
}
-
+
public void finishDrawing(IWindow window) {
if (localLOGV) Log.v(
TAG, "IWindow finishDrawing called for " + window);
@@ -5440,7 +5484,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return mKeyWaiter.finishedKey(this, window, false,
KeyWaiter.RETURN_PENDING_POINTER);
}
-
+
public MotionEvent getPendingTrackballMove(IWindow window) {
if (localLOGV) Log.v(
TAG, "IWindow getPendingMotionEvent called for " + window);
@@ -5472,7 +5516,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Log.v(
@@ -5487,7 +5531,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mNumWindow--;
killSessionLocked();
}
-
+
void killSessionLocked() {
if (mNumWindow <= 0 && mClientDead) {
mSessions.remove(this);
@@ -5506,7 +5550,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
pw.print(" mClientDead="); pw.print(mClientDead);
@@ -5567,11 +5611,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean mHaveFrame;
WindowState mNextOutsideTouch;
-
+
// Actual frame shown on-screen (may be modified by animation)
final Rect mShownFrame = new Rect();
final Rect mLastShownFrame = new Rect();
-
+
/**
* Insets that determine the actually visible area
*/
@@ -5591,19 +5635,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* given internal insets before laying out other windows based on it.
*/
boolean mGivenInsetsPending;
-
+
/**
* These are the content insets that were given during layout for
* this window, to be applied to windows behind it.
*/
final Rect mGivenContentInsets = new Rect();
-
+
/**
* These are the visible insets that were given during layout for
* this window, to be applied to windows behind it.
*/
final Rect mGivenVisibleInsets = new Rect();
-
+
/**
* Flag indicating whether the touchable region should be adjusted by
* the visible insets; if false the area outside the visible insets is
@@ -5611,7 +5655,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
* tests.
*/
int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
-
+
// Current transformation being applied.
float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
@@ -5650,7 +5694,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// where we don't yet have a surface, but should have one soon, so
// we can give the window focus before waiting for the relayout.
boolean mRelayoutCalled;
-
+
// 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;
@@ -5665,7 +5709,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// to delay showing the surface until all windows in a token are ready
// to be shown.
boolean mReadyToShow;
-
+
// Set when the window has been shown in the screen the first time.
boolean mHasDrawn;
@@ -5674,17 +5718,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Currently on the mDestroySurface list?
boolean mDestroying;
-
+
// Completely remove from window manager after exit animation?
boolean mRemoveOnExit;
// Set when the orientation is changing and this window has not yet
// been updated for the new orientation.
boolean mOrientationChanging;
-
+
// Is this window now (or just being) removed?
boolean mRemoved;
-
+
WindowState(Session s, IWindow c, WindowToken token,
WindowState attachedWindow, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -5710,7 +5754,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return;
}
mDeathRecipient = deathRecipient;
-
+
if ((mAttrs.type >= FIRST_SUB_WINDOW &&
mAttrs.type <= LAST_SUB_WINDOW)) {
// The multiplier here is to reserve space for multiple
@@ -5786,7 +5830,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
w = mAttrs.width == mAttrs.FILL_PARENT ? pw : mRequestedWidth;
h = mAttrs.height== mAttrs.FILL_PARENT ? ph : mRequestedHeight;
}
-
+
final Rect container = mContainingFrame;
container.set(pf);
@@ -5795,12 +5839,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
final Rect content = mContentFrame;
content.set(cf);
-
+
final Rect visible = mVisibleFrame;
visible.set(vf);
-
+
final Rect frame = mFrame;
-
+
//System.out.println("In: w=" + w + " h=" + h + " container=" +
// container + " x=" + mAttrs.x + " y=" + mAttrs.y);
@@ -5812,7 +5856,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Now make sure the window fits in the overall display.
Gravity.applyDisplay(mAttrs.gravity, df, frame);
-
+
// Make sure the content and visible frames are inside of the
// final window frame.
if (content.left < frame.left) content.left = frame.left;
@@ -5823,19 +5867,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (visible.top < frame.top) visible.top = frame.top;
if (visible.right > frame.right) visible.right = frame.right;
if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
-
+
final Rect contentInsets = mContentInsets;
contentInsets.left = content.left-frame.left;
contentInsets.top = content.top-frame.top;
contentInsets.right = frame.right-content.right;
contentInsets.bottom = frame.bottom-content.bottom;
-
+
final Rect visibleInsets = mVisibleInsets;
visibleInsets.left = visible.left-frame.left;
visibleInsets.top = visible.top-frame.top;
visibleInsets.right = frame.right-visible.right;
visibleInsets.bottom = frame.bottom-visible.bottom;
-
+
if (localLOGV) {
//if ("com.google.android.youtube".equals(mAttrs.packageName)
// && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
@@ -5848,7 +5892,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
//}
}
}
-
+
public Rect getFrameLw() {
return mFrame;
}
@@ -5876,11 +5920,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public Rect getGivenContentInsetsLw() {
return mGivenContentInsets;
}
-
+
public Rect getGivenVisibleInsetsLw() {
return mGivenVisibleInsets;
}
-
+
public WindowManager.LayoutParams getAttrs() {
return mAttrs;
}
@@ -5888,7 +5932,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public int getSurfaceLayer() {
return mLayer;
}
-
+
public IApplicationToken getAppToken() {
return mAppToken != null ? mAppToken.appToken : null;
}
@@ -5922,7 +5966,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mAnimation = null;
}
}
-
+
Surface createSurfaceLocked() {
if (mSurface == null) {
mDrawPending = true;
@@ -5962,7 +6006,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
try {
mSurface = new Surface(
- mSession.mSurfaceSession, mSession.mPid,
+ mSession.mSurfaceSession, mSession.mPid,
0, w, h, mAttrs.format, flags);
} catch (Surface.OutOfResourcesException e) {
Log.w(TAG, "OutOfResourcesException creating surface");
@@ -5972,7 +6016,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Log.e(TAG, "Exception creating surface", e);
return null;
}
-
+
if (localLOGV) Log.v(
TAG, "Got surface: " + mSurface
+ ", set left=" + mFrame.left + " top=" + mFrame.top
@@ -6009,7 +6053,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return mSurface;
}
-
+
void destroySurfaceLocked() {
// Window is no longer on-screen, so can no longer receive
// key events... if we were waiting for it to finish
@@ -6022,7 +6066,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (mAppToken != null && this == mAppToken.startingWindow) {
mAppToken.startingDisplayed = false;
}
-
+
if (localLOGV) Log.v(
TAG, "Window " + this
+ " destroying surface " + mSurface + ", session " + mSession);
@@ -6112,7 +6156,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
enableScreenIfNeededLocked();
applyEnterAnimationLocked(this);
-
+
int i = mChildWindows.size();
while (i > 0) {
i--;
@@ -6122,7 +6166,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
c.performShowLocked();
}
}
-
+
if (mAttrs.type != TYPE_APPLICATION_STARTING
&& mAppToken != null) {
mAppToken.firstWindowDrawn = true;
@@ -6138,13 +6182,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return true;
}
-
+
// This must be called while inside a transaction. Returns true if
// there is more animation to run.
boolean stepAnimationLocked(long currentTime, int dw, int dh) {
if (!mDisplayFrozen) {
// We will run animations as long as the display isn't frozen.
-
+
if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
mHasTransformation = true;
mHasLocalTransformation = true;
@@ -6202,7 +6246,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mLocalAnimating = true;
mAnimation = null;
}
-
+
if (!mAnimating && !mLocalAnimating) {
return false;
}
@@ -6211,7 +6255,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
TAG, "Animation done in " + this + ": exiting=" + mExiting
+ ", reportedVisible="
+ (mAppToken != null ? mAppToken.reportedVisible : false));
-
+
mAnimating = false;
mLocalAnimating = false;
mAnimation = null;
@@ -6235,7 +6279,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mFinishedStarting.add(mAppToken);
mH.sendEmptyMessage(H.FINISHED_STARTING);
}
-
+
finishExit();
if (mAppToken != null) {
@@ -6251,16 +6295,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ ": exiting=" + mExiting
+ " remove=" + mRemoveOnExit
+ " windowAnimating=" + isWindowAnimating());
-
+
final int N = mChildWindows.size();
for (int i=0; i<N; i++) {
((WindowState)mChildWindows.get(i)).finishExit();
}
-
+
if (!mExiting) {
return;
}
-
+
if (isWindowAnimating()) {
return;
}
@@ -6287,7 +6331,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mRemoveOnExit = false;
}
}
-
+
boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
if (dsdx < .99999f || dsdx > 1.00001f) return false;
if (dtdy < .99999f || dtdy > 1.00001f) return false;
@@ -6295,7 +6339,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (dsdy < -.000001f || dsdy > .000001f) return false;
return true;
}
-
+
void computeShownFrameLocked() {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation =
@@ -6306,7 +6350,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
? mAppToken.transformation : null;
if (selfTransformation || attachedTransformation != null
|| appTransformation != null) {
- // cache often used attributes locally
+ // cache often used attributes locally
final Rect frame = mFrame;
final float tmpFloats[] = mTmpFloats;
final Matrix tmpMatrix = mTmpMatrix;
@@ -6328,7 +6372,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Here we must not transform the position of the surface
// since it is already included in the transformation.
//Log.i(TAG, "Transform: " + matrix);
-
+
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_X];
@@ -6363,14 +6407,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
//Log.i(TAG, "Not applying alpha transform");
}
-
+
if (localLOGV) Log.v(
TAG, "Continuing animation in " + this +
": " + mShownFrame +
", alpha=" + mTransformation.getAlpha());
return;
}
-
+
mShownFrame.set(mFrame);
mShownAlpha = mAlpha;
mDsDx = 1;
@@ -6378,7 +6422,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mDsDy = 0;
mDtDy = 1;
}
-
+
/**
* Is this window visible? It is not visible if there is no
* surface, or we are in the process of running an exit animation
@@ -6441,7 +6485,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
&& (!mAttachedHidden || mAnimating);
}
}
-
+
/**
* Like isOnScreen(), but we don't return true if the window is part
* of a transition that has not yet been started.
@@ -6460,7 +6504,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
final AppWindowToken atoken = mAppToken;
return mAnimation != null
|| (attached != null && attached.mAnimation != null)
- || (atoken != null &&
+ || (atoken != null &&
(atoken.animation != null
|| atoken.inPendingTransaction));
}
@@ -6502,7 +6546,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return false;
}
-
+
boolean isFullscreenOpaque(int screenWidth, int screenHeight) {
if (mAttrs.format != PixelFormat.OPAQUE || mSurface == null
|| mAnimation != null || mDrawPending || mCommitDrawPending) {
@@ -6594,7 +6638,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
void dump(PrintWriter pw, String prefix) {
StringBuilder sb = new StringBuilder(64);
-
+
pw.print(prefix); pw.print("mSession="); pw.print(mSession);
pw.print(" mClient="); pw.println(mClient.asBinder());
pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
@@ -6710,7 +6754,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
}
}
-
+
// -------------------------------------------------------------
// Window Token State
// -------------------------------------------------------------
@@ -6721,17 +6765,17 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// The type of window this token is for, as per WindowManager.LayoutParams.
final int windowType;
-
+
// Set if this token was explicitly added by a client, so should
// not be removed when all windows are removed.
final boolean explicit;
-
+
// For printing.
String stringName;
-
+
// If this is an AppWindowToken, this is non-null.
AppWindowToken appWindowToken;
-
+
// All of the windows associated with this token.
final ArrayList<WindowState> windows = new ArrayList<WindowState>();
@@ -6782,7 +6826,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int groupId = -1;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
+
// These are used for determining when all windows associated with
// an activity have been drawn, so they can be made visible together
// at the same time.
@@ -6791,20 +6835,20 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int numDrawnWindows;
boolean inPendingTransaction;
boolean allDrawn;
-
+
// Is this token going to be hidden in a little while? If so, it
// won't be taken into account for setting the screen orientation.
boolean willBeHidden;
-
+
// Is this window's surface needed? This is almost like hidden, except
// it will sometimes be true a little earlier: when the token has
// been shown, but is still waiting for its app transition to execute
// before making its windows shown.
boolean hiddenRequested;
-
+
// Have we told the window clients to hide themselves?
boolean clientHidden;
-
+
// Last visibility state we reported to the app token.
boolean reportedVisible;
@@ -6813,16 +6857,16 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Have we been asked to have this token keep the screen frozen?
boolean freezingScreen;
-
+
boolean animating;
Animation animation;
boolean hasTransformation;
final Transformation transformation = new Transformation();
-
+
// Offset to the window of all layers in the token, for use by
// AppWindowToken animations.
int animLayerAdjustment;
-
+
// Information about an application starting window if displayed.
StartingData startingData;
WindowState startingWindow;
@@ -6837,7 +6881,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
appWindowToken = this;
appToken = _token;
}
-
+
public void setAnimation(Animation anim) {
if (localLOGV) Log.v(
TAG, "Setting animation in " + this + ": " + anim);
@@ -6852,13 +6896,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else if (zorder == Animation.ZORDER_BOTTOM) {
adj = -TYPE_LAYER_OFFSET;
}
-
+
if (animLayerAdjustment != adj) {
animLayerAdjustment = adj;
updateLayers();
}
}
-
+
public void setDummyAnimation() {
if (animation == null) {
if (localLOGV) Log.v(
@@ -6873,7 +6917,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
animating = true;
}
}
-
+
void updateLayers() {
final int N = allAppWindows.size();
final int adj = animLayerAdjustment;
@@ -6887,7 +6931,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
void sendAppVisibilityToClients() {
final int N = allAppWindows.size();
for (int i=0; i<N; i++) {
@@ -6904,7 +6948,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
void showAllWindowsLocked() {
final int NW = allAppWindows.size();
for (int i=0; i<NW; i++) {
@@ -6914,12 +6958,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
w.performShowLocked();
}
}
-
+
// This must be called while inside a transaction.
boolean stepAnimationLocked(long currentTime, int dw, int dh) {
if (!mDisplayFrozen) {
// We will run animations as long as the display isn't frozen.
-
+
if (animation == sDummyAnimation) {
// This guy is going to animate, but not yet. For now count
// it is not animating for purposes of scheduling transactions;
@@ -6927,7 +6971,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// a real animation and the next call will execute normally.
return false;
}
-
+
if ((allDrawn || animating || startingDisplayed) && animation != null) {
if (!animating) {
if (DEBUG_ANIM) Log.v(
@@ -6963,7 +7007,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
hasTransformation = false;
-
+
if (!animating) {
return false;
}
@@ -6973,7 +7017,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
moveInputMethodWindowsIfNeededLocked(true);
}
-
+
if (DEBUG_ANIM) Log.v(
TAG, "Animation done in " + this
+ ": reportedVisible=" + reportedVisible);
@@ -6983,13 +7027,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
animLayerAdjustment = 0;
updateLayers();
}
-
+
final int N = windows.size();
for (int i=0; i<N; i++) {
((WindowState)windows.get(i)).finishExit();
}
updateReportedVisibilityLocked();
-
+
return false;
}
@@ -6997,11 +7041,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (appToken == null) {
return;
}
-
+
int numInteresting = 0;
int numVisible = 0;
boolean nowGone = true;
-
+
if (DEBUG_VISIBILITY) Log.v(TAG, "Update reported visibility: " + this);
final int N = allAppWindows.size();
for (int i=0; i<N; i++) {
@@ -7035,7 +7079,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
nowGone = false;
}
}
-
+
boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
if (DEBUG_VISIBILITY) Log.v(TAG, "VIS " + this + ": interesting="
+ numInteresting + " visible=" + numVisible);
@@ -7052,7 +7096,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mH.sendMessage(m);
}
}
-
+
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
if (appToken != null) {
@@ -7117,7 +7161,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return stringName;
}
}
-
+
public static WindowManager.LayoutParams findAnimations(
ArrayList<AppWindowToken> order,
ArrayList<AppWindowToken> tokenList1,
@@ -7125,7 +7169,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// We need to figure out which animation to use...
WindowManager.LayoutParams animParams = null;
int animSrc = 0;
-
+
//Log.i(TAG, "Looking for animations...");
for (int i=order.size()-1; i>=0; i--) {
AppWindowToken wtoken = order.get(i);
@@ -7154,10 +7198,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
return animParams;
}
-
+
// -------------------------------------------------------------
// DummyAnimation
// -------------------------------------------------------------
@@ -7171,7 +7215,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
static final Animation sDummyAnimation = new DummyAnimation();
-
+
// -------------------------------------------------------------
// Async Handler
// -------------------------------------------------------------
@@ -7182,7 +7226,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
final CharSequence nonLocalizedLabel;
final int labelRes;
final int icon;
-
+
StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
int _labelRes, int _icon) {
pkg = _pkg;
@@ -7209,19 +7253,19 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
public static final int ENABLE_SCREEN = 16;
public static final int APP_FREEZE_TIMEOUT = 17;
public static final int COMPUTE_AND_SEND_NEW_CONFIGURATION = 18;
-
+
private Session mLastReportedHold;
-
+
public H() {
}
-
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REPORT_FOCUS_CHANGE: {
WindowState lastFocus;
WindowState newFocus;
-
+
synchronized(mWindowMap) {
lastFocus = mLastFocus;
newFocus = mCurrentFocus;
@@ -7265,7 +7309,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
case REPORT_LOSING_FOCUS: {
ArrayList<WindowState> losers;
-
+
synchronized(mWindowMap) {
losers = mLosingFocus;
mLosingFocus = new ArrayList<WindowState>();
@@ -7297,10 +7341,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Animation has been canceled... do nothing.
return;
}
-
+
if (DEBUG_STARTING_WINDOW) Log.v(TAG, "Add starting "
+ wtoken + ": pkg=" + sd.pkg);
-
+
View view = null;
try {
view = mPolicy.addStartingWindow(
@@ -7427,7 +7471,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} catch (RemoteException ex) {
}
} break;
-
+
case WINDOW_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
Log.w(TAG, "Window freeze timeout expired.");
@@ -7444,7 +7488,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
break;
}
-
+
case HOLD_SCREEN_CHANGED: {
Session oldHold;
Session newHold;
@@ -7453,7 +7497,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
newHold = (Session)msg.obj;
mLastReportedHold = newHold;
}
-
+
if (oldHold != newHold) {
try {
if (oldHold != null) {
@@ -7471,7 +7515,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
break;
}
-
+
case APP_TRANSITION_TIMEOUT: {
synchronized (mWindowMap) {
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
@@ -7484,7 +7528,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
break;
}
-
+
case PERSIST_ANIMATION_SCALE: {
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
@@ -7492,7 +7536,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
break;
}
-
+
case FORCE_GC: {
synchronized(mWindowMap) {
if (mAnimationPending) {
@@ -7512,12 +7556,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Runtime.getRuntime().gc();
break;
}
-
+
case ENABLE_SCREEN: {
performEnableScreen();
break;
}
-
+
case APP_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
Log.w(TAG, "App freeze timeout expired.");
@@ -7533,14 +7577,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
break;
}
-
+
case COMPUTE_AND_SEND_NEW_CONFIGURATION: {
- if (updateOrientationFromAppTokens(null, null) != null) {
+ if (updateOrientationFromAppTokensUnchecked(null, null) != null) {
sendNewConfiguration();
}
break;
}
-
+
}
}
}
@@ -7574,7 +7618,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return false;
}
-
+
// -------------------------------------------------------------
// Internals
// -------------------------------------------------------------
@@ -7582,7 +7626,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
final WindowState windowForClientLocked(Session session, IWindow client) {
return windowForClientLocked(session, client.asBinder());
}
-
+
final WindowState windowForClientLocked(Session session, IBinder client) {
WindowState win = mWindowMap.get(client);
if (localLOGV) Log.v(
@@ -7607,7 +7651,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int curBaseLayer = 0;
int curLayer = 0;
int i;
-
+
for (i=0; i<N; i++) {
WindowState w = (WindowState)mWindows.get(i);
if (w.mBaseLayer == curBaseLayer || w.mIsImWindow) {
@@ -7663,11 +7707,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
mInLayout = true;
try {
performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
-
+
int i = mPendingRemove.size()-1;
if (i >= 0) {
while (i >= 0) {
@@ -7703,7 +7747,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
int i;
// FIRST LOOP: Perform a layout, if needed.
-
+
while (mLayoutNeeded) {
mPolicy.beginLayoutLw(dw, dh);
@@ -7738,7 +7782,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
// Now perform layout of attached windows, which usually
// depend on the position of the window they are attached to.
// XXX does not deal with windows that are attached to windows
@@ -7769,7 +7813,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
private final void performLayoutAndPlaceSurfacesLockedInner(
boolean recoveringMemory) {
final long currentTime = SystemClock.uptimeMillis();
@@ -7781,11 +7825,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// FIRST LOOP: Perform a layout, if needed.
performLayoutLockedInner();
-
+
if (mFxSession == null) {
mFxSession = new SurfaceSession();
}
-
+
if (SHOW_TRANSACTIONS) Log.i(TAG, ">>> OPEN TRANSACTION");
// Initialize state of exiting tokens.
@@ -8109,7 +8153,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
!w.mLastContentInsets.equals(w.mContentInsets);
w.mVisibleInsetsChanged =
!w.mLastVisibleInsets.equals(w.mVisibleInsets);
- if (!w.mLastFrame.equals(w.mFrame)
+ if (!w.mLastFrame.equals(w.mFrame)
|| w.mContentInsetsChanged
|| w.mVisibleInsetsChanged) {
w.mLastFrame.set(w.mFrame);
@@ -8131,7 +8175,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
w.mAppToken.allDrawn = false;
}
}
- if (DEBUG_ORIENTATION) Log.v(TAG,
+ if (DEBUG_ORIENTATION) Log.v(TAG,
"Resizing window " + w + " to " + w.mFrame);
mResizingWindows.add(w);
} else if (w.mOrientationChanging) {
@@ -8321,7 +8365,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (SHOW_TRANSACTIONS) Log.i(TAG, " DIM "
+ mDimSurface + ": CREATE");
try {
- mDimSurface = new Surface(mFxSession, 0,
+ mDimSurface = new Surface(mFxSession, 0,
-1, 16, 16,
PixelFormat.OPAQUE,
Surface.FX_SURFACE_DIM);
@@ -8376,7 +8420,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
if (SHOW_TRANSACTIONS) Log.i(TAG, " BLUR "
+ mBlurSurface + ": CREATE");
try {
- mBlurSurface = new Surface(mFxSession, 0,
+ mBlurSurface = new Surface(mFxSession, 0,
-1, 16, 16,
PixelFormat.OPAQUE,
Surface.FX_SURFACE_BLUR);
@@ -8430,7 +8474,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
more = false;
}
-
+
// Do we need to continue animating?
if (more) {
if (SHOW_TRANSACTIONS) Log.i(TAG, " DIM "
@@ -8456,7 +8500,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
if (!blurring && mBlurShown) {
if (SHOW_TRANSACTIONS) Log.i(TAG, " BLUR " + mBlurSurface
+ ": HIDE");
@@ -8474,7 +8518,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
Surface.closeTransaction();
-
+
if (DEBUG_ORIENTATION && mDisplayFrozen) Log.v(TAG,
"With display frozen, orientationChangeComplete="
+ orientationChangeComplete);
@@ -8487,7 +8531,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
stopFreezingDisplayLocked();
}
}
-
+
i = mResizingWindows.size();
if (i > 0) {
do {
@@ -8505,7 +8549,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} while (i > 0);
mResizingWindows.clear();
}
-
+
// Destroy the surface of any windows that are no longer visible.
i = mDestroySurface.size();
if (i > 0) {
@@ -8564,13 +8608,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
}
}
-
+
/**
* Have the surface flinger show a surface, robustly dealing with
* error conditions. In particular, if there is not enough memory
* to show the surface, then we will try to get rid of other surfaces
* in order to succeed.
- *
+ *
* @return Returns true if the surface was successfully shown.
*/
boolean showSurfaceRobustlyLocked(WindowState win) {
@@ -8582,22 +8626,22 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} catch (RuntimeException e) {
Log.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
}
-
+
reclaimSomeSurfaceMemoryLocked(win, "show");
-
+
return false;
}
-
+
void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
final Surface surface = win.mSurface;
-
+
EventLog.writeEvent(LOG_WM_NO_SURFACE_MEMORY, win.toString(),
win.mSession.mPid, operation);
-
+
if (mForceRemoves == null) {
mForceRemoves = new ArrayList<WindowState>();
}
-
+
long callingIdentity = Binder.clearCallingIdentity();
try {
// There was some problem... first, do a sanity check of the
@@ -8631,7 +8675,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
boolean killedApps = false;
if (!leakedSurface) {
Log.w(TAG, "No leaked surfaces; killing applicatons!");
@@ -8655,7 +8699,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
}
-
+
if (leakedSurface || killedApps) {
// We managed to reclaim some memory, so get rid of the trouble
// surface and ask the app to request another one.
@@ -8664,7 +8708,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
surface.clear();
win.mSurface = null;
}
-
+
try {
win.mClient.dispatchGetNewSurface();
} catch (RemoteException e) {
@@ -8674,7 +8718,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
Binder.restoreCallingIdentity(callingIdentity);
}
}
-
+
private boolean updateFocusedWindowLocked(int mode) {
WindowState newFocus = computeFocusedWindowLocked();
if (mCurrentFocus != newFocus) {
@@ -8687,7 +8731,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
final WindowState oldFocus = mCurrentFocus;
mCurrentFocus = newFocus;
mLosingFocus.remove(newFocus);
-
+
final WindowState imWindow = mInputMethodWindow;
if (newFocus != imWindow && oldFocus != imWindow) {
if (moveInputMethodWindowsIfNeededLocked(
@@ -8703,7 +8747,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
assignLayersLocked();
}
}
-
+
if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
mKeyWaiter.handleNewWindowLocked(newFocus);
}
@@ -8731,13 +8775,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ ", canReceive=" + win.canReceiveKeys());
AppWindowToken thisApp = win.mAppToken;
-
+
// If this window's application has been removed, just skip it.
if (thisApp != null && thisApp.removed) {
i--;
continue;
}
-
+
// If there is a focused app, don't allow focus to go to any
// windows below it. If this is an application window, step
// through the app tokens until we find its app.
@@ -8794,9 +8838,9 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
return;
}
-
+
mScreenFrozenLock.acquire();
-
+
long now = SystemClock.uptimeMillis();
//Log.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
if (mFreezeGcPending != 0) {
@@ -8809,32 +8853,32 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
} else {
mFreezeGcPending = now;
}
-
+
mDisplayFrozen = true;
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
mAppTransitionReady = true;
}
-
+
if (PROFILE_ORIENTATION) {
File file = new File("/data/system/frozen");
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
Surface.freezeDisplay(0);
}
-
+
private void stopFreezingDisplayLocked() {
if (!mDisplayFrozen) {
return;
}
-
+
mDisplayFrozen = false;
mH.removeMessages(H.APP_FREEZE_TIMEOUT);
if (PROFILE_ORIENTATION) {
Debug.stopMethodTracing();
}
Surface.unfreezeDisplay(0);
-
+
// Reset the key delivery timeout on unfreeze, too. We force a wakeup here
// too because regular key delivery processing should resume immediately.
synchronized (mKeyWaiter) {
@@ -8850,10 +8894,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mH.removeMessages(H.FORCE_GC);
mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
2000);
-
+
mScreenFrozenLock.release();
}
-
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -8863,7 +8907,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
+ ", uid=" + Binder.getCallingUid());
return;
}
-
+
synchronized(mWindowMap) {
pw.println("Current Window Manager state:");
for (int i=mWindows.size()-1; i>=0; i--) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 736c0da..07d6b6f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -17,7 +17,6 @@
package com.android.server.am;
import com.android.internal.os.BatteryStatsImpl;
-import com.android.internal.os.RuntimeInit;
import com.android.server.IntentResolver;
import com.android.server.ProcessMap;
import com.android.server.ProcessStats;
@@ -289,6 +288,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// because the user interacts with it so much.
final int HOME_APP_ADJ;
+ // This is a process currently hosting a backup operation. Killing it
+ // is not entirely fatal but is generally a bad idea.
+ final int BACKUP_APP_ADJ;
+
// This is a process holding a secondary server -- killing it will not
// have much of an impact as far as the user is concerned. Value set in
// system/rootdir/init.rc on startup.
@@ -317,6 +320,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
final int EMPTY_APP_MEM;
final int HIDDEN_APP_MEM;
final int HOME_APP_MEM;
+ final int BACKUP_APP_MEM;
final int SECONDARY_SERVER_MEM;
final int VISIBLE_APP_MEM;
final int FOREGROUND_APP_MEM;
@@ -1358,6 +1362,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
SECONDARY_SERVER_ADJ =
Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
+ BACKUP_APP_ADJ =
+ Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
HOME_APP_ADJ =
Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
HIDDEN_APP_MIN_ADJ =
@@ -1373,6 +1379,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
SECONDARY_SERVER_MEM =
Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
+ BACKUP_APP_MEM =
+ Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
HOME_APP_MEM =
Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
HIDDEN_APP_MEM =
@@ -2752,7 +2760,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// instance of the activity so a new fresh one can be started.
if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
if (!ret.finishing) {
- int index = indexOfTokenLocked(ret, false);
+ int index = indexOfTokenLocked(ret);
if (index >= 0) {
finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
null, "clear");
@@ -2845,7 +2853,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
HistoryRecord sourceRecord = null;
HistoryRecord resultRecord = null;
if (resultTo != null) {
- int index = indexOfTokenLocked(resultTo, false);
+ int index = indexOfTokenLocked(resultTo);
if (DEBUG_RESULTS) Log.v(
TAG, "Sending result to " + resultTo + " (index " + index + ")");
if (index >= 0) {
@@ -3411,7 +3419,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
synchronized (this) {
- int index = indexOfTokenLocked(callingActivity, false);
+ int index = indexOfTokenLocked(callingActivity);
if (index < 0) {
return false;
}
@@ -3561,7 +3569,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
public void setRequestedOrientation(IBinder token,
int requestedOrientation) {
synchronized (this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return;
}
@@ -3583,7 +3591,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
public int getRequestedOrientation(IBinder token) {
synchronized (this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
@@ -3639,7 +3647,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
TAG, "Finishing activity: token=" + token
+ ", result=" + resultCode + ", data=" + resultData);
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return false;
}
@@ -3763,7 +3771,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
int mode) {
- final int index = indexOfTokenLocked(r, false);
+ final int index = indexOfTokenLocked(r);
if (index < 0) {
return null;
}
@@ -3888,7 +3896,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
public final void finishSubActivity(IBinder token, String resultWho,
int requestCode) {
synchronized(this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return;
}
@@ -4438,7 +4446,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
synchronized(this) {
- int index = indexOfTokenLocked(token, true);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return;
}
@@ -5003,7 +5011,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
// Get the activity record.
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
HistoryRecord r = (HistoryRecord)mHistory.get(index);
@@ -5157,7 +5165,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
HistoryRecord r = null;
synchronized (this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
r = (HistoryRecord)mHistory.get(index);
if (!timeout) {
@@ -5188,7 +5196,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
final long origId = Binder.clearCallingIdentity();
synchronized (this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
r = (HistoryRecord)mHistory.get(index);
r.thumbnail = thumbnail;
@@ -5218,7 +5226,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
synchronized (this) {
mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
HistoryRecord r = (HistoryRecord)mHistory.get(index);
if (r.state == ActivityState.DESTROYING) {
@@ -5245,7 +5253,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
private HistoryRecord getCallingRecordLocked(IBinder token) {
- int index = indexOfTokenLocked(token, true);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
HistoryRecord r = (HistoryRecord)mHistory.get(index);
if (r != null) {
@@ -5257,7 +5265,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
public ComponentName getActivityClassForToken(IBinder token) {
synchronized(this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
HistoryRecord r = (HistoryRecord)mHistory.get(index);
return r.intent.getComponent();
@@ -5268,7 +5276,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
public String getPackageForToken(IBinder token) {
synchronized(this) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index >= 0) {
HistoryRecord r = (HistoryRecord)mHistory.get(index);
return r.packageName;
@@ -5307,7 +5315,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
HistoryRecord activity = null;
if (type == INTENT_SENDER_ACTIVITY_RESULT) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return null;
}
@@ -6828,7 +6836,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
synchronized(this) {
if (r == null) {
- int index = indexOfTokenLocked(token, false);
+ int index = indexOfTokenLocked(token);
if (index < 0) {
return;
}
@@ -8934,7 +8942,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return false;
}
- private final int indexOfTokenLocked(IBinder token, boolean required) {
+ private final int indexOfTokenLocked(IBinder token) {
int count = mHistory.size();
// convert the token to an entry in the history.
@@ -8948,19 +8956,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
break;
}
}
- if (index < 0 && required) {
- RuntimeInit.crash(TAG, new InvalidTokenException(token));
- }
return index;
}
- static class InvalidTokenException extends Exception {
- InvalidTokenException(IBinder token) {
- super("Bad activity token: " + token);
- }
- }
-
private final void killServicesLocked(ProcessRecord app,
boolean allowRestart) {
// Report disconnected services.
@@ -9985,7 +9984,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
HistoryRecord activity = null;
if (token != null) {
- int aindex = indexOfTokenLocked(token, false);
+ int aindex = indexOfTokenLocked(token);
if (aindex < 0) {
Log.w(TAG, "Binding with unknown activity: " + token);
return 0;
@@ -10344,6 +10343,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mBackupTarget = r;
mBackupAppName = app.packageName;
+ // Try not to kill the process during backup
+ updateOomAdjLocked(proc);
+
// If the process is already attached, schedule the creation of the backup agent now.
// If it is not yet live, this will be done when it attaches to the framework.
if (proc.thread != null) {
@@ -10403,14 +10405,22 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return;
}
- try {
- mBackupTarget.app.thread.scheduleDestroyBackupAgent(appInfo);
- } catch (Exception e) {
- Log.e(TAG, "Exception when unbinding backup agent:");
- e.printStackTrace();
- }
+ ProcessRecord proc = mBackupTarget.app;
mBackupTarget = null;
mBackupAppName = null;
+
+ // Not backing this app up any more; reset its OOM adjustment
+ updateOomAdjLocked(proc);
+
+ // If the app crashed during backup, 'thread' will be null here
+ if (proc.thread != null) {
+ try {
+ proc.thread.scheduleDestroyBackupAgent(appInfo);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception when unbinding backup agent:");
+ e.printStackTrace();
+ }
+ }
}
}
// =========================================================
@@ -11885,6 +11895,14 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
app.curRawAdj = adj;
app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
+ if (mBackupTarget != null && app == mBackupTarget.app) {
+ // If possible we want to avoid killing apps while they're being backed up
+ if (adj > BACKUP_APP_ADJ) {
+ if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
+ adj = BACKUP_APP_ADJ;
+ }
+ }
+
if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
// If this process has active services running in it, we would
// like to avoid killing it unless it would prevent the current
@@ -12165,11 +12183,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
"Setting process group of " + app.processName
+ " to " + app.curSchedGroup);
if (true) {
+ long oldId = Binder.clearCallingIdentity();
try {
Process.setProcessGroup(app.pid, app.curSchedGroup);
} catch (Exception e) {
Log.w(TAG, "Failed setting process group of " + app.pid
+ " to " + app.curSchedGroup);
+ e.printStackTrace();
+ } finally {
+ Binder.restoreCallingIdentity(oldId);
}
}
if (false) {
diff --git a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
index 8a82966..6390d8e 100644
--- a/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
+++ b/telephony/java/android/telephony/JapanesePhoneNumberFormatter.java
@@ -21,11 +21,11 @@ import android.text.Editable;
/*
* Japanese Phone number formatting rule is a bit complicated.
* Here are some valid examples:
- *
+ *
* 022-229-1234 0223-23-1234 022-301-9876 015-482-7849 0154-91-3478
* 01547-5-4534 090-1234-1234 080-0123-6789
* 0800-000-9999 0570-000-000 0276-00-0000
- *
+ *
* As you can see, there is no straight-forward rule here.
* In order to handle this, a big array is prepared.
*/
@@ -151,14 +151,14 @@ import android.text.Editable;
-100, -100, -45, -45, -100, -100, -100, -100, -100, -100,
-25, -35, -35, -35, -35, -35, -35, -25, -25, -35,
-35, -35, -35, -35, -35, -35, -35, -35, -35, -45};
-
+
public static void format(Editable text) {
// Here, "root" means the position of "'":
// 0'3, 0'90, and +81'-90
// (dash will be deleted soon, so it is actually +81'90).
int rootIndex = 1;
int length = text.length();
- if (length > 3
+ if (length > 3
&& text.subSequence(0, 3).toString().equals("+81")) {
rootIndex = 3;
} else if (length < 1 || text.charAt(0) != '0') {
@@ -176,10 +176,10 @@ import android.text.Editable;
i++;
}
}
-
+
length = text.length();
int dashposition;
-
+
i = rootIndex;
int base = 0;
while (i < length) {
@@ -208,7 +208,7 @@ import android.text.Editable;
i++;
}
}
-
+
if (length > 3 && rootIndex == 3) {
text.insert(rootIndex, "-");
}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.aidl b/telephony/java/android/telephony/NeighboringCellInfo.aidl
index a7e709e..c464332 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.aidl
+++ b/telephony/java/android/telephony/NeighboringCellInfo.aidl
@@ -2,16 +2,16 @@
**
** Copyright 2007, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
** limitations under the License.
*/
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 326401a..f492abd 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -20,7 +20,7 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Represents the neighboring cell information, including
+ * Represents the neighboring cell information, including
* Received Signal Strength and Cell ID location.
*/
public class NeighboringCellInfo implements Parcelable
@@ -52,7 +52,7 @@ public class NeighboringCellInfo implements Parcelable
mRssi = rssi;
mCid = cid;
}
-
+
/**
* Initialize the object from a parcel.
*/
@@ -60,12 +60,12 @@ public class NeighboringCellInfo implements Parcelable
mRssi = in.readInt();
mCid = in.readInt();
}
-
+
/**
- * @return received signal strength in "asu", ranging from 0 - 31,
+ * @return received signal strength in "asu", ranging from 0 - 31,
* or UNKNOWN_RSSI if unknown
*
- * For GSM, dBm = -113 + 2*asu,
+ * For GSM, dBm = -113 + 2*asu,
* 0 means "-113 dBm or less" and 31 means "-51 dBm or greater"
*/
public int getRssi() {
@@ -95,7 +95,7 @@ public class NeighboringCellInfo implements Parcelable
@Override
public String toString() {
- return "["+ ((mCid == UNKNOWN_CID) ? "/" : Integer.toHexString(mCid))
+ return "["+ ((mCid == UNKNOWN_CID) ? "/" : Integer.toHexString(mCid))
+ " at " + ((mRssi == UNKNOWN_RSSI)? "/" : mRssi) + "]";
}
@@ -105,7 +105,7 @@ public class NeighboringCellInfo implements Parcelable
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mRssi);
- dest.writeInt(mCid);
+ dest.writeInt(mCid);
}
public static final Parcelable.Creator<NeighboringCellInfo> CREATOR
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index f9b95b2..b60da5a 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -224,25 +224,29 @@ public class SmsMessage {
/**
* Calculates the number of SMS's required to encode the message body and
- * the number of characters remaining until the next message, given the
- * current encoding.
+ * the number of characters remaining until the next message.
*
- * @param messageBody the message to encode
- * @param use7bitOnly if true, characters that are not part of the GSM
- * alphabet are counted as a single space char. If false, a
- * messageBody containing non-GSM alphabet characters is calculated
- * for 16-bit encoding.
+ * @param msgBody the message to encode
+ * @param use7bitOnly if true, characters that are not part of the
+ * radio-specific 7-bit encoding are counted as single
+ * space chars. If false, and if the messageBody contains
+ * non-7-bit encodable characters, length is calculated
+ * using a 16-bit encoding.
* @return an int[4] with int[0] being the number of SMS's required, int[1]
* the number of code units used, and int[2] is the number of code
* units remaining until the next message. int[3] is the encoding
* type that should be used for the message.
*/
- public static int[] calculateLength(CharSequence messageBody, boolean use7bitOnly) {
+ public static int[] calculateLength(CharSequence msgBody, boolean use7bitOnly) {
+ int activePhone = TelephonyManager.getDefault().getPhoneType();
int ret[] = new int[4];
- try {
- // Try GSM alphabet
- int septets = GsmAlphabet.countGsmSeptets(messageBody, !use7bitOnly);
+ int septets = (PHONE_TYPE_CDMA == activePhone) ?
+ com.android.internal.telephony.cdma.SmsMessage.calc7bitEncodedLength(msgBody,
+ use7bitOnly) :
+ com.android.internal.telephony.gsm.SmsMessage.calc7bitEncodedLength(msgBody,
+ use7bitOnly);
+ if (septets != -1) {
ret[1] = septets;
if (septets > MAX_USER_DATA_SEPTETS) {
ret[0] = (septets / MAX_USER_DATA_SEPTETS_WITH_HEADER) + 1;
@@ -253,12 +257,10 @@ public class SmsMessage {
ret[2] = MAX_USER_DATA_SEPTETS - septets;
}
ret[3] = ENCODING_7BIT;
- } catch (EncodeException ex) {
- // fall back to UCS-2
- int octets = messageBody.length() * 2;
- ret[1] = messageBody.length();
+ } else {
+ int octets = msgBody.length() * 2;
+ ret[1] = msgBody.length();
if (octets > MAX_USER_DATA_BYTES) {
- // 6 is the size of the user data header
ret[0] = (octets / MAX_USER_DATA_BYTES_WITH_HEADER) + 1;
ret[2] = (MAX_USER_DATA_BYTES_WITH_HEADER
- (octets % MAX_USER_DATA_BYTES_WITH_HEADER))/2;
diff --git a/telephony/java/android/telephony/package.html b/telephony/java/android/telephony/package.html
index aee4a6f..cb2fb49 100644
--- a/telephony/java/android/telephony/package.html
+++ b/telephony/java/android/telephony/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides APIs for monitoring the basic phone information, such as
+Provides APIs for monitoring the basic phone information, such as
the network type and connection state, plus utilities
for manipulating phone number strings.
</BODY>
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index dba4972..3edca66 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -59,6 +59,12 @@ public abstract class BaseCommands implements CommandsInterface {
protected RegistrantList mCallWaitingInfoRegistrants = new RegistrantList();
protected RegistrantList mDisplayInfoRegistrants = new RegistrantList();
protected RegistrantList mSignalInfoRegistrants = new RegistrantList();
+ protected RegistrantList mNumberInfoRegistrants = new RegistrantList();
+ protected RegistrantList mRedirNumInfoRegistrants = new RegistrantList();
+ protected RegistrantList mLineControlInfoRegistrants = new RegistrantList();
+ protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList();
+ protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
+
protected Registrant mSMSRegistrant;
protected Registrant mNITZTimeRegistrant;
protected Registrant mSignalStrengthRegistrant;
@@ -75,6 +81,7 @@ public abstract class BaseCommands implements CommandsInterface {
protected Registrant mIccRefreshRegistrant;
protected Registrant mRingRegistrant;
protected Registrant mRestrictedStateRegistrant;
+ protected Registrant mGsmBroadcastSmsRegistrant;
// Network Mode received from PhoneFactory
protected int mNetworkMode;
@@ -331,6 +338,14 @@ public abstract class BaseCommands implements CommandsInterface {
mSMSRegistrant.clear();
}
+ public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
+ mGsmBroadcastSmsRegistrant = new Registrant (h, what, obj);
+ }
+
+ public void unSetOnNewGsmBroadcastSms(Handler h) {
+ mGsmBroadcastSmsRegistrant.clear();
+ }
+
public void setOnSmsOnSim(Handler h, int what, Object obj) {
mSmsOnSimRegistrant = new Registrant (h, what, obj);
}
@@ -499,16 +514,60 @@ public abstract class BaseCommands implements CommandsInterface {
public void unregisterForSignalInfo(Handler h) {
mSignalInfoRegistrants.remove(h);
}
-
+
public void registerForCdmaOtaProvision(Handler h,int what, Object obj){
Registrant r = new Registrant (h, what, obj);
- mOtaProvisionRegistrants.add(r);
+ mOtaProvisionRegistrants.add(r);
}
public void unregisterForCdmaOtaProvision(Handler h){
mOtaProvisionRegistrants.remove(h);
}
+ public void registerForNumberInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mNumberInfoRegistrants.add(r);
+ }
+
+ public void unregisterForNumberInfo(Handler h){
+ mNumberInfoRegistrants.remove(h);
+ }
+
+ public void registerForRedirectedNumberInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mRedirNumInfoRegistrants.add(r);
+ }
+
+ public void unregisterForRedirectedNumberInfo(Handler h) {
+ mRedirNumInfoRegistrants.remove(h);
+ }
+
+ public void registerForLineControlInfo(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mLineControlInfoRegistrants.add(r);
+ }
+
+ public void unregisterForLineControlInfo(Handler h) {
+ mLineControlInfoRegistrants.remove(h);
+ }
+
+ public void registerFoT53ClirlInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mT53ClirInfoRegistrants.add(r);
+ }
+
+ public void unregisterForT53ClirInfo(Handler h) {
+ mT53ClirInfoRegistrants.remove(h);
+ }
+
+ public void registerForT53AudioControlInfo(Handler h,int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mT53AudCntrlInfoRegistrants.add(r);
+ }
+
+ public void unregisterForT53AudioControlInfo(Handler h) {
+ mT53AudCntrlInfoRegistrants.remove(h);
+ }
//***** Protected Methods
/**
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
index 70471b6..7eb9d85 100644
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ b/telephony/java/com/android/internal/telephony/Call.java
@@ -46,6 +46,13 @@ public abstract class Call {
public State state = State.IDLE;
+ // Flag to indicate if the current calling/caller information
+ // is accurate. If false the information is known to be accurate.
+ //
+ // For CDMA, during call waiting/3 way, there is no network response
+ // if call waiting is answered, network timed out, dropped, 3 way
+ // merged, etc.
+ protected boolean isGeneric = false;
/* Instance Methods */
@@ -126,6 +133,7 @@ public abstract class Call {
if (t < time) {
earliest = c;
+ time = t;
}
}
@@ -157,10 +165,8 @@ public abstract class Call {
public long
getEarliestConnectTime() {
- List l;
long time = Long.MAX_VALUE;
-
- l = getConnections();
+ List l = getConnections();
if (l.size() == 0) {
return 0;
@@ -189,4 +195,44 @@ public abstract class Call {
return getState().isRinging();
}
+ /**
+ * Returns the Connection associated with this Call that was created
+ * last, or null if there are no Connections in this Call
+ */
+ public Connection
+ getLatestConnection() {
+ List l = getConnections();
+ if (l.size() == 0) {
+ return null;
+ }
+
+ long time = 0;
+ Connection latest = null;
+ for (int i = 0, s = l.size() ; i < s ; i++) {
+ Connection c = (Connection) l.get(i);
+ long t = c.getCreateTime();
+
+ if (t > time) {
+ latest = c;
+ time = t;
+ }
+ }
+
+ return latest;
+ }
+
+ /**
+ * To indicate if the connection information is accurate
+ * or not. false means accurate. Only used for CDMA.
+ */
+ public boolean isGeneric() {
+ return isGeneric;
+ }
+
+ /**
+ * Set the generic instance variable
+ */
+ public void setGeneric(boolean generic) {
+ isGeneric = generic;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java
index 8263ded..9619a66 100644
--- a/telephony/java/com/android/internal/telephony/CallTracker.java
+++ b/telephony/java/com/android/internal/telephony/CallTracker.java
@@ -44,20 +44,21 @@ public abstract class CallTracker extends Handler {
//***** Events
- protected static final int EVENT_POLL_CALLS_RESULT = 1;
- protected static final int EVENT_CALL_STATE_CHANGE = 2;
- protected static final int EVENT_REPOLL_AFTER_DELAY = 3;
- protected static final int EVENT_OPERATION_COMPLETE = 4;
- protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5;
-
- protected static final int EVENT_SWITCH_RESULT = 8;
- protected static final int EVENT_RADIO_AVAILABLE = 9;
- protected static final int EVENT_RADIO_NOT_AVAILABLE = 10;
- protected static final int EVENT_CONFERENCE_RESULT = 11;
- protected static final int EVENT_SEPARATE_RESULT = 12;
- protected static final int EVENT_ECT_RESULT = 13;
- protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14;
-
+ protected static final int EVENT_POLL_CALLS_RESULT = 1;
+ protected static final int EVENT_CALL_STATE_CHANGE = 2;
+ protected static final int EVENT_REPOLL_AFTER_DELAY = 3;
+ protected static final int EVENT_OPERATION_COMPLETE = 4;
+ protected static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5;
+
+ protected static final int EVENT_SWITCH_RESULT = 8;
+ protected static final int EVENT_RADIO_AVAILABLE = 9;
+ protected static final int EVENT_RADIO_NOT_AVAILABLE = 10;
+ protected static final int EVENT_CONFERENCE_RESULT = 11;
+ protected static final int EVENT_SEPARATE_RESULT = 12;
+ protected static final int EVENT_ECT_RESULT = 13;
+ protected static final int EVENT_EXIT_ECM_RESPONSE_CDMA = 14;
+ protected static final int EVENT_CALL_WAITING_INFO_CDMA = 15;
+ protected static final int EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA = 16;
protected void pollCallsWhenSafe() {
needsPoll = true;
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 32f31ef..afc8b62 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -80,13 +80,13 @@ public class CallerInfo {
/* Split up the phoneLabel into number type and label name */
public int numberType;
public String numberLabel;
-
+
public int photoResource;
public long person_id;
public boolean needUpdate;
public Uri contactRefUri;
-
- // fields to hold individual contact preference data,
+
+ // fields to hold individual contact preference data,
// including the send to voicemail flag and the ringtone
// uri reference.
public Uri contactRingtoneUri;
@@ -116,7 +116,7 @@ public class CallerInfo {
* number. The returned CallerInfo is null if no number is supplied.
*/
public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) {
-
+
CallerInfo info = new CallerInfo();
info.photoResource = 0;
info.phoneLabel = null;
@@ -125,9 +125,9 @@ public class CallerInfo {
info.cachedPhoto = null;
info.isCachedPhotoCurrent = false;
info.contactExists = false;
-
+
if (Config.LOGV) Log.v(TAG, "construct callerInfo from cursor");
-
+
if (cursor != null) {
if (cursor.moveToFirst()) {
@@ -144,7 +144,7 @@ public class CallerInfo {
if (columnIndex != -1) {
info.phoneNumber = cursor.getString(columnIndex);
}
-
+
// Look for the label/type combo
columnIndex = cursor.getColumnIndex(Phones.LABEL);
if (columnIndex != -1) {
@@ -168,7 +168,7 @@ public class CallerInfo {
info.person_id = cursor.getLong(columnIndex);
}
}
-
+
// look for the custom ringtone, create from the string stored
// in the database.
columnIndex = cursor.getColumnIndex(People.CUSTOM_RINGTONE);
@@ -181,7 +181,7 @@ public class CallerInfo {
// look for the send to voicemail flag, set it to true only
// under certain circumstances.
columnIndex = cursor.getColumnIndex(People.SEND_TO_VOICEMAIL);
- info.shouldSendToVoicemail = (columnIndex != -1) &&
+ info.shouldSendToVoicemail = (columnIndex != -1) &&
((cursor.getInt(columnIndex)) == 1);
info.contactExists = true;
}
@@ -194,7 +194,7 @@ public class CallerInfo {
return info;
}
-
+
/**
* getCallerInfo given a URI, look up in the call-log database
* for the uri unique key.
@@ -204,11 +204,11 @@ public class CallerInfo {
* number. The returned CallerInfo is null if no number is supplied.
*/
public static CallerInfo getCallerInfo(Context context, Uri contactRef) {
-
- return getCallerInfo(context, contactRef,
+
+ return getCallerInfo(context, contactRef,
context.getContentResolver().query(contactRef, null, null, null, null));
}
-
+
/**
* getCallerInfo given a phone number, look up in the call-log database
* for the matching caller id info.
@@ -224,13 +224,13 @@ public class CallerInfo {
return null;
} else {
// Change the callerInfo number ONLY if it is an emergency number
- // or if it is the voicemail number. If it is either, take a
+ // or if it is the voicemail number. If it is either, take a
// shortcut and skip the query.
if (PhoneNumberUtils.isEmergencyNumber(number)) {
CallerInfo ci = new CallerInfo();
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
+ // comments at the top of CallerInfo class).
ci.phoneNumber = context.getString(
com.android.internal.R.string.emergency_call_dialog_number_for_display);
return ci;
@@ -241,14 +241,14 @@ public class CallerInfo {
CallerInfo ci = new CallerInfo();
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
+ // comments at the top of CallerInfo class).
ci.phoneNumber = TelephonyManager.getDefault().getVoiceMailAlphaTag();
// TODO: FIND ANOTHER ICON
//info.photoResource = android.R.drawable.badge_voicemail;
return ci;
}
} catch (SecurityException ex) {
- // Don't crash if this process doesn't have permission to
+ // Don't crash if this process doesn't have permission to
// retrieve VM number. It's still allowed to look up caller info.
// But don't try it again.
sSkipVmCheck = true;
@@ -257,16 +257,16 @@ public class CallerInfo {
}
Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL,
- Uri.encode(number));
-
+ Uri.encode(number));
+
CallerInfo info = getCallerInfo(context, contactUri);
- // if no query results were returned with a viable number,
- // fill in the original number value we used to query with.
+ // if no query results were returned with a viable number,
+ // fill in the original number value we used to query with.
if (TextUtils.isEmpty(info.phoneNumber)) {
info.phoneNumber = number;
}
-
+
return info;
}
@@ -278,9 +278,9 @@ public class CallerInfo {
* @param number a phone number.
* @return if the number belongs to a contact, the contact's name is
* returned; otherwise, the number itself is returned.
- *
- * TODO NOTE: This MAY need to refer to the Asynchronous Query API
- * [startQuery()], instead of getCallerInfo, but since it looks like
+ *
+ * TODO NOTE: This MAY need to refer to the Asynchronous Query API
+ * [startQuery()], instead of getCallerInfo, but since it looks like
* it is only being used by the provider calls in the messaging app:
* 1. android.provider.Telephony.Mms.getDisplayAddress()
* 2. android.provider.Telephony.Sms.getDisplayAddress()
@@ -310,4 +310,4 @@ public class CallerInfo {
return null;
}
}
-}
+}
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 04da9f7..f81f42a 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -35,10 +35,10 @@ import android.util.Log;
*/
public class CallerInfoAsyncQuery {
-
+
private static final boolean DBG = false;
private static final String LOG_TAG = "PHONE";
-
+
private static final int EVENT_NEW_QUERY = 1;
private static final int EVENT_ADD_LISTENER = 2;
private static final int EVENT_END_OF_QUEUE = 3;
@@ -55,24 +55,24 @@ public class CallerInfoAsyncQuery {
*/
public interface OnQueryCompleteListener {
/**
- * Called when the query is complete.
- */
+ * Called when the query is complete.
+ */
public void onQueryComplete(int token, Object cookie, CallerInfo ci);
}
-
-
+
+
/**
* Wrap the cookie from the WorkerArgs with additional information needed by our
- * classes.
+ * classes.
*/
private static final class CookieWrapper {
public OnQueryCompleteListener listener;
public Object cookie;
public int event;
public String number;
- }
-
-
+ }
+
+
/**
* Simple exception used to communicate problems with the query pool.
*/
@@ -81,12 +81,12 @@ public class CallerInfoAsyncQuery {
super(error);
}
}
-
+
/**
* Our own implementation of the AsyncQueryHandler.
*/
private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler {
-
+
/**
* The information relevant to each CallerInfo query. Each query may have multiple
* listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper
@@ -96,20 +96,20 @@ public class CallerInfoAsyncQuery {
private Context mQueryContext;
private Uri mQueryUri;
private CallerInfo mCallerInfo;
-
+
/**
* Our own query worker thread.
- *
+ *
* This thread handles the messages enqueued in the looper. The normal sequence
* of events is that a new query shows up in the looper queue, followed by 0 or
* more add listener requests, and then an end request. Of course, these requests
* can be interlaced with requests from other tokens, but is irrelevant to this
* handler since the handler has no state.
- *
+ *
* Note that we depend on the queue to keep things in order; in other words, the
- * looper queue must be FIFO with respect to input from the synchronous startQuery
+ * looper queue must be FIFO with respect to input from the synchronous startQuery
* calls and output to this handleMessage call.
- *
+ *
* This use of the queue is required because CallerInfo objects may be accessed
* multiple times before the query is complete. All accesses (listeners) must be
* queued up and informed in order when the query is complete.
@@ -123,22 +123,22 @@ public class CallerInfoAsyncQuery {
public void handleMessage(Message msg) {
WorkerArgs args = (WorkerArgs) msg.obj;
CookieWrapper cw = (CookieWrapper) args.cookie;
-
+
if (cw == null) {
// Normally, this should never be the case for calls originating
// from within this code.
- // However, if there is any code that this Handler calls (such as in
+ // However, if there is any code that this Handler calls (such as in
// super.handleMessage) that DOES place unexpected messages on the
// queue, then we need pass these messages on.
- if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what +
+ if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what +
" ignored by CallerInfoWorkerHandler, passing onto parent.");
-
+
super.handleMessage(msg);
} else {
-
- if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
+
+ if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
" command: " + msg.what + " query URI: " + args.uri);
-
+
switch (cw.event) {
case EVENT_NEW_QUERY:
//start the sql command.
@@ -148,7 +148,7 @@ public class CallerInfoAsyncQuery {
// shortcuts to avoid query for recognized numbers.
case EVENT_EMERGENCY_NUMBER:
case EVENT_VOICEMAIL_NUMBER:
-
+
case EVENT_ADD_LISTENER:
case EVENT_END_OF_QUEUE:
// query was already completed, so just send the reply.
@@ -157,17 +157,17 @@ public class CallerInfoAsyncQuery {
Message reply = args.handler.obtainMessage(msg.what);
reply.obj = args;
reply.arg1 = msg.arg1;
-
+
reply.sendToTarget();
-
+
break;
default:
}
}
}
}
-
-
+
+
/**
* Asynchronous query handler class for the contact / callerinfo object.
*/
@@ -182,29 +182,29 @@ public class CallerInfoAsyncQuery {
/**
* Overrides onQueryComplete from AsyncQueryHandler.
- *
+ *
* This method takes into account the state of this class; we construct the CallerInfo
* object only once for each set of listeners. When the query thread has done its work
- * and calls this method, we inform the remaining listeners in the queue, until we're
- * out of listeners. Once we get the message indicating that we should expect no new
- * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the
+ * and calls this method, we inform the remaining listeners in the queue, until we're
+ * out of listeners. Once we get the message indicating that we should expect no new
+ * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the
* pool.
*/
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (DBG) log("query complete for token: " + token);
-
+
//get the cookie and notify the listener.
CookieWrapper cw = (CookieWrapper) cookie;
if (cw == null) {
// Normally, this should never be the case for calls originating
// from within this code.
- // However, if there is any code that calls this method, we should
+ // However, if there is any code that calls this method, we should
// check the parameters to make sure they're viable.
if (DBG) log("Cookie is null, ignoring onQueryComplete() request.");
return;
}
-
+
if (cw.event == EVENT_END_OF_QUEUE) {
release();
return;
@@ -216,16 +216,16 @@ public class CallerInfoAsyncQuery {
throw new QueryPoolException
("Bad context or query uri, or CallerInfoAsyncQuery already released.");
}
-
+
// adjust the callerInfo data as needed, and only if it was set from the
// initial query request.
// Change the callerInfo number ONLY if it is an emergency number or the
- // voicemail number, and adjust other data (including photoResource)
+ // voicemail number, and adjust other data (including photoResource)
// accordingly.
if (cw.event == EVENT_EMERGENCY_NUMBER) {
mCallerInfo = new CallerInfo();
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
+ // comments at the top of CallerInfo class).
mCallerInfo.phoneNumber = mQueryContext.getString(com.android.internal
.R.string.emergency_call_dialog_number_for_display);
mCallerInfo.photoResource = com.android.internal.R.drawable.picture_emergency;
@@ -234,8 +234,8 @@ public class CallerInfoAsyncQuery {
mCallerInfo = new CallerInfo();
try {
// Note we're setting the phone number here (refer to javadoc
- // comments at the top of CallerInfo class).
- mCallerInfo.phoneNumber =
+ // comments at the top of CallerInfo class).
+ mCallerInfo.phoneNumber =
TelephonyManager.getDefault().getVoiceMailAlphaTag();
} catch (SecurityException ex) {
// Should never happen: if this process does not have
@@ -243,80 +243,80 @@ public class CallerInfoAsyncQuery {
// permission to retrieve VM number and would not generate
// an EVENT_VOICEMAIL_NUMBER. But if it happens, don't crash.
}
- } else {
+ } else {
mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
// Use the number entered by the user for display.
if (!TextUtils.isEmpty(cw.number)) {
mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
}
}
-
+
if (DBG) log("constructing CallerInfo object for token: " + token);
-
+
//notify that we can clean up the queue after this.
CookieWrapper endMarker = new CookieWrapper();
endMarker.event = EVENT_END_OF_QUEUE;
startQuery (token, endMarker, null, null, null, null, null);
}
-
+
//notify the listener that the query is complete.
if (cw.listener != null) {
- if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
+ if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
" for token: " + token);
cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
}
}
}
-
+
/**
* Private constructor for factory methods.
*/
private CallerInfoAsyncQuery() {
}
-
+
/**
* Factory method to start query with a Uri query spec
*/
- public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef,
+ public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef,
OnQueryCompleteListener listener, Object cookie) {
-
+
CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
c.allocate(context, contactRef);
if (DBG) log("starting query for URI: " + contactRef + " handler: " + c.toString());
-
+
//create cookieWrapper, start query
CookieWrapper cw = new CookieWrapper();
cw.listener = listener;
cw.cookie = cookie;
cw.event = EVENT_NEW_QUERY;
-
+
c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
-
+
return c;
}
-
+
/**
* Factory method to start query with a number
*/
- public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
+ public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
OnQueryCompleteListener listener, Object cookie) {
//contruct the URI object and start Query.
Uri contactRef = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, number);
-
+
CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
c.allocate(context, contactRef);
if (DBG) log("starting query for number: " + number + " handler: " + c.toString());
-
+
//create cookieWrapper, start query
CookieWrapper cw = new CookieWrapper();
cw.listener = listener;
cw.cookie = cookie;
cw.number = number;
- // check to see if these are recognized numbers, and use shortcuts if we can.
+ // check to see if these are recognized numbers, and use shortcuts if we can.
if (PhoneNumberUtils.isEmergencyNumber(number)) {
cw.event = EVENT_EMERGENCY_NUMBER;
} else {
@@ -325,13 +325,13 @@ public class CallerInfoAsyncQuery {
try {
vmNumber = TelephonyManager.getDefault().getVoiceMailNumber();
} catch (SecurityException ex) {
- // Don't crash if this process doesn't have permission to
+ // Don't crash if this process doesn't have permission to
// retrieve VM number. It's still allowed to look up caller info.
// But don't try it again.
sSkipVmCheck = true;
}
}
- if (PhoneNumberUtils.compare(number, vmNumber)) {
+ if (PhoneNumberUtils.compare(number, vmNumber)) {
cw.event = EVENT_VOICEMAIL_NUMBER;
} else {
cw.event = EVENT_NEW_QUERY;
@@ -339,24 +339,24 @@ public class CallerInfoAsyncQuery {
}
c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
-
+
return c;
}
-
+
/**
* Method to add listeners to a currently running query
*/
public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
- if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
+ if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
mHandler.toString());
-
+
//create cookieWrapper, add query request to end of queue.
CookieWrapper cw = new CookieWrapper();
cw.listener = listener;
cw.cookie = cookie;
cw.event = EVENT_ADD_LISTENER;
-
+
mHandler.startQuery (token, cw, null, null, null, null, null);
}
@@ -382,12 +382,12 @@ public class CallerInfoAsyncQuery {
mHandler.mCallerInfo = null;
mHandler = null;
}
-
+
/**
* static logging method
*/
private static void log(String msg) {
Log.d(LOG_TAG, msg);
- }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index c6d1a4b..25c512e 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+
import android.os.Message;
import android.os.Handler;
@@ -466,6 +468,61 @@ public interface CommandsInterface {
void unregisterForSignalInfo(Handler h);
/**
+ * Registers the handler for CDMA number information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForNumberInfo(Handler h, int what, Object obj);
+ void unregisterForNumberInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA redirected number Information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
+ void unregisterForRedirectedNumberInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA line control information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForLineControlInfo(Handler h, int what, Object obj);
+ void unregisterForLineControlInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA T53 CLIR information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerFoT53ClirlInfo(Handler h, int what, Object obj);
+ void unregisterForT53ClirInfo(Handler h);
+
+ /**
+ * Registers the handler for CDMA T53 audio control information record
+ * Unlike the register* methods, there's only one notification handler
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForT53AudioControlInfo(Handler h, int what, Object obj);
+ void unregisterForT53AudioControlInfo(Handler h);
+
+ /**
* Fires on if Modem enters Emergency Callback mode
*/
void setEmergencyCallbackMode(Handler h, int what, Object obj);
@@ -1102,6 +1159,14 @@ public interface CommandsInterface {
*/
void reportSmsMemoryStatus(boolean available, Message result);
+ /**
+ * Indicates to the vendor ril that StkService is running
+ * rand is eady to receive RIL_UNSOL_STK_XXXX commands.
+ *
+ * @param result callback message
+ */
+ void reportStkServiceIsRunning(Message result);
+
void invokeOemRilRequestRaw(byte[] data, Message response);
void invokeOemRilRequestStrings(String[] strings, Message response);
@@ -1137,6 +1202,31 @@ public interface CommandsInterface {
*/
public void handleCallSetupRequestFromSim(boolean accept, Message response);
+ /**
+ * Activate or deactivate cell broadcast SMS for GSM.
+ *
+ * @param activate
+ * true = activate, false = deactivate
+ * @param result Callback message is empty on completion
+ */
+ public void setGsmBroadcastActivation(boolean activate, Message result);
+
+ /**
+ * Configure cell broadcast SMS for GSM.
+ *
+ * @param response Callback message is empty on completion
+ */
+ public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response);
+
+ /**
+ * Query the current configuration of cell broadcast SMS of GSM.
+ *
+ * @param response
+ * Callback message contains the configuration from the modem
+ * on completion
+ */
+ public void getGsmBroadcastConfig(Message response);
+
//***** new Methods for CDMA support
/**
@@ -1243,14 +1333,14 @@ public interface CommandsInterface {
public void deactivateDataCall(int cid, Message result);
/**
- * Activate or deactivate cell broadcast SMS.
+ * Activate or deactivate cell broadcast SMS for CDMA.
*
* @param activate
- * 0 = activate, 1 = deactivate
+ * true = activate, false = deactivate
* @param result
* Callback message is empty on completion
*/
- public void activateCdmaBroadcastSms(int activate, Message result);
+ public void setCdmaBroadcastActivation(boolean activate, Message result);
/**
* Configure cdma cell broadcast SMS.
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index 237974d..92f6cb8 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -27,7 +27,7 @@ public abstract class Connection {
public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network
public static int PRESENTATION_PAYPHONE = 4; // show pay phone info
-
+
public enum DisconnectCause {
NOT_DISCONNECTED, /* has not yet disconnected */
INCOMING_MISSED, /* an incoming call that was missed and never answered */
@@ -231,7 +231,7 @@ public abstract class Connection {
COMPLETE, /* The post dial string playback is complete */
CANCELLED, /* The post dial string playback was cancelled
with cancelPostDial() */
- PAUSE /* The post dial string playback is pausing for a
+ PAUSE /* The post dial string playback is pausing for a
call to processNextPostDialChar*/
}
@@ -260,8 +260,8 @@ public abstract class Connection {
/**
* Cancel any post
*/
- public abstract void cancelPostDial();
-
+ public abstract void cancelPostDial();
+
/**
* Returns the caller id presentation type for incoming and waiting calls
* @return one of PRESENTATION_*
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 6e9d1ab..7809fed 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -55,57 +55,83 @@ public abstract class DataConnection extends Handler {
public enum FailCause {
NONE,
- BAD_APN,
- BAD_PAP_SECRET,
- BARRED,
+ OPERATOR_BARRED,
+ INSUFFICIENT_RESOURCES,
+ MISSING_UKNOWN_APN,
+ UNKNOWN_PDP_ADDRESS,
USER_AUTHENTICATION,
+ ACTIVATION_REJECT_GGSN,
+ ACTIVATION_REJECT_UNSPECIFIED,
SERVICE_OPTION_NOT_SUPPORTED,
SERVICE_OPTION_NOT_SUBSCRIBED,
- SIM_LOCKED,
- RADIO_OFF,
- NO_SIGNAL,
- NO_DATA_PLAN,
+ SERVICE_OPTION_OUT_OF_ORDER,
+ NSAPI_IN_USE,
+ PROTOCOL_ERRORS,
+ REGISTRATION_FAIL,
+ GPRS_REGISTRATION_FAIL,
+ UNKNOWN,
+
RADIO_NOT_AVAILABLE,
- SUSPENED_TEMPORARY,
- RADIO_ERROR_RETRY,
- UNKNOWN;
+ RADIO_ERROR_RETRY;
public boolean isPermanentFail() {
- return (this == RADIO_OFF);
+ return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) ||
+ (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) ||
+ (this == PROTOCOL_ERRORS);
+ }
+
+ public boolean isEventLoggable() {
+ return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
+ (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
+ (this == PROTOCOL_ERRORS);
}
+ @Override
public String toString() {
switch (this) {
case NONE:
- return "no error";
- case BAD_APN:
- return "bad apn";
- case BAD_PAP_SECRET:
- return "bad pap secret";
- case BARRED:
- return "barred";
+ return "No Error";
+ case OPERATOR_BARRED:
+ return "Operator Barred";
+ case INSUFFICIENT_RESOURCES:
+ return "Insufficient Resources";
+ case MISSING_UKNOWN_APN:
+ return "Missing / Unknown APN";
+ case UNKNOWN_PDP_ADDRESS:
+ return "Unknown PDP Address";
case USER_AUTHENTICATION:
- return "error user autentication";
+ return "Error User Autentication";
+ case ACTIVATION_REJECT_GGSN:
+ return "Activation Reject GGSN";
+ case ACTIVATION_REJECT_UNSPECIFIED:
+ return "Activation Reject unspecified";
case SERVICE_OPTION_NOT_SUPPORTED:
- return "data not supported";
+ return "Data Not Supported";
case SERVICE_OPTION_NOT_SUBSCRIBED:
- return "datt not subcribed";
- case SIM_LOCKED:
- return "sim locked";
- case RADIO_OFF:
- return "radio is off";
- case NO_SIGNAL:
- return "no signal";
- case NO_DATA_PLAN:
- return "no data plan";
+ return "Data Not subscribed";
+ case SERVICE_OPTION_OUT_OF_ORDER:
+ return "Data Services Out of Order";
+ case NSAPI_IN_USE:
+ return "NSAPI in use";
+ case PROTOCOL_ERRORS:
+ return "Protocol Errors";
+ case REGISTRATION_FAIL:
+ return "Network Registration Failure";
+ case GPRS_REGISTRATION_FAIL:
+ return "Data Network Registration Failure";
case RADIO_NOT_AVAILABLE:
- return "radio not available";
- case SUSPENED_TEMPORARY:
- return "suspend temporary";
+ return "Radio Not Available";
case RADIO_ERROR_RETRY:
- return "transient radio error";
+ return "Transient Radio Rrror";
default:
- return "unknown data error";
+ return "Unknown Data Error";
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl b/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
index 6c1f4bb..facdc49 100644
--- a/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
+++ b/telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
@@ -1,11 +1,11 @@
package com.android.internal.telephony;
/**
- * Interface used to interact with extended MMI/USSD network service.
+ * Interface used to interact with extended MMI/USSD network service.
*/
interface IExtendedNetworkService {
/**
- * Set a MMI/USSD command to ExtendedNetworkService for further process.
+ * Set a MMI/USSD command to ExtendedNetworkService for further process.
* This should be called when a MMI command is placed from panel.
* @param number the dialed MMI/USSD number.
*/
diff --git a/telephony/java/com/android/internal/telephony/IccVmFixedException.java b/telephony/java/com/android/internal/telephony/IccVmFixedException.java
index 45679c1..a75496f 100644
--- a/telephony/java/com/android/internal/telephony/IccVmFixedException.java
+++ b/telephony/java/com/android/internal/telephony/IccVmFixedException.java
@@ -28,5 +28,5 @@ public final class IccVmFixedException extends IccException {
public IccVmFixedException(String s)
{
super(s);
- }
+ }
} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
index 7e90d24..3c9d126 100644
--- a/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
+++ b/telephony/java/com/android/internal/telephony/IccVmNotSupportedException.java
@@ -28,5 +28,5 @@ public final class IccVmNotSupportedException extends IccException {
public IccVmNotSupportedException(String s)
{
super(s);
- }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index a6b0480..cdbfd61 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1350,10 +1350,14 @@ public interface Phone {
/**
* Retrieves the MIN for CDMA phones.
*/
-
String getCdmaMin();
/**
+ * Retrieves PRL Version for CDMA phones
+ */
+ String getCdmaPrlVersion();
+
+ /**
* Retrieves the ESN for CDMA phones.
*/
String getEsn();
@@ -1464,14 +1468,12 @@ public interface Phone {
* @param what User-defined message code.
* @param obj User object.
*/
- // TODO(Moto) TODO: Remove when generic implemented
void registerForCallWaiting(Handler h, int what, Object obj);
/**
* Unegister for notifications when CDMA Call waiting comes
* @param h Handler to be removed from the registrant list.
*/
- // TODO(Moto): Remove when generic implemented
void unregisterForCallWaiting(Handler h);
@@ -1513,6 +1515,109 @@ public interface Phone {
*/
void unregisterForDisplayInfo(Handler h) ;
+ /**
+ * Register for CDMA number information record notification from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForNumberInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for number information record notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForNumberInfo(Handler h);
+
+ /**
+ * Register for CDMA redirected number information record notification
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForRedirectedNumberInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for redirected number information record notification.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForRedirectedNumberInfo(Handler h);
+
+ /**
+ * Register for CDMA line control information record notification
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForLineControlInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for line control information notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForLineControlInfo(Handler h);
+
+ /**
+ * Register for CDMA T53 CLIR information record notifications
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerFoT53ClirlInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for T53 CLIR information record notification
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForT53ClirInfo(Handler h);
+
+ /**
+ * Register for CDMA T53 audio control information record notifications
+ * from the network.
+ * Message.obj will contain an AsyncResult.
+ * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
+ * instance.
+ *
+ * @param h Handler that receives the notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ */
+ void registerForT53AudioControlInfo(Handler h, int what, Object obj);
+
+ /**
+ * Unregisters for T53 audio control information record notifications.
+ * Extraneous calls are tolerated silently
+ *
+ * @param h Handler to be removed from the registrant list.
+ */
+ void unregisterForT53AudioControlInfo(Handler h);
/**
* registers for exit emergency call back mode request response
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index c92cf3d..c34f26e 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -694,6 +694,12 @@ public abstract class PhoneBase implements Phone {
return null;
}
+ public String getCdmaPrlVersion(){
+ // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
+ Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
+ return null;
+ }
+
public void sendBurstDtmf(String dtmfString, Message onComplete) {
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
@@ -746,6 +752,46 @@ public abstract class PhoneBase implements Phone {
mCM.unregisterForDisplayInfo(h);
}
+ public void registerForNumberInfo(Handler h, int what, Object obj) {
+ mCM.registerForNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForNumberInfo(Handler h) {
+ mCM.unregisterForNumberInfo(h);
+ }
+
+ public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
+ mCM.registerForRedirectedNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForRedirectedNumberInfo(Handler h) {
+ mCM.unregisterForRedirectedNumberInfo(h);
+ }
+
+ public void registerForLineControlInfo(Handler h, int what, Object obj) {
+ mCM.registerForLineControlInfo( h, what, obj);
+ }
+
+ public void unregisterForLineControlInfo(Handler h) {
+ mCM.unregisterForLineControlInfo(h);
+ }
+
+ public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
+ mCM.registerFoT53ClirlInfo(h, what, obj);
+ }
+
+ public void unregisterForT53ClirInfo(Handler h) {
+ mCM.unregisterForT53ClirInfo(h);
+ }
+
+ public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
+ mCM.registerForT53AudioControlInfo( h, what, obj);
+ }
+
+ public void unregisterForT53AudioControlInfo(Handler h) {
+ mCM.unregisterForT53AudioControlInfo(h);
+ }
+
public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 7d968f9..4bb24dc 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -418,6 +418,10 @@ public class PhoneProxy extends Handler implements Phone {
return mActivePhone.getCdmaMin();
}
+ public String getCdmaPrlVersion() {
+ return mActivePhone.getCdmaPrlVersion();
+ }
+
public String getLine1AlphaTag() {
return mActivePhone.getLine1AlphaTag();
}
@@ -745,6 +749,46 @@ public class PhoneProxy extends Handler implements Phone {
mActivePhone.unregisterForDisplayInfo(h);
}
+ public void registerForNumberInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForNumberInfo(Handler h) {
+ mActivePhone.unregisterForNumberInfo(h);
+ }
+
+ public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForRedirectedNumberInfo(h, what, obj);
+ }
+
+ public void unregisterForRedirectedNumberInfo(Handler h) {
+ mActivePhone.unregisterForRedirectedNumberInfo(h);
+ }
+
+ public void registerForLineControlInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForLineControlInfo( h, what, obj);
+ }
+
+ public void unregisterForLineControlInfo(Handler h) {
+ mActivePhone.unregisterForLineControlInfo(h);
+ }
+
+ public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerFoT53ClirlInfo(h, what, obj);
+ }
+
+ public void unregisterForT53ClirInfo(Handler h) {
+ mActivePhone.unregisterForT53ClirInfo(h);
+ }
+
+ public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
+ mActivePhone.registerForT53AudioControlInfo( h, what, obj);
+ }
+
+ public void unregisterForT53AudioControlInfo(Handler h) {
+ mActivePhone.unregisterForT53AudioControlInfo(h);
+ }
+
public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
mActivePhone.setOnEcbModeExitResponse(h,what,obj);
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 0cdeeff..07fc7c6 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -42,6 +42,7 @@ import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.gsm.NetworkInfo;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.IccCardApplication;
import com.android.internal.telephony.IccCardStatus;
@@ -1259,13 +1260,15 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
- rr.mp.writeInt(5);
+ rr.mp.writeInt(6);
rr.mp.writeString(radioTechnology);
rr.mp.writeString(profile);
rr.mp.writeString(apn);
rr.mp.writeString(user);
rr.mp.writeString(password);
+ //TODO(): Add to the APN database, AuthType is set to CHAP/PAP
+ rr.mp.writeString("3");
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
+ apn);
@@ -1807,7 +1810,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
public void setSmscAddress(String address, Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_SMSC_ADDRESS, result);
- rr.mp.writeInt(1);
rr.mp.writeString(address);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -1830,6 +1832,70 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
+ /**
+ * {@inheritDoc}
+ */
+ public void reportStkServiceIsRunning(Message result) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void getGsmBroadcastConfig(Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, response);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, response);
+
+ int numOfConfig = config.length;
+ rr.mp.writeInt(numOfConfig);
+
+ for(int i = 0; i < numOfConfig; i++) {
+ rr.mp.writeInt(config[i].getFromServiceId());
+ rr.mp.writeInt(config[i].getToServiceId());
+ rr.mp.writeInt(config[i].getFromCodeScheme());
+ rr.mp.writeInt(config[i].getToCodeScheme());
+ rr.mp.writeInt(config[i].isSelected() ? 1 : 0);
+ }
+
+ if (RILJ_LOGD) {
+ riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " with " + numOfConfig + "configs : ");
+ for (int i = 0; i < numOfConfig; i++) {
+ riljLog(config[i].toString());
+ }
+ }
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setGsmBroadcastActivation(boolean activate, Message response) {
+ RILRequest rr = RILRequest.obtain(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, response);
+
+ rr.mp.writeInt(1);
+ rr.mp.writeInt(activate ? 0 : 1);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ send(rr);
+ }
+
//***** Private Methods
private void sendScreenState(boolean on) {
@@ -2083,13 +2149,13 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_CDMA_BURST_DTMF: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SEND_SMS: ret = responseSMS(p); break;
case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_BROADCAST_CONFIG: ret = responseBR_SMS_CNF(p); break;
- case RIL_REQUEST_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCDMA_BR_CNF(p); break;
+ case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: ret = responseGmsBroadcastConfig(p); break;
+ case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
+ case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
- case RIL_REQUEST_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_VALIDATE_AKEY: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_VALIDATE_AKEY: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
@@ -2097,6 +2163,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
@@ -2234,7 +2301,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: ret = responseInts(p); break;
- case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInfoRec(p); break;
+ case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break;
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
default:
@@ -2436,12 +2503,16 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+ if (RILJ_LOGD) unsljLog(response);
+
if (mIccStatusChangedRegistrants != null) {
mIccStatusChangedRegistrants.notifyRegistrants();
}
break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+ if (RILJ_LOGD) unsljLog(response);
+
SmsMessage sms = (SmsMessage) ret;
if (mSMSRegistrant != null) {
@@ -2451,13 +2522,16 @@ public final class RIL extends BaseCommands implements CommandsInterface {
break;
case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
- // TODO T: waiting for SMS BC feature
+ if (RILJ_LOGD) unsljLog(response);
+
+ if (mGsmBroadcastSmsRegistrant != null) {
+ mGsmBroadcastSmsRegistrant
+ .notifyRegistrant(new AsyncResult(null, ret, null));
+ }
break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
- if (Config.LOGD) {
- if (RILJ_LOGD) riljLog("[UNSL]< RUIM_SMS_STORAGE_FULL");
- }
+ if (RILJ_LOGD) unsljLog(response);
if (mIccSmsFullRegistrant != null) {
mIccSmsFullRegistrant.notifyRegistrant();
@@ -2491,23 +2565,18 @@ public final class RIL extends BaseCommands implements CommandsInterface {
break;
case RIL_UNSOL_CDMA_INFO_REC:
- if (RILJ_LOGD) unsljLog(response);
+ ArrayList<CdmaInformationRecords> listInfoRecs;
- CdmaInformationRecords infoRec = (CdmaInformationRecords) ret;
- if (infoRec.isDispInfo) {
- if (mDisplayInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.cdmaDisplayInfoRecord);
-
- mDisplayInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.cdmaDisplayInfoRecord, null));
- }
+ try {
+ listInfoRecs = (ArrayList<CdmaInformationRecords>)ret;
+ } catch (ClassCastException e) {
+ Log.e(LOG_TAG, "Unexpected exception casting to listInfoRecs", e);
+ break;
}
- if (infoRec.isSignInfo) {
- if (mSignalInfoRegistrants != null) {
- if (RILJ_LOGD) unsljLogRet(response, infoRec.cdmaSignalInfoRecord);
- mSignalInfoRegistrants.notifyRegistrants(
- new AsyncResult (null, infoRec.cdmaSignalInfoRecord, null));
- }
+
+ for (CdmaInformationRecords rec : listInfoRecs) {
+ if (RILJ_LOGD) unsljLogRet(response, rec);
+ notifyRegistrantsCdmaInfoRec(rec);
}
break;
@@ -2626,13 +2695,14 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseSMS(Parcel p) {
- int messageRef;
+ int messageRef, errorCode;
String ackPDU;
messageRef = p.readInt();
ackPDU = p.readString();
+ errorCode = p.readInt();
- SmsResponse response = new SmsResponse(messageRef, ackPDU);
+ SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
return response;
}
@@ -2765,30 +2835,24 @@ public final class RIL extends BaseCommands implements CommandsInterface {
dc.als = p.readInt();
voiceSettings = p.readInt();
dc.isVoice = (0 == voiceSettings) ? false : true;
- int voicePrivacy = p.readInt();
- dc.isVoicePrivacy = (0 != voicePrivacy);
+ dc.isVoicePrivacy = (0 != p.readInt());
dc.number = p.readString();
int np = p.readInt();
dc.numberPresentation = DriverCall.presentationFromCLIP(np);
dc.name = p.readString();
dc.namePresentation = p.readInt();
- // Make sure there's a leading + on addresses with a TOA
- // of 145
-
- dc.number = PhoneNumberUtils.stringFromStringAndTOA(
- dc.number, dc.TOA);
+ // Make sure there's a leading + on addresses with a TOA of 145
+ dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
response.add(dc);
- if ( RILConstants.CDMA_VOICE_PRIVACY == voicePrivacy ) {
+ if (dc.isVoicePrivacy) {
mVoicePrivacyOnRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is enabled: " +
- Integer.toString(voicePrivacy));
+ Log.d(LOG_TAG, "InCall VoicePrivacy is enabled");
} else {
mVoicePrivacyOffRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is disabled: " +
- Integer.toString(voicePrivacy));
+ Log.d(LOG_TAG, "InCall VoicePrivacy is disabled");
}
}
@@ -2855,41 +2919,58 @@ public final class RIL extends BaseCommands implements CommandsInterface {
response = new ArrayList<NeighboringCellInfo>(num);
for (int i = 0 ; i < num ; i++) {
- try {
- int rssi = p.readInt();
- int cid = Integer.valueOf(p.readString(), 16);
- cell = new NeighboringCellInfo(rssi, cid);
- response.add(cell);
- } catch ( Exception e) {
- }
+ int rssi = p.readInt();
+ int cid = Integer.valueOf(p.readString(), 16);
+ cell = new NeighboringCellInfo(rssi, cid);
+ response.add(cell);
}
return response;
}
- private Object
- responseBR_SMS_CNF(Parcel p) {
- // TODO
- return null;
+ private Object responseGmsBroadcastConfig(Parcel p) {
+ int num;
+ ArrayList<SmsBroadcastConfigInfo> response;
+ SmsBroadcastConfigInfo info;
+
+ num = p.readInt();
+ response = new ArrayList<SmsBroadcastConfigInfo>(num);
+
+ for (int i = 0; i < num; i++) {
+ int fromId = p.readInt();
+ int toId = p.readInt();
+ int fromScheme = p.readInt();
+ int toScheme = p.readInt();
+ boolean selected = (p.readInt() == 1);
+
+ info = new SmsBroadcastConfigInfo(fromId, toId, fromScheme,
+ toScheme, selected);
+ response.add(info);
+ }
+ return response;
}
private Object
- responseCDMA_BR_CNF(Parcel p) {
+ responseCdmaBroadcastConfig(Parcel p) {
int numServiceCategories;
int response[];
numServiceCategories = p.readInt();
if (numServiceCategories == 0) {
+ // TODO(Teleca) TODO(Moto): The logic of providing default
+ // values should not be done by this transport layer. And
+ // needs to be done by the vendor ril or application logic.
+ // TODO(Google): Remove ASAP
int numInts;
numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
response = new int[numInts];
- // Indicate that a zero length table was received
- response[0] = 0; // TODO(Moto): This is very strange, please explain why.
+ // Faking a default record for all possible records.
+ response[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
// Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
- // default language and selection status to false
+ // default language and selection status to false for all.
for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT ) {
response[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
response[i + 1] = 1;
@@ -2923,66 +3004,24 @@ public final class RIL extends BaseCommands implements CommandsInterface {
return response;
}
- private Object
- responseCdmaInfoRec(Parcel p) {
- int infoRecordName;
- CdmaInformationRecords records = new CdmaInformationRecords();
+ private ArrayList<CdmaInformationRecords>
+ responseCdmaInformationRecord(Parcel p) {
+ int numberOfInfoRecs;
+ ArrayList<CdmaInformationRecords> response;
+
+ /**
+ * Loop through all of the information records unmarshalling them
+ * and converting them to Java Objects.
+ */
+ numberOfInfoRecs = p.readInt();
+ response = new ArrayList<CdmaInformationRecords>(numberOfInfoRecs);
- int numberOfInfoRecs = p.readInt();
for (int i = 0; i < numberOfInfoRecs; i++) {
- infoRecordName = p.readInt();
- switch(infoRecordName) {
- case CdmaInformationRecords.RIL_CDMA_DISPLAY_INFO_REC:
- case CdmaInformationRecords.RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
- records.setDispInfo(p.readString());
- break;
- case CdmaInformationRecords.RIL_CDMA_SIGNAL_INFO_REC:
- records.setSignInfo(p.readInt(), p.readInt(), p.readInt(), p.readInt());
- break;
- // InfoReocords with names as below aren't supported in AFW yet
- case CdmaInformationRecords.RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
- case CdmaInformationRecords.RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
- case CdmaInformationRecords.RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
- // TODO(Moto) implement
- p.readString(); // number
- p.readInt(); // number_type
- p.readInt(); // number_plan
- p.readInt(); // pi
- p.readInt(); // si
- break;
- case CdmaInformationRecords.RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
- // TODO(Moto) implement
- p.readString(); // redirecting number
- p.readInt(); // number_type
- p.readInt(); // number_plan
- p.readInt(); // pi
- p.readInt(); // si
- p.readInt(); // reason
- break;
- case CdmaInformationRecords.RIL_CDMA_LINE_CONTROL_INFO_REC:
- // TODO(Moto) implement
- p.readInt(); // PolarityIncluded
- p.readInt(); // Toggle
- p.readInt(); // Reverse
- p.readInt(); // PowerDenial
- break;
- case CdmaInformationRecords.RIL_CDMA_T53_CLIR_INFO_REC:
- // TODO(Moto) implement
- p.readInt(); // Cause
- break;
- case CdmaInformationRecords.RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
- // TODO(Moto) implement
- p.readInt(); // upLink
- p.readInt(); // downLink
- break;
- case CdmaInformationRecords.RIL_CDMA_T53_RELEASE_INFO_REC:
- // TODO(Moto) implement unknown fall through
- default:
- throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
- + records.recordToString(infoRecordName) + " ");
- }
+ CdmaInformationRecords InfoRec = new CdmaInformationRecords(p);
+ response.add(InfoRec);
}
- return records;
+
+ return response;
}
private Object
@@ -3013,6 +3052,54 @@ public final class RIL extends BaseCommands implements CommandsInterface {
return response;
}
+ private void
+ notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
+ int response = RIL_UNSOL_CDMA_INFO_REC;
+ if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
+ if (mDisplayInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mDisplayInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaSignalInfoRec) {
+ if (mSignalInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mSignalInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaNumberInfoRec) {
+ if (mNumberInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mNumberInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaRedirectingNumberInfoRec) {
+ if (mRedirNumInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mRedirNumInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaLineControlInfoRec) {
+ if (mLineControlInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mLineControlInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53ClirInfoRec) {
+ if (mT53ClirInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mT53ClirInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ } else if (infoRec.record instanceof CdmaInformationRecords.CdmaT53AudioControlInfoRec) {
+ if (mT53AudCntrlInfoRegistrants != null) {
+ if (RILJ_LOGD) unsljLogRet(response, infoRec.record);
+ mT53AudCntrlInfoRegistrants.notifyRegistrants(
+ new AsyncResult (null, infoRec.record, null));
+ }
+ }
+ }
+
static String
requestToString(int request) {
/*
@@ -3108,11 +3195,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_CDMA_BURST_DTMF: return "RIL_REQUEST_CDMA_BURST_DTMF";
case RIL_REQUEST_CDMA_SEND_SMS: return "RIL_REQUEST_CDMA_SEND_SMS";
case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE";
- case RIL_REQUEST_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GET_BROADCAST_CONFIG";
- case RIL_REQUEST_SET_BROADCAST_CONFIG: return "RIL_REQUEST_SET_BROADCAST_CONFIG";
+ case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_GET_BROADCAST_CONFIG";
+ case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG: return "RIL_REQUEST_GSM_SET_BROADCAST_CONFIG";
case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
- case RIL_REQUEST_BROADCAST_ACTIVATION: return "RIL_REQUEST_BROADCAST_ACTIVATION";
+ case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
case RIL_REQUEST_CDMA_VALIDATE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AKEY";
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
@@ -3122,6 +3209,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_GET_SMSC_ADDRESS: return "RIL_REQUEST_GET_SMSC_ADDRESS";
case RIL_REQUEST_SET_SMSC_ADDRESS: return "RIL_REQUEST_SET_SMSC_ADDRESS";
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
+ case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
+ case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
default: return "<unknown request>";
}
}
@@ -3290,7 +3379,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
sendCDMAFeatureCode(String FeatureCode, Message response) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_FLASH, response);
- rr.mp.writeInt(1);
rr.mp.writeString(FeatureCode);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
@@ -3318,11 +3406,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void activateCdmaBroadcastSms(int activate, Message response) {
+ public void setCdmaBroadcastActivation(boolean activate, Message response) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, response);
rr.mp.writeInt(1);
- rr.mp.writeInt(activate);
+ rr.mp.writeInt(activate ? 0 :1);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 26995ef..b2e16c7 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -78,9 +78,6 @@ public interface RILConstants {
int CDM_TTY_HCO_MODE = 2;
int CDM_TTY_VCO_MODE = 3;
- byte CDMA_VOICE_PRIVACY = 0x70; /* "p" value used in Ril_Call.isVoice if Privacy
- is active */
-
/*
cat include/telephony/ril.h | \
egrep '^#define' | \
@@ -209,9 +206,9 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_CDMA_VALIDATE_AKEY = 86;
int RIL_REQUEST_CDMA_SEND_SMS = 87;
int RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE = 88;
- int RIL_REQUEST_GET_BROADCAST_CONFIG = 89;
- int RIL_REQUEST_SET_BROADCAST_CONFIG = 90;
- int RIL_REQUEST_BROADCAST_ACTIVATION = 91;
+ int RIL_REQUEST_GSM_GET_BROADCAST_CONFIG = 89;
+ int RIL_REQUEST_GSM_SET_BROADCAST_CONFIG = 90;
+ int RIL_REQUEST_GSM_BROADCAST_ACTIVATION = 91;
int RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG = 92;
int RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG = 93;
int RIL_REQUEST_CDMA_BROADCAST_ACTIVATION = 94;
@@ -223,6 +220,7 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_GET_SMSC_ADDRESS = 100;
int RIL_REQUEST_SET_SMSC_ADDRESS = 101;
int RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
+ int RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 12808ce..a3016fa 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -26,6 +26,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.DialogInterface;
+import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
@@ -115,7 +116,7 @@ public abstract class SMSDispatcher extends Handler {
/** Maximum number of times to retry sending a failed SMS. */
private static final int MAX_SEND_RETRIES = 3;
/** Delay before next send attempt on a failed SMS, in milliseconds. */
- private static final int SEND_RETRY_DELAY = 2000;
+ private static final int SEND_RETRY_DELAY = 2000;
/** single part SMS */
private static final int SINGLE_PART_SMS = 1;
@@ -142,6 +143,7 @@ public abstract class SMSDispatcher extends Handler {
private static SmsMessage mSmsMessage;
private static SmsMessageBase mSmsMessageBase;
private SmsMessageBase.SubmitPduBase mSubmitPduBase;
+ private boolean mStorageAvailable = true;
protected static int getNextConcatenatedRef() {
sConcatenatedRef += 1;
@@ -171,11 +173,11 @@ public abstract class SMSDispatcher extends Handler {
/**
* Check to see if an application allow to send new SMS messages
- *
+ *
* @param appName is the application sending sms
* @param smsWaiting is the number of new sms wants to be sent
- * @return true if application is allowed to send the requested number
- * of new sms messages
+ * @return true if application is allowed to send the requested number
+ * of new sms messages
*/
boolean check(String appName, int smsWaiting) {
if (!mSmsStamp.containsKey(appName)) {
@@ -194,7 +196,7 @@ public abstract class SMSDispatcher extends Handler {
sent.remove(0);
}
-
+
if ( (sent.size() + smsWaiting) <= mMaxAllowed) {
for (int i = 0; i < smsWaiting; i++ ) {
sent.add(ct);
@@ -229,6 +231,15 @@ public abstract class SMSDispatcher extends Handler {
// Don't always start message ref at 0.
sConcatenatedRef = new Random().nextInt(256);
+
+ // Register for device storage intents. Use these to notify the RIL
+ // that storage for SMS is or is not available.
+ // TODO: Revisit this for a later release. Storage reporting should
+ // rely more on application indication.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
+ filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+ mContext.registerReceiver(mResultReceiver, filter);
}
public void dispose() {
@@ -277,7 +288,11 @@ public abstract class SMSDispatcher extends Handler {
sms = (SmsMessage) ar.result;
try {
- dispatchMessage(sms.mWrappedSmsMessage);
+ if (mStorageAvailable) {
+ dispatchMessage(sms.mWrappedSmsMessage);
+ } else {
+ acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_OUT_OF_MEMORY, null);
+ }
} catch (RuntimeException ex) {
acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
}
@@ -317,7 +332,7 @@ public abstract class SMSDispatcher extends Handler {
sendMultipartSms(mSTracker);
} else {
sendSms(mSTracker);
- }
+ }
mSTracker = null;
}
break;
@@ -697,7 +712,7 @@ public abstract class SMSDispatcher extends Handler {
/**
* Send the multi-part SMS based on multipart Sms tracker
- *
+ *
* @param tracker holds the multipart Sms tracker ready to be sent
*/
protected abstract void sendMultipartSms (SmsTracker tracker);
@@ -744,7 +759,7 @@ public abstract class SMSDispatcher extends Handler {
/**
* Check if a SmsTracker holds multi-part Sms
- *
+ *
* @param tracker a SmsTracker could hold a multi-part Sms
* @return true for tracker holds Multi-parts Sms
*/
@@ -775,7 +790,7 @@ public abstract class SMSDispatcher extends Handler {
mRetryCount = 0;
}
}
-
+
protected SmsTracker SmsTrackerFactory(HashMap data, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
return new SmsTracker(data, sentIntent, deliveryIntent);
@@ -795,12 +810,23 @@ public abstract class SMSDispatcher extends Handler {
private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- int rc = getResultCode();
- boolean success = (rc == Activity.RESULT_OK) || (rc == Intents.RESULT_SMS_HANDLED);
-
- // For a multi-part message, this only ACKs the last part.
- // Previous parts were ACK'd as they were received.
- acknowledgeLastIncomingSms(success, rc, null);
+ if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_LOW)) {
+ mStorageAvailable = false;
+ mCm.reportSmsMemoryStatus(false, null);
+ } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_OK)) {
+ mStorageAvailable = true;
+ mCm.reportSmsMemoryStatus(true, null);
+ } else {
+ // Assume the intent is one of the SMS receive intents that
+ // was sent as an ordered broadcast. Check result and ACK.
+ int rc = getResultCode();
+ boolean success = (rc == Activity.RESULT_OK)
+ || (rc == Intents.RESULT_SMS_HANDLED);
+
+ // For a multi-part message, this only ACKs the last part.
+ // Previous parts were ACK'd as they were received.
+ acknowledgeLastIncomingSms(success, rc, null);
+ }
}
};
diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
index 3c4df56..bd79e02 100644
--- a/telephony/java/com/android/internal/telephony/SmsResponse.java
+++ b/telephony/java/com/android/internal/telephony/SmsResponse.java
@@ -26,9 +26,15 @@ public class SmsResponse {
int messageRef;
/** ackPdu for the just-sent SMS. */
String ackPdu;
+ /**
+ * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS,
+ * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ int errorCode;
- public SmsResponse(int messageRef, String ackPdu) {
+ public SmsResponse(int messageRef, String ackPdu, int errorCode) {
this.messageRef = messageRef;
this.ackPdu = ackPdu;
+ this.errorCode = errorCode;
}
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index c78ceae..9152211 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -51,7 +51,7 @@ public class TelephonyIntents {
* <p class="note">
* Requires no permission.
*/
- public static final String ACTION_RADIO_TECHNOLOGY_CHANGED
+ public static final String ACTION_RADIO_TECHNOLOGY_CHANGED
= "android.intent.action.RADIO_TECHNOLOGY";
/**
* <p>Broadcast Action: The emergency callback mode is changed.
@@ -185,8 +185,9 @@ public class TelephonyIntents {
/**
* <p>Broadcast Action: It indicates the Emergency callback mode blocks datacall/sms
* <p class="note">.
+ * This is to pop up a notice to show user that the phone is in emergency callback mode
+ * and atacalls and outgoing sms are blocked.
*/
- // TODO(Moto): What is the use case, who is interested in this?
public static final String ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
= "android.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS";
@@ -202,6 +203,11 @@ public class TelephonyIntents {
// TODO(Moto): Generally broadcast intents are for use to allow entities which
// may not know about each other to "communicate". This seems quite specific
// and maybe using the registrant style would be better.
+
+ // Moto: Since this is used for apps not in the same process of phone, can the
+ // registrant style be used? (Ling Li says: Maybe the "app" can request rather
+ // than save the MDN each time and this intent would not be necessary?)
+ // Moto response: Moto internal discussion is on-going.
public static final String ACTION_CDMA_OTA_MDN_CHANGED
= "android.intent.action.ACTION_MDN_STATE_CHANGED";
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 4e8950f..290e1fc 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -101,4 +101,9 @@ public interface TelephonyProperties
/** Indicate if phone is in emergency callback mode */
static final String PROPERTY_INECM_MODE = "ril.cdma.inecmmode";
+ /** Indicate the timer value for exiting emergency callback mode */
+ static final String PROPERTY_ECM_EXIT_TIMER = "ro.cdma.ecmexittimer";
+
+ /** The international dialing prefix conversion string */
+ static final String PROPERTY_IDP_STRING = "ro.cdma.idpstring";
}
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index c851bc1..a9aacda 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -36,7 +36,7 @@ public class WapPushOverSms {
private SMSDispatcher mSmsDispatcher;
/**
- * Hold the wake lock for 5 seconds, which should be enough time for
+ * Hold the wake lock for 5 seconds, which should be enough time for
* any receiver(s) to grab its own wake lock.
*/
private final int WAKE_LOCK_TIMEOUT = 5000;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 0ebe507..9aa7eab 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -34,9 +34,6 @@ import android.telephony.SignalStrength;
import android.text.TextUtils;
import android.util.Log;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_INECM_MODE;
-
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
@@ -66,6 +63,9 @@ public class CDMAPhone extends PhoneBase {
static final String LOG_TAG = "CDMA";
private static final boolean LOCAL_DEBUG = true;
+ // Default Emergency Callback Mode exit timer
+ private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 30000;
+
//***** Instance Variables
CdmaCallTracker mCT;
CdmaSMSDispatcher mSMS;
@@ -93,7 +93,7 @@ public class CDMAPhone extends PhoneBase {
private Registrant mECMExitRespRegistrant;
private String mEsn;
private String mMeid;
-
+
// A runnable which is used to automatically exit from ECM after a period of time.
private Runnable mExitEcmRunnable = new Runnable() {
public void run() {
@@ -144,8 +144,8 @@ public class CDMAPhone extends PhoneBase {
SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
new Integer(RILConstants.CDMA_PHONE).toString());
- // TODO(Moto): Is this needed to handle phone crashes and/or power cycling?
- String inEcm=SystemProperties.get(PROPERTY_INECM_MODE, "false");
+ // This is needed to handle phone process crashes
+ String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
mIsPhoneInECMState = inEcm.equals("true");
}
@@ -288,16 +288,10 @@ public class CDMAPhone extends PhoneBase {
if (fc != null) {
//mMmiRegistrants.notifyRegistrants(new AsyncResult(null, fc, null));
fc.processCode();
- } else {
- FeatureCode digits = new FeatureCode(this);
- // use dial number as poundString
- digits.poundString = newDialString;
- digits.processCode();
+ return null;
}
- return null;
- } else {
- return mCT.dial(newDialString);
}
+ return mCT.dial(newDialString);
}
public SignalStrength getSignalStrength() {
@@ -388,6 +382,10 @@ public class CDMAPhone extends PhoneBase {
return mSST.getMdnNumber();
}
+ public String getCdmaPrlVersion(){
+ return mRuimRecords.getPrlVersion();
+ }
+
public String getCdmaMIN() {
return mSST.getCdmaMin();
}
@@ -420,8 +418,13 @@ public class CDMAPhone extends PhoneBase {
}
public String getSubscriberId() {
- Log.e(LOG_TAG, "method getSubscriberId for IMSI is NOT supported in CDMA!");
- return null;
+ // Subscriber ID is the combination of MCC+MNC+MIN as CDMA IMSI
+ // TODO(Moto): Replace with call to mRuimRecords.getIMSI_M() when implemented.
+ if ((getServiceState().getOperatorNumeric() != null) && (getCdmaMIN() != null)) {
+ return (getServiceState().getOperatorNumeric() + getCdmaMIN());
+ } else {
+ return null;
+ }
}
public boolean canConference() {
@@ -513,11 +516,11 @@ public class CDMAPhone extends PhoneBase {
}
public void registerForCallWaiting(Handler h, int what, Object obj) {
- Log.e(LOG_TAG, "method registerForCallWaiting is NOT yet supported in CDMA");
+ mCT.registerForCallWaiting(h, what, obj);
}
public void unregisterForCallWaiting(Handler h) {
- Log.e(LOG_TAG, "method unregisterForCallWaiting is NOT yet supported in CDMA");
+ mCT.unregisterForCallWaiting(h);
}
public String getIpAddress(String apnType) {
@@ -850,12 +853,12 @@ public class CDMAPhone extends PhoneBase {
mIsPhoneInECMState = true;
// notify change
sendEmergencyCallbackModeChange();
- setSystemProperty(PROPERTY_INECM_MODE, "true");
-
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "true");
+
// Post this runnable so we will automatically exit
// if no one invokes exitEmergencyCallbackMode() directly.
- // TODO(Moto): Get the delay a property so it can be adjusted
- long delayInMillis = 300000; // 30,000 millis == 5 minutes
+ long delayInMillis = SystemProperties.getLong(
+ TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
h.postDelayed(mExitEcmRunnable, delayInMillis);
}
}
@@ -874,7 +877,7 @@ public class CDMAPhone extends PhoneBase {
if (ar.exception == null) {
if (mIsPhoneInECMState) {
mIsPhoneInECMState = false;
- setSystemProperty(PROPERTY_INECM_MODE, "false");
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, "false");
}
// send an Intent
sendEmergencyCallbackModeChange();
@@ -911,7 +914,7 @@ public class CDMAPhone extends PhoneBase {
}
if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result);
- setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result);
+ setSystemProperty(TelephonyProperties.PROPERTY_BASEBAND_VERSION, (String)ar.result);
}
break;
@@ -977,7 +980,7 @@ public class CDMAPhone extends PhoneBase {
Log.d(LOG_TAG, "ERI read, notify registrants");
mEriFileLoadedRegistrants.notifyRegistrants();
}
- setSystemProperty(PROPERTY_INECM_MODE,"false");
+ setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE,"false");
}
break;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
index 34514d9..e8724c2 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCall.java
@@ -181,9 +181,7 @@ public final class CdmaCall extends Call {
*/
void
onHangupLocal() {
- for (int i = 0, s = connections.size()
- ; i < s; i++
- ) {
+ for (int i = 0, s = connections.size(); i < s; i++) {
CdmaConnection cn = (CdmaConnection)connections.get(i);
cn.onHangupLocal();
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index c02fcd4..da9fd0c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -58,6 +58,7 @@ public final class CdmaCallTracker extends CallTracker {
CdmaConnection connections[] = new CdmaConnection[MAX_CONNECTIONS];
RegistrantList voiceCallEndedRegistrants = new RegistrantList();
RegistrantList voiceCallStartedRegistrants = new RegistrantList();
+ RegistrantList callWaitingRegistrants = new RegistrantList();
// connections dropped durin last poll
@@ -93,13 +94,15 @@ public final class CdmaCallTracker extends CallTracker {
cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null);
+ cm.registerForCallWaitingInfo(this, EVENT_CALL_WAITING_INFO_CDMA, null);
+ foregroundCall.setGeneric(false);
}
public void dispose() {
cm.unregisterForCallStateChanged(this);
cm.unregisterForOn(this);
cm.unregisterForNotAvailable(this);
-
+ cm.unregisterForCallWaitingInfo(this);
for(CdmaConnection c : connections) {
try {
if(c != null) hangup(c);
@@ -143,6 +146,15 @@ public final class CdmaCallTracker extends CallTracker {
voiceCallEndedRegistrants.remove(h);
}
+ public void registerForCallWaiting(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ callWaitingRegistrants.add(r);
+ }
+
+ public void unregisterForCallWaiting(Handler h) {
+ callWaitingRegistrants.remove(h);
+ }
+
private void
fakeHoldForegroundBeforeDial() {
List<Connection> connCopy;
@@ -170,34 +182,24 @@ public final class CdmaCallTracker extends CallTracker {
throw new CallStateException("cannot dial in current state");
}
+
+ // We are initiating a call therefore even if we previously
+ // didn't know the state (i.e. Generic was true) we now know
+ // and therefore can set Generic to false.
+ foregroundCall.setGeneric(false);
+
// The new call must be assigned to the foreground call.
// That call must be idle, so place anything that's
// there on hold
if (foregroundCall.getState() == CdmaCall.State.ACTIVE) {
- // this will probably be done by the radio anyway
- // but the dial might fail before this happens
- // and we need to make sure the foreground call is clear
- // for the newly dialed connection
- switchWaitingOrHoldingAndActive();
-
- // Fake local state so that
- // a) foregroundCall is empty for the newly dialed connection
- // b) hasNonHangupStateChanged remains false in the
- // next poll, so that we don't clear a failed dialing call
- fakeHoldForegroundBeforeDial();
- }
-
- if (foregroundCall.getState() != CdmaCall.State.IDLE) {
- //we should have failed in !canDial() above before we get here
- throw new CallStateException("cannot dial in current state");
+ return dialThreeWay(dialString);
}
pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall);
hangupPendingMO = false;
if (pendingMO.address == null || pendingMO.address.length() == 0
- || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0
- ) {
+ || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0) {
// Phone number is invalid
pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER;
@@ -231,19 +233,39 @@ public final class CdmaCallTracker extends CallTracker {
return dial(dialString, CommandsInterface.CLIR_DEFAULT);
}
- void
- acceptCall () throws CallStateException {
- // FIXME if SWITCH fails, should retry with ANSWER
- // in case the active/holding call disappeared and this
- // is no longer call waiting
+ private Connection
+ dialThreeWay (String dialString) {
+ if (!foregroundCall.isIdle()) {
+ // Attach the new connection to foregroundCall
+ pendingMO = new CdmaConnection(phone.getContext(),
+ dialString, this, foregroundCall);
+ cm.sendCDMAFeatureCode(pendingMO.address,
+ obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA));
+ return pendingMO;
+ }
+ return null;
+ }
+ void
+ acceptCall() throws CallStateException {
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
Log.i("phone", "acceptCall: incoming...");
// Always unmute when answering a new call
setMute(false);
cm.acceptCall(obtainCompleteMessage());
- } else if (ringingCall.getState() == CdmaCall.State.WAITING) {
- setMute(false);
+ } else if ((foregroundCall.connections.size() > 0) &&
+ (ringingCall.getState() == CdmaCall.State.WAITING)) {
+ // TODO(Moto): jsh asks, "Is this check necessary? I don't think it should be
+ // possible to have no fg connection and a WAITING call, but if we should hit
+ // this situation, is a CallStateExcetion appropriate?"
+ CdmaConnection cwConn = (CdmaConnection)(ringingCall.getLatestConnection());
+
+ // Since there is no network response for supplimentary
+ // service for CDMA, we assume call waiting is answered.
+ // ringing Call state change to idle is in CdmaCall.detach
+ // triggered by updateParent.
+ cwConn.updateParent(ringingCall, foregroundCall);
+ cwConn.onConnectedInOrOut();
switchWaitingOrHoldingAndActive();
} else {
throw new CallStateException("phone not ringing");
@@ -267,14 +289,14 @@ public final class CdmaCallTracker extends CallTracker {
if (ringingCall.getState() == CdmaCall.State.INCOMING) {
throw new CallStateException("cannot be in the incoming state");
} else {
- cm.sendCDMAFeatureCode("", obtainCompleteMessage(EVENT_SWITCH_RESULT));
+ flashAndSetGenericTrue();
}
}
void
conference() throws CallStateException {
- // three way calls in CDMA will be handled by feature codes
- Log.e(LOG_TAG, "conference: not possible in CDMA");
+ // Should we be checking state?
+ flashAndSetGenericTrue();
}
void
@@ -307,6 +329,7 @@ public final class CdmaCallTracker extends CallTracker {
pendingMO == null
&& !ringingCall.isRinging()
&& (!foregroundCall.getState().isAlive()
+ || (foregroundCall.getState() == CdmaCall.State.ACTIVE)
|| !backgroundCall.getState().isAlive());
return ret;
@@ -495,9 +518,24 @@ public final class CdmaCallTracker extends CallTracker {
}
hasNonHangupStateChanged = true;
} else if (conn != null && dc == null) {
- // Connection missing in CLCC response that we were
- // tracking.
- droppedDuringPoll.add(conn);
+ int count = foregroundCall.connections.size();
+ if (count == 0) {
+ // Handle an unanswered MO/MT call, there is no
+ // foregroundCall connections at this time.
+ droppedDuringPoll.add(conn);
+ } else {
+ // Loop through foreground call connections as
+ // it contains the known logical connections.
+ for (int n = 0; n < count; n++) {
+ CdmaConnection cn = (CdmaConnection)foregroundCall.connections.get(n);
+ droppedDuringPoll.add(cn);
+ }
+ // TODO(Moto): jsh asks, "Are we sure we don't need to do this for
+ // ringingCall as well? What if there's a WAITING call (ie, UI timer
+ // hasn't expired, moving it to DISCONNECTED)? How/when will it
+ // transition to DISCONNECTED?"
+ }
+ foregroundCall.setGeneric(false);
// Dropped connections are removed from the CallTracker
// list but kept in the Call list
connections[i] = null;
@@ -634,6 +672,18 @@ public final class CdmaCallTracker extends CallTracker {
if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true");
hangupPendingMO = true;
+ } else if ((conn.getCall() == ringingCall)
+ && (ringingCall.getState() == CdmaCall.State.WAITING)) {
+ // Handle call waiting hang up case.
+ //
+ // The ringingCall state will change to IDLE in CdmaCall.detach
+ // if the ringing call connection size is 0. We don't specifically
+ // set the ringing call state to IDLE here to avoid a race condition
+ // where a new call waiting could get a hang up from an old call
+ // waiting ringingCall.
+ // TODO(Moto): jsh asks, "Should we call conn.ondisconnect() here or Somewhere?"
+ ringingCall.detach(conn);
+ return;
} else {
try {
cm.hangupConnection (conn.getCDMAIndex(), obtainCompleteMessage());
@@ -768,6 +818,16 @@ public final class CdmaCallTracker extends CallTracker {
return null;
}
+ private void flashAndSetGenericTrue() throws CallStateException {
+ cm.sendCDMAFeatureCode("", obtainMessage(EVENT_SWITCH_RESULT));
+
+ // Set generic to true because in CDMA it is not known what
+ // the status of the call is after a call waiting is answered,
+ // 3 way call merged or a switch between calls.
+ foregroundCall.setGeneric(true);
+ phone.notifyCallStateChanged();
+ }
+
private Phone.SuppService getFailedService(int what) {
switch (what) {
case EVENT_SWITCH_RESULT:
@@ -789,6 +849,30 @@ public final class CdmaCallTracker extends CallTracker {
pollCallsWhenSafe();
}
+ private void notifyCallWaitingInfo(CdmaCallWaitingNotification obj) {
+ if (callWaitingRegistrants != null) {
+ callWaitingRegistrants.notifyRegistrants(new AsyncResult(null, obj, null));
+ }
+ }
+
+ private void handleCallWaitingInfo (CdmaCallWaitingNotification cw) {
+ // Check how many connections in foregroundCall.
+ // If the connection in foregroundCall is more
+ // than one, then the connection information is
+ // not reliable anymore since it means either
+ // call waiting is connected or 3 way call is
+ // dialed before, so set generic.
+ if (foregroundCall.connections.size() > 1 ) {
+ foregroundCall.setGeneric(true);
+ }
+
+ // Create a new CdmaConnection which attaches itself to ringingCall.
+ ringingCall.setGeneric(false);
+ new CdmaConnection(phone.getContext(), cw, this, ringingCall);
+
+ // Finally notify application
+ notifyCallWaitingInfo(cw);
+ }
//****** Overridden from Handler
public void
@@ -811,13 +895,13 @@ public final class CdmaCallTracker extends CallTracker {
break;
case EVENT_OPERATION_COMPLETE:
- ar = (AsyncResult)msg.obj;
operationComplete();
break;
case EVENT_SWITCH_RESULT:
- ar = (AsyncResult)msg.obj;
- operationComplete();
+ // In GSM call operationComplete() here which gets the
+ // current call list. But in CDMA there is no list so
+ // there is nothing to do.
break;
case EVENT_GET_LAST_CALL_FAIL_CAUSE:
@@ -850,6 +934,7 @@ public final class CdmaCallTracker extends CallTracker {
droppedDuringPoll.clear();
break;
+ case EVENT_REPOLL_AFTER_DELAY:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
@@ -871,6 +956,22 @@ public final class CdmaCallTracker extends CallTracker {
phone.unsetOnEcbModeExitResponse(this);
break;
+ case EVENT_CALL_WAITING_INFO_CDMA:
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception == null) {
+ handleCallWaitingInfo((CdmaCallWaitingNotification)ar.result);
+ Log.d(LOG_TAG, "Event EVENT_CALL_WAITING_INFO_CDMA Received");
+ }
+ break;
+
+ case EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA:
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception == null) {
+ // Assume 3 way call is connected
+ pendingMO.onConnectedInOrOut();
+ }
+ break;
+
default:{
throw new RuntimeException("unexpected event not handled");
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 32442f6..588bdf0 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -25,11 +25,14 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.Registrant;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.Config;
import android.util.Log;
+import android.text.TextUtils;
+
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
-
+import com.android.internal.telephony.TelephonyProperties;
/**
* {@hide}
@@ -90,17 +93,7 @@ public class CdmaConnection extends Connection {
//***** Constants
static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
static final int PAUSE_DELAY_MILLIS = 2 * 1000;
-
- // TODO(Moto): These should be come from a resourse file
- // at a minimum as different carriers may want to use
- // different characters and our general default is "," & ";".
- // Furthermore Android supports contacts that have phone
- // numbers entered as strings so '1-800-164flowers' would not
- // be handled as expected. Both issues need to be resolved.
- static final char CUSTOMERIZED_WAIT_CHAR_UPPER ='W';
- static final char CUSTOMERIZED_WAIT_CHAR_LOWER ='w';
- static final char CUSTOMERIZED_PAUSE_CHAR_UPPER ='P';
- static final char CUSTOMERIZED_PAUSE_CHAR_LOWER ='p';
+
//***** Inner Classes
class MyHandler extends Handler {
@@ -147,19 +140,9 @@ public class CdmaConnection extends Connection {
parent.attach(this, dc);
}
- CdmaConnection () {
- owner = null;
- h = null;
- address = null;
- index = -1;
- parent = null;
- isIncoming = true;
- createTime = System.currentTimeMillis();
- }
-
- /** This is an MO call, created when dialing */
+ /** This is an MO call/three way call, created when dialing */
/*package*/
- CdmaConnection (Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
+ CdmaConnection(Context context, String dialString, CdmaCallTracker ct, CdmaCall parent) {
createWakeLock(context);
acquireWakeLock();
@@ -184,10 +167,36 @@ public class CdmaConnection extends Connection {
if (parent != null) {
this.parent = parent;
- parent.attachFake(this, CdmaCall.State.DIALING);
+
+ //for the three way call case, not change parent state
+ if (parent.state == CdmaCall.State.ACTIVE) {
+ parent.attachFake(this, CdmaCall.State.ACTIVE);
+ } else {
+ parent.attachFake(this, CdmaCall.State.DIALING);
+ }
}
}
+ /** This is a Call waiting call*/
+ CdmaConnection(Context context, CdmaCallWaitingNotification cw, CdmaCallTracker ct,
+ CdmaCall parent) {
+ createWakeLock(context);
+ acquireWakeLock();
+
+ owner = ct;
+ h = new MyHandler(owner.getLooper());
+ address = cw.number;
+ numberPresentation = cw.numberPresentation;
+ cnapName = cw.name;
+ cnapNamePresentation = cw.namePresentation;
+ index = -1;
+ isIncoming = true;
+ createTime = System.currentTimeMillis();
+ connectTime = 0;
+ this.parent = parent;
+ parent.attachFake(this, CdmaCall.State.WAITING);
+ }
+
public void dispose() {
}
@@ -363,16 +372,6 @@ public class CdmaConnection extends Connection {
}
}
- /**
- * Used for 3way call only
- */
- void update (CdmaConnection c) {
- address = c.address;
- cnapName = c.cnapName;
- cnapNamePresentation = c.cnapNamePresentation;
- numberPresentation = c.numberPresentation;
- }
-
public void cancelPostDial() {
setPostDialState(PostDialState.CANCELLED);
}
@@ -408,7 +407,7 @@ public class CdmaConnection extends Connection {
case CallFailCause.CDMA_LOCKED_UNTIL_POWER_CYCLE:
return DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE;
case CallFailCause.CDMA_DROP:
- return DisconnectCause.LOST_SIGNAL; // TODO(Moto): wink/dave changed from CDMA_DROP;
+ return DisconnectCause.CDMA_DROP;
case CallFailCause.CDMA_INTERCEPT:
return DisconnectCause.CDMA_INTERCEPT;
case CallFailCause.CDMA_REORDER:
@@ -488,15 +487,16 @@ public class CdmaConnection extends Connection {
}
// A null cnapName should be the same as ""
- if (null != dc.name) {
- if (cnapName != dc.name) {
- cnapName = dc.name;
+ if (TextUtils.isEmpty(dc.name)) {
+ if (!TextUtils.isEmpty(cnapName)) {
changed = true;
+ cnapName = "";
}
- } else {
- cnapName = "";
- // TODO(Moto): Should changed = true if cnapName wasn't previously ""
+ } else if (!dc.name.equals(cnapName)) {
+ changed = true;
+ cnapName = dc.name;
}
+
log("--dssds----"+cnapName);
cnapNamePresentation = dc.namePresentation;
numberPresentation = dc.numberPresentation;
@@ -631,21 +631,7 @@ public class CdmaConnection extends Connection {
int wIndex = subStr.indexOf(PhoneNumberUtils.WAIT);
int pIndex = subStr.indexOf(PhoneNumberUtils.PAUSE);
- // TODO(Moto): Courtesy of jsh; is this simpler expression equivalent?
- //
- // if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) {
- // subStr = subStr.substring(0, wIndex);
- // } else if (pIndex > 0) {
- // subStr = subStr.substring(0, pIndex);
- // }
-
- if (wIndex > 0 && pIndex > 0) {
- if (wIndex > pIndex) {
- subStr = subStr.substring(0, pIndex);
- } else {
- subStr = subStr.substring(0, wIndex);
- }
- } else if (wIndex > 0) {
+ if (wIndex > 0 && (wIndex < pIndex || pIndex <= 0)) {
subStr = subStr.substring(0, wIndex);
} else if (pIndex > 0) {
subStr = subStr.substring(0, pIndex);
@@ -654,6 +640,16 @@ public class CdmaConnection extends Connection {
return subStr;
}
+ public void updateParent(CdmaCall oldParent, CdmaCall newParent){
+ if (newParent != oldParent) {
+ if (oldParent != null) {
+ oldParent.detach(this);
+ }
+ newParent.attachFake(this, CdmaCall.State.ACTIVE);
+ parent = newParent;
+ }
+ }
+
@Override
protected void finalize()
{
@@ -795,114 +791,121 @@ public class CdmaConnection extends Connection {
}
private static boolean isPause(char c) {
- if (c == CUSTOMERIZED_PAUSE_CHAR_UPPER || c == CUSTOMERIZED_PAUSE_CHAR_LOWER
- || c == PhoneNumberUtils.PAUSE) {
- return true;
- } else {
- return false;
- }
+ return c == PhoneNumberUtils.PAUSE;
}
private static boolean isWait(char c) {
- if (c == CUSTOMERIZED_WAIT_CHAR_LOWER || c == CUSTOMERIZED_WAIT_CHAR_UPPER
- || c == PhoneNumberUtils.WAIT) {
- return true;
- } else {
- return false;
+ return c == PhoneNumberUtils.WAIT;
+ }
+
+
+
+
+ // This function is to find the next PAUSE character index if
+ // multiple pauses in a row. Otherwise it finds the next non PAUSE or
+ // non WAIT character index.
+ private static int
+ findNextPCharOrNonPOrNonWCharIndex(String phoneNumber, int currIndex) {
+ boolean wMatched = false;
+ int index = currIndex + 1;
+ int length = phoneNumber.length();
+ while (index < length) {
+ char cNext = phoneNumber.charAt(index);
+ // if there is any W inside P/W sequence,mark it
+ if (isWait(cNext)) {
+ wMatched = true;
+ }
+ // if any characters other than P/W chars after P/W sequence
+ // we break out the loop and append the correct
+ if (!isWait(cNext) && !isPause(cNext)) {
+ break;
+ }
+ index++;
+ }
+
+ // It means the PAUSE character(s) is in the middle of dial string
+ // and it needs to be handled one by one.
+ if ((index < length) && (index > (currIndex + 1)) &&
+ ((wMatched == false) && isPause(phoneNumber.charAt(currIndex)))) {
+ return (currIndex + 1);
+ }
+ return index;
+ }
+
+ // This function returns either PAUSE or WAIT character to append.
+ // It is based on the next non PAUSE/WAIT character in the phoneNumber and the
+ // index for the current PAUSE/WAIT character
+ private static char
+ findPOrWCharToAppend(String phoneNumber, int currPwIndex, int nextNonPwCharIndex) {
+ char c = phoneNumber.charAt(currPwIndex);
+ char ret;
+
+ // Append the PW char
+ ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
+
+ // if there is a PAUSE in at the begining of PW character sequences, and this
+ // PW character sequences has more than 2 PAUSE and WAIT Characters,skip P, append W
+ if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 1))) {
+ ret = PhoneNumberUtils.WAIT;
}
+ return ret;
}
+
/**
- * format string
- * convert "+" to "011"
- * handle corner cases for PAUSE/WAIT
- * If PAUSE/WAIT sequence at the end,ignore them
- * If PAUSE/WAIT sequence in the middle, then if there is any WAIT
- * in PAUSE/WAIT sequence, treat them like WAIT
- * If PAUSE followed by WAIT or WAIT followed by PAUSE in the middle,
- * treat them like just PAUSE or WAIT
+ * format orignal dial string
+ * 1) convert international dialing prefix "+" to
+ * string specified per region
+ *
+ * 2) handle corner cases for PAUSE/WAIT dialing:
+ *
+ * If PAUSE/WAIT sequence at the end, ignore them.
+ *
+ * If consecutive PAUSE/WAIT sequence in the middle of the string,
+ * and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
*/
- private static String formatDialString(String phoneNumber) {
+ public static String formatDialString(String phoneNumber) {
if (phoneNumber == null) {
return null;
}
int length = phoneNumber.length();
StringBuilder ret = new StringBuilder();
-
- // TODO(Moto): Modifying the for loop index is confusing, a
- // while loop is probably better and overall this code is
- // hard to follow. If this was routine was refactored and
- // used several private methods with good names to make it
- // easier to follow.
- for (int i = 0; i < length; i++) {
- char c = phoneNumber.charAt(i);
-
+ char c;
+ int currIndex = 0;
+ while (currIndex < length) {
+ c = phoneNumber.charAt(currIndex);
if (PhoneNumberUtils.isDialable(c)) {
if (c == '+') {
- // TODO(Moto): Is this valid for "all" countries????
- // should probably be pulled from a resource based
- // on current contry code (MCC).
- ret.append("011");
+ String ps = null;
+ SystemProperties.get(TelephonyProperties.PROPERTY_IDP_STRING, ps);
+ if (TextUtils.isEmpty(ps)) {
+ ps = "011";
+ }
+ ret.append(ps);
} else {
ret.append(c);
}
} else if (isPause(c) || isWait(c)) {
- if (i < length - 1) { // if PAUSE/WAIT not at the end
- int index = 0;
- boolean wMatched = false;
- for (index = i + 1; index < length; index++) {
- char cNext = phoneNumber.charAt(index);
- // if there is any W inside P/W sequence,mark it
- if (isWait(cNext)) {
- wMatched = true;
- }
- // if any characters other than P/W chars after P/W sequence
- // we break out the loop and append the correct
- if (!isWait(cNext) && !isPause(cNext)) {
- break;
+ if (currIndex < length - 1) {
+ // if PW not at the end
+ int nextIndex = findNextPCharOrNonPOrNonWCharIndex(phoneNumber, currIndex);
+ // If there is non PW char following PW sequence
+ if (nextIndex < length) {
+ char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
+ ret.append(pC);
+ // If PW char is immediately followed by non-PW char
+ if (nextIndex > (currIndex + 1)) {
+ currIndex = nextIndex - 1;
}
+ } else if (nextIndex == length) {
+ // It means PW characters at the end, ignore
+ currIndex = length - 1;
}
- if (index == length) {
- // it means there is no dialable character after PAUSE/WAIT
- i = length - 1;
- break;
- } else {// means index <length
- if (isPause(c)) {
- c = PhoneNumberUtils.PAUSE;
- } else if (isWait(c)) {
- c = PhoneNumberUtils.WAIT;
- }
-
- if (index == i + 1) {
- ret.append(c);
- } else if (isWait(c)) {
- // for case like 123WP456 =123P456
- if ((index == i + 2) && isPause(phoneNumber.charAt(index - 1))) {
- // skip W,append P
- ret.append(PhoneNumberUtils.PAUSE);
- } else {
- // append W
- ret.append(c);
- }
- i = index - 1;
- } else if (isPause(c)) {
-
- // for case like 123PW456 =123W456, skip p, append W
- // or there is 1 W in between, treat the whole PW
- // sequence as W
- if (wMatched == true) {
- // skip P,append W
- ret.append(PhoneNumberUtils.WAIT);
- i = index - 1;
- } else {
- ret.append(c);
- }
- } // end of pause case
- } // end of index <length, it means dialable characters after P/W
}
- } else { // if it's characters other than P/W
+ } else {
ret.append(c);
}
+ currIndex++;
}
return ret.toString();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index a9c0f46..f2b07a8 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -233,7 +233,7 @@ public class CdmaDataConnection extends DataConnection {
switch (rilCause) {
case PS_NET_DOWN_REASON_OPERATOR_DETERMINED_BARRING:
- cause = FailCause.BARRED;
+ cause = FailCause.OPERATOR_BARRED;
break;
case PS_NET_DOWN_REASON_AUTH_FAILED:
cause = FailCause.USER_AUTHENTICATION;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 900480f..2a65de3 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -304,7 +304,10 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
} else if (!enable) {
setEnabled(EXTERNAL_NETWORK_DEFAULT_ID, false);
- cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = Phone.REASON_DATA_DISABLED;
+ sendMessage(msg);
}
return true;
}
@@ -401,6 +404,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
mReconnectIntent = null;
}
+ setState(State.DISCONNECTING);
+
for (DataConnection connBase : dataConnectionList) {
CdmaDataConnection conn = (CdmaDataConnection) connBase;
@@ -416,24 +421,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
stopNetStatPoll();
- /*
- * If we've been asked to tear down the connection,
- * set the state to DISCONNECTING. However, there's
- * a race that can occur if for some reason we were
- * already in the IDLE state. In that case, the call
- * to conn.disconnect() above will immediately post
- * a message to the handler thread that the disconnect
- * is done, and if the handler runs before the code
- * below does, the handler will have set the state to
- * IDLE before the code below runs. If we didn't check
- * for that, future calls to trySetupData would fail,
- * and we would never get out of the DISCONNECTING state.
- */
if (!tearDown) {
setState(State.IDLE);
phone.notifyDataConnection(reason);
- } else if (state != State.IDLE) {
- setState(State.DISCONNECTING);
}
}
@@ -756,16 +746,9 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
+ return;
}
-
- if (tryAgain(cause)) {
- // Wait a bit before trying again, so that
- // we're not tying up the RIL command channel
- sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
- RECONNECT_DELAY_INITIAL_MILLIS);
- } else {
- startDelayedRetry(cause, reason);
- }
+ startDelayedRetry(cause, reason);
}
}
@@ -808,6 +791,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
resetPollStats();
}
} else {
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED);
}
@@ -820,14 +805,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
cleanUpConnection(tearDown, reason);
}
- private boolean tryAgain(FailCause cause) {
- return (cause != FailCause.RADIO_NOT_AVAILABLE)
- && (cause != FailCause.RADIO_OFF)
- && (cause != FailCause.RADIO_ERROR_RETRY)
- && (cause != FailCause.NO_SIGNAL)
- && (cause != FailCause.SIM_LOCKED);
- }
-
private void createAllDataConnectionList() {
dataConnectionList = new ArrayList<DataConnection>();
CdmaDataConnection dataConn;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
index 93a6aa4..7402769 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java
@@ -16,8 +16,14 @@
package com.android.internal.telephony.cdma;
import static com.android.internal.telephony.RILConstants.*;
+import android.os.Parcel;
public final class CdmaInformationRecords {
+ public Object record;
+
+ /**
+ * Record type identifier
+ */
public static final int RIL_CDMA_DISPLAY_INFO_REC = 0;
public static final int RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC = 1;
public static final int RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC = 2;
@@ -30,34 +36,54 @@ public final class CdmaInformationRecords {
public static final int RIL_CDMA_T53_RELEASE_INFO_REC = 9;
public static final int RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC = 10;
- public boolean isDispInfo;
- public boolean isSignInfo;
- public String cdmaDisplayInfoRecord;
- public int[] cdmaSignalInfoRecord;
+ public CdmaInformationRecords(Parcel p) {
+ int id = p.readInt();
+ switch (id) {
+ case RIL_CDMA_DISPLAY_INFO_REC:
+ case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
+ record = new CdmaDisplayInfoRec(id, p.readString());
+ break;
- private static final int ALPHA_LEN_FOR_DISPLAY_INFO = 64;
+ case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
+ case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
+ case RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
+ record = new CdmaNumberInfoRec(id, p.readString(), p.readInt(), p.readInt(),
+ p.readInt(), p.readInt());
+ break;
- public CdmaInformationRecords() {
- isDispInfo = false;
- isSignInfo = false;
- }
+ case RIL_CDMA_SIGNAL_INFO_REC:
+ record = new CdmaSignalInfoRec(p.readInt(), p.readInt(), p.readInt(), p.readInt());
+ break;
- public void setDispInfo(String resString) {
- isDispInfo = true;
- cdmaDisplayInfoRecord = resString;
- }
+ case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
+ record = new CdmaRedirectingNumberInfoRec(p.readString(), p.readInt(), p.readInt(),
+ p.readInt(), p.readInt(), p.readInt());
+ break;
+
+ case RIL_CDMA_LINE_CONTROL_INFO_REC:
+ record = new CdmaLineControlInfoRec(p.readInt(), p.readInt(), p.readInt(),
+ p.readInt());
+ break;
+
+ case RIL_CDMA_T53_CLIR_INFO_REC:
+ record = new CdmaT53ClirInfoRec(p.readInt());
+ break;
+
+ case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
+ record = new CdmaT53AudioControlInfoRec(p.readInt(), p.readInt());
+ break;
+
+ case RIL_CDMA_T53_RELEASE_INFO_REC:
+ // TODO(Moto): WHAT to do, for now fall through and throw exception
+ default:
+ throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
+ + CdmaInformationRecords.idToString(id) + " ");
- public void setSignInfo(int isPresent, int signalType, int alertPitch, int signal) {
- isSignInfo = true;
- cdmaSignalInfoRecord = new int[4];
- cdmaSignalInfoRecord[0] = isPresent;
- cdmaSignalInfoRecord[1] = signalType;
- cdmaSignalInfoRecord[2] = alertPitch;
- cdmaSignalInfoRecord[3] = signal;
+ }
}
- public String recordToString (int record) {
- switch(record) {
+ public static String idToString(int id) {
+ switch(id) {
case RIL_CDMA_DISPLAY_INFO_REC: return "RIL_CDMA_DISPLAY_INFO_REC";
case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC";
case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: return "RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC";
@@ -72,4 +98,166 @@ public final class CdmaInformationRecords {
default: return "<unknown record>";
}
}
+
+ /**
+ * Signal Information record from 3GPP2 C.S005 3.7.5.5
+ */
+ public static class CdmaSignalInfoRec {
+ public boolean isPresent; /* non-zero if signal information record is present */
+ public int signalType;
+ public int alertPitch;
+ public int signal;
+
+ public CdmaSignalInfoRec() {}
+
+ public CdmaSignalInfoRec(int isPresent, int signalType, int alertPitch, int signal) {
+ this.isPresent = isPresent != 0;
+ this.signalType = signalType;
+ this.alertPitch = alertPitch;
+ this.signal = signal;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaSignalInfo: {" +
+ " isPresent: " + isPresent +
+ ", signalType: " + signalType +
+ ", alertPitch: " + alertPitch +
+ ", signal: " + signal +
+ " }";
+ }
+ }
+
+ public static class CdmaDisplayInfoRec {
+ public int id;
+ public String alpha;
+
+ public CdmaDisplayInfoRec(int id, String alpha) {
+ this.id = id;
+ this.alpha = alpha;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaDisplayInfoRec: {" +
+ " id: " + CdmaInformationRecords.idToString(id) +
+ ", alpha: " + alpha +
+ " }";
+ }
+ }
+
+ public static class CdmaNumberInfoRec {
+ public int id;
+ public String number;
+ public byte numberType;
+ public byte numberPlan;
+ public byte pi;
+ public byte si;
+
+ public CdmaNumberInfoRec(int id, String number, int numberType, int numberPlan, int pi,
+ int si) {
+ this.number = number;
+ this.numberType = (byte)numberType;
+ this.numberPlan = (byte)numberPlan;
+ this.pi = (byte)pi;
+ this.si = (byte)si;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaNumberInfoRec: {" +
+ " id: " + CdmaInformationRecords.idToString(id) +
+ ", number: " + number +
+ ", numberType: " + numberType +
+ ", numberPlan: " + numberPlan +
+ ", pi: " + pi +
+ ", si: " + si +
+ " }";
+ }
+ }
+
+ public static class CdmaRedirectingNumberInfoRec {
+ public static final int REASON_UNKNOWN = 0;
+ public static final int REASON_CALL_FORWARDING_BUSY = 1;
+ public static final int REASON_CALL_FORWARDING_NO_REPLY = 2;
+ public static final int REASON_CALLED_DTE_OUT_OF_ORDER = 9;
+ public static final int REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
+ public static final int REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
+
+ public CdmaNumberInfoRec numberInfoRec;
+ public int redirectingReason;
+
+ public CdmaRedirectingNumberInfoRec(String number, int numberType, int numberPlan,
+ int pi, int si, int reason) {
+ numberInfoRec = new CdmaNumberInfoRec(RIL_CDMA_REDIRECTING_NUMBER_INFO_REC,
+ number, numberType, numberPlan, pi, si);
+ redirectingReason = reason;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaNumberInfoRec: {" +
+ " numberInfoRec: " + numberInfoRec +
+ ", redirectingReason: " + redirectingReason +
+ " }";
+ }
+ }
+
+ public static class CdmaLineControlInfoRec {
+ public byte lineCtrlPolarityIncluded;
+ public byte lineCtrlToggle;
+ public byte lineCtrlReverse;
+ public byte lineCtrlPowerDenial;
+
+ public CdmaLineControlInfoRec(int lineCtrlPolarityIncluded, int lineCtrlToggle,
+ int lineCtrlReverse, int lineCtrlPowerDenial) {
+ this.lineCtrlPolarityIncluded = (byte)lineCtrlPolarityIncluded;
+ this.lineCtrlToggle = (byte)lineCtrlToggle;
+ this.lineCtrlReverse = (byte)lineCtrlReverse;
+ this.lineCtrlPowerDenial = (byte)lineCtrlPowerDenial;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaLineControlInfoRec: {" +
+ " lineCtrlPolarityIncluded: " + lineCtrlPolarityIncluded +
+ " lineCtrlToggle: " + lineCtrlToggle +
+ " lineCtrlReverse: " + lineCtrlReverse +
+ " lineCtrlPowerDenial: " + lineCtrlPowerDenial +
+ " }";
+ }
+ }
+
+ public static class CdmaT53ClirInfoRec {
+ public byte cause;
+
+ public CdmaT53ClirInfoRec(int cause) {
+ this.cause = (byte)cause;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaT53ClirInfoRec: {" +
+ " cause: " + cause +
+ " }";
+ }
+ }
+
+ public static class CdmaT53AudioControlInfoRec {
+ public byte uplink;
+ public byte downlink;
+
+ public CdmaT53AudioControlInfoRec(int uplink, int downlink) {
+ this.uplink = (byte) uplink;
+ this.downlink = (byte) downlink;
+ }
+
+ @Override
+ public String toString() {
+ return "CdmaT53AudioControlInfoRec: {" +
+ " uplink: " + uplink +
+ " downlink: " + downlink +
+ " }";
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index f12e7e3..79e1cd6 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -342,7 +342,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher {
/** {@inheritDoc} */
protected void activateCellBroadcastSms(int activate, Message response) {
- mCm.activateCdmaBroadcastSms(activate, response);
+ mCm.setCdmaBroadcastActivation((activate == 0), response);
}
/** {@inheritDoc} */
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 12ceeaf..0be09b9 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -19,8 +19,11 @@ package com.android.internal.telephony.cdma;
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContentValues;
import android.content.Intent;
import android.database.ContentObserver;
+import android.database.SQLException;
+import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
@@ -32,6 +35,7 @@ import android.os.SystemProperties;
import android.provider.Checkin;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.provider.Telephony;
import android.provider.Telephony.Intents;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -134,6 +138,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
static final String LOG_TAG = "CDMA";
private ContentResolver cr;
+ private String currentCarrier = null;
private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) {
@Override
@@ -203,6 +208,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
cr.unregisterContentObserver(this.mAutoTimeObserver);
}
+ @Override
protected void finalize() {
if (DBG) log("CdmaServiceStateTracker finalized");
}
@@ -265,10 +271,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
EVENT_GET_LOC_DONE_CDMA, onComplete));
}
-
- //***** Overridden from ServiceStateTracker
- public void
- handleMessage (Message msg) {
+ @Override
+ public void handleMessage (Message msg) {
AsyncResult ar;
int[] ints;
String[] strings;
@@ -434,8 +438,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
//***** Private Instance Methods
- protected void setPowerStateToDesired()
- {
+ @Override
+ protected void setPowerStateToDesired() {
// If we want it on and it's off, turn it on
if (mDesiredPowerState
&& cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
@@ -470,6 +474,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
} // Otherwise, we're in the desired state
}
+ @Override
protected void updateSpnDisplay() {
String spn = "";
boolean showSpn = false;
@@ -511,8 +516,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
* Handle the result of one of the pollState()-related requests
*/
- protected void
- handlePollStateResult (int what, AsyncResult ar) {
+ @Override
+ protected void handlePollStateResult (int what, AsyncResult ar) {
int ints[];
String states[];
@@ -624,11 +629,32 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
if (opNames != null && opNames.length >= 3) {
if (cm.getRadioState().isNVReady()) {
// In CDMA in case on NV the ss.mOperatorAlphaLong is set later with the
- // ERI text, so here is ignored what is coming from the modem
+ // ERI text, so here it is ignored what is coming from the modem
newSS.setOperatorName(null, opNames[1], opNames[2]);
} else {
newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
}
+
+ if (!(opNames[2].equals(currentCarrier))) {
+ // TODO(Moto): jsh asks, "This uses the MCC+MNC of the current registered
+ // network to set the "current" entry in the APN table. But the correct
+ // entry should be the MCC+MNC that matches the subscribed operator
+ // (eg, phone issuer). These can be different when roaming."
+ try {
+ // Set the current field of the telephony provider according to
+ // the CDMA's operator
+ Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
+ ContentValues map = new ContentValues();
+ map.put(Telephony.Carriers.NUMERIC, opNames[2]);
+ cr.insert(uri, map);
+ // save current carrier for the next time check
+ currentCarrier = opNames[2];
+ } catch (SQLException e) {
+ Log.e(LOG_TAG, "Can't store current operator", e);
+ }
+ } else {
+ Log.i(LOG_TAG, "current carrier is not changed");
+ }
} else {
Log.w(LOG_TAG, "error parsing opNames");
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
index 0997456..6c1384c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
@@ -254,7 +254,7 @@ public final class EriManager {
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText0).toString());
break;
-
+
case EriInfo.ROAMING_INDICATOR_OFF:
ret = new EriDisplayInformation(
EriInfo.ROAMING_INDICATOR_OFF,
@@ -284,56 +284,56 @@ public final class EriManager {
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText4).toString());
break;
-
+
case 5:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText5).toString());
break;
-
+
case 6:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText6).toString());
break;
-
+
case 7:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText7).toString());
break;
-
+
case 8:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText8).toString());
break;
-
+
case 9:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText9).toString());
break;
-
+
case 10:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText10).toString());
break;
-
+
case 11:
ret = new EriDisplayInformation(
roamInd,
EriInfo.ROAMING_ICON_MODE_NORMAL,
mContext.getText(com.android.internal.R.string.roamingText11).toString());
break;
-
+
case 12:
ret = new EriDisplayInformation(
roamInd,
@@ -363,7 +363,7 @@ public final class EriManager {
mContext.getText(com.android.internal
.R.string.roamingText0).toString());
break;
-
+
case EriInfo.ROAMING_INDICATOR_OFF:
ret = new EriDisplayInformation(
EriInfo.ROAMING_INDICATOR_OFF,
@@ -371,7 +371,7 @@ public final class EriManager {
mContext.getText(com.android.internal
.R.string.roamingText1).toString());
break;
-
+
case EriInfo.ROAMING_INDICATOR_FLASH:
ret = new EriDisplayInformation(
EriInfo.ROAMING_INDICATOR_FLASH,
@@ -379,7 +379,7 @@ public final class EriManager {
mContext.getText(com.android.internal
.R.string.roamingText2).toString());
break;
-
+
default:
ret = new EriDisplayInformation(-1, -1, "ERI text");
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
index 85fe6dc..23a4ac7 100644
--- a/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
+++ b/telephony/java/com/android/internal/telephony/cdma/FeatureCode.java
@@ -84,7 +84,6 @@ public final class FeatureCode extends Handler implements MmiCode {
CDMAPhone phone;
Context context;
- CdmaConnection suppConn;
String action; // '*' in CDMA
String sc; // Service Code
String poundString; // Entire Flash string
@@ -237,17 +236,9 @@ public final class FeatureCode extends Handler implements MmiCode {
}
/** Process a Flash Code...anything that isn't a dialing number */
- void processCode () {
+ void processCode() {
Log.d(LOG_TAG, "send feature code...");
- if (this.poundString != null) {
- // TODO(Moto): Is suppConn going away?
- suppConn = new CdmaConnection(phone.getContext(), this.poundString, phone.mCT, null);
- phone.mCM.sendCDMAFeatureCode(suppConn.address,
- obtainMessage(EVENT_CDMA_FLASH_COMPLETED));
- } else {
- phone.mCM.sendCDMAFeatureCode(this.poundString,
- obtainMessage(EVENT_CDMA_FLASH_COMPLETED));
- }
+ phone.mCM.sendCDMAFeatureCode(this.poundString, obtainMessage(EVENT_CDMA_FLASH_COMPLETED));
}
/** Called from CDMAPhone.handleMessage; not a Handler subclass */
@@ -268,7 +259,6 @@ public final class FeatureCode extends Handler implements MmiCode {
} else {
state = State.COMPLETE;
message = context.getText(com.android.internal.R.string.fcComplete);
- suppConn.processNextPostDialChar();
}
phone.onFeatureCodeDone(this);
break;
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 7edd30f..c7e61da 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -16,19 +16,17 @@
package com.android.internal.telephony.cdma;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
import android.util.Log;
-import static com.android.internal.telephony.TelephonyProperties.*;
import com.android.internal.telephony.AdnRecord;
import com.android.internal.telephony.AdnRecordCache;
import com.android.internal.telephony.AdnRecordLoader;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.RuimCard;
import com.android.internal.telephony.gsm.MccTable;
@@ -55,8 +53,13 @@ public final class RuimRecords extends IccRecords {
//***** Instance Variables
- String spn;
- int spnDisplayCondition;
+ private String mImsi;
+ private String mMyMobileNumber;
+ private String mSid;
+ private String mNid;
+ private String mMin2Min1;
+
+ private String mPrlVersion;
//***** Event Constants
@@ -122,8 +125,8 @@ public final class RuimRecords extends IccRecords {
adnCache.reset();
- phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
- phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, null);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
// recordsRequested is set to false indicating that the SIM
// read requests made so far are not valid. This is set to
@@ -131,6 +134,25 @@ public final class RuimRecords extends IccRecords {
recordsRequested = false;
}
+ /** Returns null if RUIM is not yet ready */
+ public String getIMSI_M() {
+ // TODO(Moto): mImsi is not initialized, fix.
+ return mImsi;
+ }
+
+ public String getMdnNumber() {
+ return mMyMobileNumber;
+ }
+
+ public String getCdmaMin() {
+ return mMin2Min1;
+ }
+
+ /** Returns null if RUIM is not yet ready */
+ public String getPrlVersion() {
+ return mPrlVersion;
+ }
+
@Override
public void setVoiceMailNumber(String alphaTag, String voiceNumber, Message onComplete){
// In CDMA this is Operator/OEM dependent
@@ -155,6 +177,30 @@ public final class RuimRecords extends IccRecords {
}
}
+ /**
+ * Returns the 5 or 6 digit MCC/MNC of the operator that
+ * provided the RUIM card. Returns null of RUIM is not yet ready
+ */
+ public String getRUIMOperatorNumeric() {
+ if (mImsi == null) {
+ return null;
+ }
+
+ // TODO(Moto): mncLength is not set anywhere.
+ if (mncLength != 0) {
+ // Length = length of MCC + length of MNC
+ // TODO: change spec name
+ // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3)
+ return mImsi.substring(0, 3 + mncLength);
+ }
+
+ // Guess the MNC length based on the MCC if we don't
+ // have a valid value in ef[ad]
+
+ int mcc = Integer.parseInt(mImsi.substring(0,3));
+ return mImsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
+ }
+
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
@@ -181,35 +227,27 @@ public final class RuimRecords extends IccRecords {
/* IO events */
case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
- // TODO(Moto):TODO(Teleca): This event was removed by Teleca/QCT
- // I've left it as it's needed to complete EVENT_OTA_PROVISION_STATUS_CHANGE.
- // But since various instance variables are removed I've commented
- // out code that references them. I'm sure this is wrong so
- // Moto/Teleca/QCT need to come to an agreement. Also see onRuimReady
- // and onVnReady.
-
ar = (AsyncResult)msg.obj;
String localTemp[] = (String[])ar.result;
if (ar.exception != null) {
break;
}
- if(m_ota_commited) {
- //if(mMyMobileNumber != localTemp[0]) {
+ if (m_ota_commited) {
+ if (mMyMobileNumber != localTemp[0]) {
Intent intent = new Intent(TelephonyIntents.ACTION_CDMA_OTA_MDN_CHANGED);
intent.putExtra("mdn", localTemp[0]);
Log.d(LOG_TAG,"Broadcasting intent MDN Change in OTA ");
ActivityManagerNative.broadcastStickyIntent(intent, null);
- //}
- m_ota_commited=false;
+ }
+ m_ota_commited = false;
}
- //mMyMobileNumber = localTemp[0];
- //mSid = localTemp[1];
- //mNid = localTemp[2];
- //if (localTemp.length >= 3) { // TODO(Moto): remove when new ril always returns min2_min1
- // mMin2Min1 = localTemp[3];
- //}
+ mMyMobileNumber = localTemp[0];
+ mSid = localTemp[1];
+ mNid = localTemp[2];
+ mMin2Min1 = localTemp[3];
+ mPrlVersion = localTemp[4];
- //Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
+ Log.d(LOG_TAG, "MDN: " + mMyMobileNumber + " MIN: " + mMin2Min1);
break;
@@ -262,9 +300,11 @@ public final class RuimRecords extends IccRecords {
if (ar.exception == null) {
int[] ints = (int[]) ar.result;
int otaStatus = ints[0];
- if (otaStatus== phone.CDMA_OTA_PROVISION_STATUS_COMMITTED) {
+ if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_COMMITTED) {
m_ota_commited=true;
phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+ } else if (otaStatus == phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) {
+ phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
}
}
break;
@@ -315,14 +355,14 @@ public final class RuimRecords extends IccRecords {
RuimCard.INTENT_VALUE_ICC_READY, null);
fetchRuimRecords();
-
- // TODO(Moto): TODO(Teleca): Work out how to do CDMA subscription
- // phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+
+ phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+
}
private void onNvReady() {
- // TODO(Moto): TODO(Teleca): Work out how to do CDMA subscription
- // phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+ phone.mCM.getCDMASubscription(obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_DONE));
+
}
private void fetchRuimRecords() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
index 444dec3..925a755 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
@@ -74,13 +74,18 @@ public class SignalToneUtil {
static private HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
private static Integer signalParamHash(int signalType, int alertPitch, int signal) {
- // TODO(Moto): The input should get checked before usage
+ if ((signalType < 0) || (signalType > 256) || (alertPitch > 256) ||
+ (alertPitch < 0) || (signal > 256) || (signal < 0)) {
+ return new Integer(ToneGenerator.TONE_CDMA_INVALID);
+ }
return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal);
}
public static int getAudioToneFromSignalInfo(int signalType, int alertPitch, int signal) {
- int result = ToneGenerator.TONE_CDMA_INVALID;
- result = hm.get(signalParamHash(signalType, alertPitch, signal));
+ Integer result = hm.get(signalParamHash(signalType, alertPitch, signal));
+ if (result == null) {
+ return ToneGenerator.TONE_CDMA_INVALID;
+ }
return result;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 9152559..bbdd0dd 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -357,6 +357,17 @@ public class SmsMessage extends SmsMessageBase {
}
/**
+ * Calculate the number of septets needed to encode the message.
+ *
+ * @param messageBody the message to encode
+ * @param force ignore (but still count) illegal characters if true
+ * @return septet count, or -1 on failure
+ */
+ public static int calc7bitEncodedLength(CharSequence msgBody, boolean force) {
+ return BearerData.calc7bitEncodedLength(msgBody.toString(), force);
+ }
+
+ /**
* Note: This function is a GSM specific functionality which is not supported in CDMA mode.
*/
public int getProtocolIdentifier() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/package.html b/telephony/java/com/android/internal/telephony/cdma/package.html
index cf1ad4a..4eb1f9c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/package.html
+++ b/telephony/java/com/android/internal/telephony/cdma/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides classes to control or read data from CDMA phones.
+Provides classes to control or read data from CDMA phones.
@hide
</BODY>
</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index ab65b0a..3c45aa4 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -385,7 +385,17 @@ public final class BearerData{
outStream.skip(3);
}
- private static byte[] encode7bitAscii(String msg)
+ private static class SeptetData {
+ byte data[];
+ int septetCount;
+
+ SeptetData(byte[] data, int septetCount) {
+ this.data = data;
+ this.septetCount = septetCount;
+ }
+ }
+
+ private static SeptetData encode7bitAscii(String msg, boolean force)
throws CodingException
{
try {
@@ -396,23 +406,43 @@ public final class BearerData{
// Test ourselves for ASCII membership, since Java seems not to care.
if ((charCode < UserData.PRINTABLE_ASCII_MIN_INDEX) ||
(charCode > UserData.PRINTABLE_ASCII_MAX_INDEX)) {
- throw new CodingException("illegal ASCII code (" + charCode + ")");
+ if (force) {
+ outStream.write(7, UserData.UNENCODABLE_7_BIT_CHAR);
+ } else {
+ throw new CodingException("illegal ASCII code (" + charCode + ")");
+ }
+ } else {
+ outStream.write(7, expandedData[i]);
}
- outStream.write(7, expandedData[i]);
}
- return outStream.toByteArray();
- } catch (java.io.UnsupportedEncodingException ex) {
+ return new SeptetData(outStream.toByteArray(), expandedData.length);
+ } catch (java.io.UnsupportedEncodingException ex) {
throw new CodingException("7bit ASCII encode failed: " + ex);
- } catch (BitwiseOutputStream.AccessException ex) {
+ } catch (BitwiseOutputStream.AccessException ex) {
throw new CodingException("7bit ASCII encode failed: " + ex);
}
}
+ /**
+ * Calculate the number of septets needed to encode the message.
+ *
+ * @param force ignore (but still count) illegal characters if true
+ * @return septet count, or -1 on failure
+ */
+ public static int calc7bitEncodedLength(String msg, boolean force) {
+ try {
+ SeptetData data = encode7bitAscii(msg, force);
+ return data.septetCount;
+ } catch (CodingException ex) {
+ return -1;
+ }
+ }
+
private static byte[] encodeUtf16(String msg)
throws CodingException
{
try {
- return msg.getBytes("utf-16be"); // XXX(do not submit) -- make sure decode matches
+ return msg.getBytes("utf-16be");
} catch (java.io.UnsupportedEncodingException ex) {
throw new CodingException("UTF-16 encode failed: " + ex);
}
@@ -462,7 +492,8 @@ public final class BearerData{
if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
payloadData = encode7bitGsm(uData.payloadStr);
} else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
- payloadData = encode7bitAscii(uData.payloadStr);
+ SeptetData septetData = encode7bitAscii(uData.payloadStr, true);
+ payloadData = septetData.data;
} else if (uData.msgEncoding == UserData.ENCODING_UNICODE_16) {
payloadData = encodeUtf16(uData.payloadStr);
} else {
@@ -478,7 +509,8 @@ public final class BearerData{
uData.payloadStr = "";
}
try {
- payloadData = encode7bitAscii(uData.payloadStr);
+ SeptetData septetData = encode7bitAscii(uData.payloadStr, false);
+ payloadData = septetData.data;
uData.msgEncoding = UserData.ENCODING_7BIT_ASCII;
} catch (CodingException ex) {
payloadData = encodeUtf16(uData.payloadStr);
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
index 7c37bc2..8d4e769 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
@@ -50,6 +50,14 @@ public class UserData {
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'};
/**
+ * Character to use when forced to encode otherwise unencodable
+ * characters, meaning those not in the respective ASCII or GSM
+ * 7-bit encoding tables. Current choice is SPACE, which is 0x20
+ * in both the GSM-7bit and ASCII-7bit encodings.
+ */
+ static final byte UNENCODABLE_7_BIT_CHAR = 0x20;
+
+ /**
* Only elements between these indices in the ASCII table are printable.
*/
public static final int PRINTABLE_ASCII_MIN_INDEX = 0x20;
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/package.html b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
index 48e1034..b2bc736 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/package.html
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides CDMA-specific features for text/data/PDU SMS messages
+Provides CDMA-specific features for text/data/PDU SMS messages
@hide
</BODY>
</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 2b2f077..d93ca1d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -83,7 +83,7 @@ public class GsmConnection extends Connection {
static final int EVENT_PAUSE_DONE = 2;
static final int EVENT_NEXT_POST_DIAL = 3;
static final int EVENT_WAKE_LOCK_TIMEOUT = 4;
-
+
//***** Constants
static final int PAUSE_DELAY_FIRST_MILLIS = 100;
static final int PAUSE_DELAY_MILLIS = 3 * 1000;
@@ -117,7 +117,7 @@ public class GsmConnection extends Connection {
GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index) {
createWakeLock(context);
acquireWakeLock();
-
+
owner = ct;
h = new MyHandler(owner.getLooper());
@@ -138,7 +138,7 @@ public class GsmConnection extends Connection {
GsmConnection (Context context, String dialString, GsmCallTracker ct, GsmCall parent) {
createWakeLock(context);
acquireWakeLock();
-
+
owner = ct;
h = new MyHandler(owner.getLooper());
@@ -375,7 +375,7 @@ public class GsmConnection extends Connection {
return DisconnectCause.ICC_ERROR;
} else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
if (phone.mSST.rs.isCsRestricted()) {
- return DisconnectCause.CS_RESTRICTED;
+ return DisconnectCause.CS_RESTRICTED;
} else if (phone.mSST.rs.isCsEmergencyRestricted()) {
return DisconnectCause.CS_RESTRICTED_EMERGENCY;
} else if (phone.mSST.rs.isCsNormalRestricted()) {
@@ -575,7 +575,7 @@ public class GsmConnection extends Connection {
return postDialString.substring(nextPostDialChar);
}
-
+
@Override
protected void finalize()
{
@@ -609,7 +609,7 @@ public class GsmConnection extends Connection {
c = 0;
} else {
boolean isValid;
-
+
setPostDialState(PostDialState.STARTED);
c = postDialString.charAt(nextPostDialChar++);
@@ -680,31 +680,31 @@ public class GsmConnection extends Connection {
}
/**
- * Set post dial state and acquire wake lock while switching to "started"
- * state, the wake lock will be released if state switches out of "started"
- * state or after WAKE_LOCK_TIMEOUT_MILLIS.
+ * Set post dial state and acquire wake lock while switching to "started"
+ * state, the wake lock will be released if state switches out of "started"
+ * state or after WAKE_LOCK_TIMEOUT_MILLIS.
* @param s new PostDialState
*/
private void setPostDialState(PostDialState s) {
- if (postDialState != PostDialState.STARTED
+ if (postDialState != PostDialState.STARTED
&& s == PostDialState.STARTED) {
acquireWakeLock();
Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT);
h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS);
- } else if (postDialState == PostDialState.STARTED
+ } else if (postDialState == PostDialState.STARTED
&& s != PostDialState.STARTED) {
h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
releaseWakeLock();
}
postDialState = s;
}
-
+
private void
createWakeLock(Context context) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
}
-
+
private void
acquireWakeLock() {
log("acquireWakeLock");
@@ -720,7 +720,7 @@ public class GsmConnection extends Connection {
}
}
}
-
+
private void log(String msg) {
Log.d(LOG_TAG, "[GSMConn] " + msg);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 3f43502..035c690 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -487,7 +487,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
(isApnTypeActive(Phone.APN_TYPE_SUPL) && isEnabled(Phone.APN_TYPE_SUPL))) {
return false;
}
- cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = Phone.REASON_DATA_DISABLED;
+ sendMessage(msg);
return true;
} else {
// isEnabled && enable
@@ -585,7 +588,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
waitingApns = buildWaitingApns();
if (waitingApns.isEmpty()) {
if (DBG) log("No APN found");
- notifyNoData(PdpConnection.FailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
return false;
} else {
log ("Create from allApns : " + apnListToString(allApns));
@@ -633,6 +636,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
mReconnectIntent = null;
}
+ setState(State.DISCONNECTING);
+
for (DataConnection conn : pdpList) {
PdpConnection pdp = (PdpConnection) conn;
if (tearDown) {
@@ -644,25 +649,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
stopNetStatPoll();
- /*
- * If we've been asked to tear down the connection,
- * set the state to DISCONNECTING. However, there's
- * a race that can occur if for some reason we were
- * already in the IDLE state. In that case, the call
- * to pdp.disconnect() above will immediately post
- * a message to the handler thread that the disconnect
- * is done, and if the handler runs before the code
- * below does, the handler will have set the state to
- * IDLE before the code below runs. If we didn't check
- * for that, future calls to trySetupData would fail,
- * and we would never get out of the DISCONNECTING state.
- */
if (!tearDown) {
setState(State.IDLE);
phone.notifyDataConnection(reason);
mActiveApn = null;
- } else if (state != State.IDLE) {
- setState(State.DISCONNECTING);
}
}
@@ -810,6 +800,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (state != State.DISCONNECTING) {
cleanUpConnection(isConnected, Phone.REASON_APN_CHANGED);
if (!isConnected) {
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
trySetupData(Phone.REASON_APN_CHANGED);
}
}
@@ -1323,13 +1315,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
cause = (PdpConnection.FailCause) (ar.result);
if(DBG) log("PDP setup failed " + cause);
// Log this failure to the Event Logs.
- if (cause == PdpConnection.FailCause.BAD_APN ||
- cause == PdpConnection.FailCause.BAD_PAP_SECRET ||
- cause == PdpConnection.FailCause.BARRED ||
- cause == PdpConnection.FailCause.RADIO_ERROR_RETRY ||
- cause == PdpConnection.FailCause.SUSPENED_TEMPORARY ||
- cause == PdpConnection.FailCause.UNKNOWN ||
- cause == PdpConnection.FailCause.USER_AUTHENTICATION) {
+ if (cause.isEventLoggable()) {
int cid = -1;
GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
if (loc != null) cid = loc.getCid();
@@ -1343,23 +1329,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
+ return;
}
- if (tryNextApn(cause)) {
- waitingApns.remove(0);
- if (waitingApns.isEmpty()) {
- // No more to try, start delayed retry
- startDelayedRetry(cause, reason);
- } else {
- // we still have more apns to try
- setState(State.SCANNING);
- // Wait a bit before trying the next APN, so that
- // we're not tying up the RIL command channel
- sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
- RECONNECT_DELAY_INITIAL_MILLIS);
- }
- } else {
+ waitingApns.remove(0);
+ if (waitingApns.isEmpty()) {
+ // No more to try, start delayed retry
startDelayedRetry(cause, reason);
+ } else {
+ // we still have more apns to try
+ setState(State.SCANNING);
+ // Wait a bit before trying the next APN, so that
+ // we're not tying up the RIL command channel
+ sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
+ RECONNECT_DELAY_INITIAL_MILLIS);
}
}
}
@@ -1403,6 +1386,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
resetPollStats();
}
} else {
+ // reset reconnect timer
+ nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
// in case data setup was attempted when we were on a voice call
trySetupData(Phone.REASON_VOICE_CALL_ENDED);
}
@@ -1412,14 +1397,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
cleanUpConnection(tearDown, reason);
}
- private boolean tryNextApn(FailCause cause) {
- return (cause != FailCause.RADIO_NOT_AVAILABLE)
- && (cause != FailCause.RADIO_OFF)
- && (cause != FailCause.RADIO_ERROR_RETRY)
- && (cause != FailCause.NO_SIGNAL)
- && (cause != FailCause.SIM_LOCKED);
- }
-
private int getRestoreDefaultApnDelay() {
String restoreApnDelayStr = SystemProperties.get(APN_RESTORE_DELAY_PROP_NAME);
@@ -1466,7 +1443,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (allApns.isEmpty()) {
if (DBG) log("No APN found for carrier: " + operator);
preferredApn = null;
- notifyNoData(PdpConnection.FailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
} else {
preferredApn = getPreferredApn();
Log.d(LOG_TAG, "Get PreferredAPN");
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 4db8fc6..18e6375 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -621,7 +621,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
if (isInterrogate()) {
phone.mCM.queryFacilityLock(facility, password,
serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this));
- } else if (isActivate() || isDeactivate()) {
+ } else if (isActivate() || isDeactivate()) {
phone.mCM.setFacilityLock(facility, isActivate(), password,
serviceClass, obtainMessage(EVENT_SET_COMPLETE, this));
} else {
@@ -1186,9 +1186,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
sb.append(createQueryCallWaitingResultMessage(ints[1]));
} else if (isServiceCodeCallBarring(sc)) {
// ints[0] for Call Barring is a bit vector of services
- sb.append(createQueryCallBarringResultMessage(ints[0]));
+ sb.append(createQueryCallBarringResultMessage(ints[0]));
} else if (ints[0] == 1) {
- // for all other services, treat it as a boolean
+ // for all other services, treat it as a boolean
sb.append(context.getText(com.android.internal.R.string.serviceEnabled));
} else {
sb.append(context.getText(com.android.internal.R.string.mmiError));
@@ -1224,9 +1224,9 @@ public final class GsmMmiCode extends Handler implements MmiCode {
{
StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor));
- for (int classMask = 1
+ for (int classMask = 1
; classMask <= SERVICE_CLASS_MAX
- ; classMask <<= 1
+ ; classMask <<= 1
) {
if ((classMask & serviceClass) != 0) {
sb.append("\n");
@@ -1235,7 +1235,7 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
return sb;
}
-
+
/***
* TODO: It would be nice to have a method here that can take in a dialstring and
* figure out if there is an MMI code embedded within it. This code would replace
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 8bf5d19..f87392a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -183,7 +183,7 @@ final class GsmSMSDispatcher extends SMSDispatcher {
* Send a multi-part text based SMS which already passed SMS control check.
*
* It is the working function for sendMultipartText().
- *
+ *
* @param destinationAddress the address to send the message to
* @param scAddress is the service center address or null to use
* the current default SMSC
@@ -269,24 +269,24 @@ final class GsmSMSDispatcher extends SMSDispatcher {
/**
* Send the multi-part SMS based on multipart Sms tracker
- *
+ *
* @param tracker holds the multipart Sms tracker ready to be sent
*/
protected void sendMultipartSms (SmsTracker tracker) {
ArrayList<String> parts;
ArrayList<PendingIntent> sentIntents;
ArrayList<PendingIntent> deliveryIntents;
-
+
HashMap map = tracker.mData;
-
+
String destinationAddress = (String) map.get("destination");
String scAddress = (String) map.get("scaddress");
-
+
parts = (ArrayList<String>) map.get("parts");
sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents");
deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents");
-
- sendMultipartTextWithPermit(destinationAddress,
+
+ sendMultipartTextWithPermit(destinationAddress,
scAddress, parts, sentIntents, deliveryIntents);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
index 3f794a8..278beef 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
@@ -35,15 +35,24 @@ public class PdpConnection extends DataConnection {
private static final String LOG_TAG = "GSM";
private static final boolean DBG = true;
- private static final boolean FAKE_FAIL = false;
/** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */
- private static final int PDP_FAIL_RIL_BARRED = 8;
- private static final int PDP_FAIL_RIL_BAD_APN = 27;
- private static final int PDP_FAIL_RIL_USER_AUTHENTICATION = 29;
- private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED = 32;
- private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED = 33;
- private static final int PDP_FAIL_RIL_ERROR_UNSPECIFIED = 0xffff;
+ private static final int PDP_FAIL_OPERATOR_BARRED = 0x08;
+ private static final int PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
+ private static final int PDP_FAIL_MISSING_UKNOWN_APN = 0x1B;
+ private static final int PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
+ private static final int PDP_FAIL_USER_AUTHENTICATION = 0x1D;
+ private static final int PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
+ private static final int PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
+ private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
+ private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
+ private static final int PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
+ private static final int PDP_FAIL_NSAPI_IN_USE = 0x23;
+ private static final int PDP_FAIL_PROTOCOL_ERRORS = 0x6F;
+ private static final int PDP_FAIL_ERROR_UNSPECIFIED = 0xffff;
+
+ private static final int PDP_FAIL_REGISTRATION_FAIL = -1;
+ private static final int PDP_FAIL_GPRS_REGISTRATION_FAIL = -2;
//***** Instance Variables
private String pdp_name;
@@ -83,14 +92,6 @@ public class PdpConnection extends DataConnection {
lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
- if (FAKE_FAIL) {
- // for debug before baseband implement error in setup PDP
- if (apn.apn.equalsIgnoreCase("badapn")){
- notifyFail(FailCause.BAD_APN, onConnectCompleted);
- return;
- }
- }
-
phone.mCM.setupDataCall(Integer.toString(RILConstants.GSM_PHONE), null, apn.apn, apn.user,
apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
@@ -190,21 +191,51 @@ public class PdpConnection extends DataConnection {
FailCause cause;
switch (rilCause) {
- case PDP_FAIL_RIL_BARRED:
- cause = FailCause.BARRED;
+ case PDP_FAIL_OPERATOR_BARRED:
+ cause = FailCause.OPERATOR_BARRED;
+ break;
+ case PDP_FAIL_INSUFFICIENT_RESOURCES:
+ cause = FailCause.INSUFFICIENT_RESOURCES;
break;
- case PDP_FAIL_RIL_BAD_APN:
- cause = FailCause.BAD_APN;
+ case PDP_FAIL_MISSING_UKNOWN_APN:
+ cause = FailCause.MISSING_UKNOWN_APN;
break;
- case PDP_FAIL_RIL_USER_AUTHENTICATION:
+ case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
+ cause = FailCause.UNKNOWN_PDP_ADDRESS;
+ break;
+ case PDP_FAIL_USER_AUTHENTICATION:
cause = FailCause.USER_AUTHENTICATION;
break;
- case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED:
+ case PDP_FAIL_ACTIVATION_REJECT_GGSN:
+ cause = FailCause.ACTIVATION_REJECT_GGSN;
+ break;
+ case PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
+ cause = FailCause.ACTIVATION_REJECT_UNSPECIFIED;
+ break;
+ case PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
+ cause = FailCause.SERVICE_OPTION_OUT_OF_ORDER;
+ break;
+ case PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
break;
- case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED:
+ case PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
break;
+ case PDP_FAIL_NSAPI_IN_USE:
+ cause = FailCause.NSAPI_IN_USE;
+ break;
+ case PDP_FAIL_PROTOCOL_ERRORS:
+ cause = FailCause.PROTOCOL_ERRORS;
+ break;
+ case PDP_FAIL_ERROR_UNSPECIFIED:
+ cause = FailCause.UNKNOWN;
+ break;
+ case PDP_FAIL_REGISTRATION_FAIL:
+ cause = FailCause.REGISTRATION_FAIL;
+ break;
+ case PDP_FAIL_GPRS_REGISTRATION_FAIL:
+ cause = FailCause.GPRS_REGISTRATION_FAIL;
+ break;
default:
cause = FailCause.UNKNOWN;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java b/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
index d17f134..3f7d5d7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
+++ b/telephony/java/com/android/internal/telephony/gsm/RestrictedState.java
@@ -19,7 +19,7 @@ package com.android.internal.telephony.gsm;
import android.telephony.ServiceState;
public class RestrictedState {
-
+
/**
* Set true to block packet data access due to restriction
*/
@@ -32,7 +32,7 @@ public class RestrictedState {
* Set true to block emergency call due to restriction
*/
private boolean mCsEmergencyRestricted;
-
+
public RestrictedState() {
setPsRestricted(false);
setCsNormalRestricted(false);
@@ -80,11 +80,11 @@ public class RestrictedState {
public boolean isPsRestricted() {
return mPsRestricted;
}
-
+
public boolean isCsRestricted() {
return mCsNormalRestricted && mCsEmergencyRestricted;
}
-
+
@Override
public boolean equals (Object o) {
RestrictedState s;
@@ -107,7 +107,7 @@ public class RestrictedState {
@Override
public String toString() {
String csString = "none";
-
+
if (mCsEmergencyRestricted && mCsNormalRestricted) {
csString = "all";
} else if (mCsEmergencyRestricted && !mCsNormalRestricted) {
@@ -115,7 +115,7 @@ public class RestrictedState {
} else if (!mCsEmergencyRestricted && mCsNormalRestricted) {
csString = "normal call";
}
-
+
return "Restricted State CS: " + csString + " PS:" + mPsRestricted;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index fb45c7c..65d3362 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -69,7 +69,7 @@ public final class SIMRecords extends IccRecords {
SpnOverride mSpnOverride;
-
+
//***** Cached SIM State; cleared on channel close
String imsi;
@@ -206,7 +206,7 @@ public final class SIMRecords extends IccRecords {
// -1 means no EF_SPN found; treat accordingly.
spnDisplayCondition = -1;
efMWIS = null;
- efCPHS_MWI = null;
+ efCPHS_MWI = null;
spdiNetworks = null;
pnnHomeName = null;
@@ -485,7 +485,7 @@ public final class SIMRecords extends IccRecords {
return imsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
}
-
+
/**
* If the timezone is not already set, set it based on the MCC of the SIM.
* @param mcc Mobile Country Code of the SIM
@@ -494,7 +494,7 @@ public final class SIMRecords extends IccRecords {
String timezone = SystemProperties.get(TIMEZONE_PROPERTY);
if (timezone == null || timezone.length() == 0) {
String zoneId = MccTable.defaultTimeZoneForMcc(mcc);
-
+
if (zoneId != null && zoneId.length() > 0) {
// Set time zone based on MCC
AlarmManager alarm =
@@ -1037,7 +1037,7 @@ public final class SIMRecords extends IccRecords {
IccUtils.bytesToHexString(data));
mEfCfis = data;
-
+
// Refer TS 51.011 Section 10.3.46 for the content description
callForwardingEnabled = ((data[1] & 0x01) != 0);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
new file mode 100644
index 0000000..45f50bc
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsBroadcastConfigInfo.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.gsm;
+
+/**
+ * SmsBroadcastConfigInfo defines one configuration of Cell Broadcast
+ * Message (CBM) to be received by the ME
+ *
+ * fromServiceId - toServiceId defines a range of CBM message identifiers
+ * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS
+ * and 9.4.4.2.2 for UMTS. All other values can be treated as empty
+ * CBM message ID.
+ *
+ * fromCodeScheme - toCodeScheme defines a range of CBM data coding schemes
+ * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS
+ * and 9.4.4.2.3 for UMTS.
+ * All other values can be treated as empty CBM data coding scheme.
+ *
+ * selected false means message types specified in <fromServiceId, toServiceId>
+ * and <fromCodeScheme, toCodeScheme>are not accepted, while true means accepted.
+ *
+ */
+public class SmsBroadcastConfigInfo {
+ private int fromServiceId;
+ private int toServiceId;
+ private int fromCodeScheme;
+ private int toCodeScheme;
+ private boolean selected;
+
+ /**
+ * Initialize the object from rssi and cid.
+ */
+ public SmsBroadcastConfigInfo(int fromId, int toId, int fromScheme,
+ int toScheme, boolean selected) {
+ setFromServiceId(fromId);
+ setToServiceId(toId);
+ setFromCodeScheme(fromScheme);
+ setToCodeScheme(toScheme);
+ this.setSelected(selected);
+ }
+
+ /**
+ * @param fromServiceId the fromServiceId to set
+ */
+ public void setFromServiceId(int fromServiceId) {
+ this.fromServiceId = fromServiceId;
+ }
+
+ /**
+ * @return the fromServiceId
+ */
+ public int getFromServiceId() {
+ return fromServiceId;
+ }
+
+ /**
+ * @param toServiceId the toServiceId to set
+ */
+ public void setToServiceId(int toServiceId) {
+ this.toServiceId = toServiceId;
+ }
+
+ /**
+ * @return the toServiceId
+ */
+ public int getToServiceId() {
+ return toServiceId;
+ }
+
+ /**
+ * @param fromCodeScheme the fromCodeScheme to set
+ */
+ public void setFromCodeScheme(int fromCodeScheme) {
+ this.fromCodeScheme = fromCodeScheme;
+ }
+
+ /**
+ * @return the fromCodeScheme
+ */
+ public int getFromCodeScheme() {
+ return fromCodeScheme;
+ }
+
+ /**
+ * @param toCodeScheme the toCodeScheme to set
+ */
+ public void setToCodeScheme(int toCodeScheme) {
+ this.toCodeScheme = toCodeScheme;
+ }
+
+ /**
+ * @return the toCodeScheme
+ */
+ public int getToCodeScheme() {
+ return toCodeScheme;
+ }
+
+ /**
+ * @param selected the selected to set
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * @return the selected
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ @Override
+ public String toString() {
+ return "SmsBroadcastConfigInfo: Id [" +
+ getFromServiceId() + "," + getToServiceId() + "] Code [" +
+ getFromCodeScheme() + "," + getToCodeScheme() + "] " +
+ (isSelected() ? "ENABLED" : "DISABLED");
+ }
+} \ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 6435be5..a15bbdf 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -739,6 +739,22 @@ public class SmsMessage extends SmsMessageBase{
}
}
+ /**
+ * Calculate the number of septets needed to encode the message.
+ *
+ * @param messageBody the message to encode
+ * @param force ignore (but still count) illegal characters if true
+ * @return septet count, or -1 on failure
+ */
+ public static int calc7bitEncodedLength(CharSequence messageBody, boolean force) {
+ try {
+ return GsmAlphabet.countGsmSeptets(messageBody, !force);
+ } catch (EncodeException ex) {
+ /* Just fall through to the -1 error result below. */
+ }
+ return -1;
+ }
+
/** {@inheritDoc} */
public int getProtocolIdentifier() {
return protocolIdentifier;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
index 11ad52d..e68655e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
@@ -34,7 +34,7 @@ public class SuppServiceNotification {
public int type;
/** TS 27.007 7.17 "number" (MT only) */
public String number;
-
+
static public final int MO_CODE_UNCONDITIONAL_CF_ACTIVE = 0;
static public final int MO_CODE_SOME_CF_ACTIVE = 1;
static public final int MO_CODE_CALL_FORWARDED = 2;
@@ -44,7 +44,7 @@ public class SuppServiceNotification {
static public final int MO_CODE_INCOMING_CALLS_BARRED = 6;
static public final int MO_CODE_CLIR_SUPPRESSION_REJECTED = 7;
static public final int MO_CODE_CALL_DEFLECTED = 8;
-
+
static public final int MT_CODE_FORWARDED_CALL = 0;
static public final int MT_CODE_CUG_CALL = 1;
static public final int MT_CODE_CALL_ON_HOLD = 2;
diff --git a/telephony/java/com/android/internal/telephony/gsm/package.html b/telephony/java/com/android/internal/telephony/gsm/package.html
index 4b1cf99..fed8399 100755
--- a/telephony/java/com/android/internal/telephony/gsm/package.html
+++ b/telephony/java/com/android/internal/telephony/gsm/package.html
@@ -1,6 +1,6 @@
<HTML>
<BODY>
-Provides classes to control or read data from GSM phones.
+Provides classes to control or read data from GSM phones.
@hide
</BODY>
</HTML>
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
index c002729..58f1f97 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
@@ -24,15 +24,15 @@ package com.android.internal.telephony.gsm.stk;
public interface AppInterface {
/*
- * Intent's actions which are broadcasted by the Telephony once a new STK
+ * Intent's actions which are broadcasted by the Telephony once a new STK
* proactive command, session end arrive.
*/
- public static final String STK_CMD_ACTION =
+ public static final String STK_CMD_ACTION =
"android.intent.action.stk.command";
- public static final String STK_SESSION_END_ACTION =
+ public static final String STK_SESSION_END_ACTION =
"android.intent.action.stk.session_end";
-
- /*
+
+ /*
* Callback function from app to telephony to pass a result code and user's
* input back to the SIM.
*/
@@ -44,20 +44,20 @@ public interface AppInterface {
* implementation should support those.
*/
public static enum CommandType {
- DISPLAY_TEXT(0x21),
- GET_INKEY(0x22),
- GET_INPUT(0x23),
- LAUNCH_BROWSER(0x15),
- PLAY_TONE(0x20),
- REFRESH(0x01),
- SELECT_ITEM(0x24),
- SEND_SS(0x11),
- SEND_USSD(0x12),
- SEND_SMS(0x13),
- SEND_DTMF(0x14),
- SET_UP_EVENT_LIST(0x05),
- SET_UP_IDLE_MODE_TEXT(0x28),
- SET_UP_MENU(0x25),
+ DISPLAY_TEXT(0x21),
+ GET_INKEY(0x22),
+ GET_INPUT(0x23),
+ LAUNCH_BROWSER(0x15),
+ PLAY_TONE(0x20),
+ REFRESH(0x01),
+ SELECT_ITEM(0x24),
+ SEND_SS(0x11),
+ SEND_USSD(0x12),
+ SEND_SMS(0x13),
+ SEND_DTMF(0x14),
+ SET_UP_EVENT_LIST(0x05),
+ SET_UP_IDLE_MODE_TEXT(0x28),
+ SET_UP_MENU(0x25),
SET_UP_CALL(0x10);
private int mValue;
@@ -72,7 +72,7 @@ public interface AppInterface {
/**
* Create a CommandType object.
- *
+ *
* @param value Integer value to be converted to a CommandType object.
* @return CommandType object whose "Type of Command" value is {@code
* value}. If no CommandType object has that value, null is
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
index 168361a..e81ff98 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
@@ -36,17 +36,17 @@ class CommandDetails extends ValueObject implements Parcelable {
public ComprehensionTlvTag getTag() {
return ComprehensionTlvTag.COMMAND_DETAILS;
}
-
+
CommandDetails() {
}
public boolean compareTo(CommandDetails other) {
return (this.compRequired == other.compRequired &&
this.commandNumber == other.commandNumber &&
- this.commandQualifier == other.commandQualifier &&
+ this.commandQualifier == other.commandQualifier &&
this.typeOfCommand == other.typeOfCommand);
}
-
+
public CommandDetails(Parcel in) {
compRequired = true;
commandNumber = in.readInt();
@@ -60,7 +60,7 @@ class CommandDetails extends ValueObject implements Parcelable {
dest.writeInt(commandQualifier);
}
- public static final Parcelable.Creator<CommandDetails> CREATOR =
+ public static final Parcelable.Creator<CommandDetails> CREATOR =
new Parcelable.Creator<CommandDetails>() {
public CommandDetails createFromParcel(Parcel in) {
return new CommandDetails(in);
@@ -85,7 +85,7 @@ class DeviceIdentities extends ValueObject {
}
}
-// Container class to hold icon identifier value.
+// Container class to hold icon identifier value.
class IconId extends ValueObject {
int recordNumber;
boolean selfExplanatory;
@@ -95,7 +95,7 @@ class IconId extends ValueObject {
}
}
-// Container class to hold item icon identifier list value.
+// Container class to hold item icon identifier list value.
class ItemsIconId extends ValueObject {
int [] recordNumbers;
boolean selfExplanatory;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
index a27c582..3da652f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
@@ -158,7 +158,7 @@ class GetInputParams extends CommandParams {
this.input = input;
}
- boolean setIcon(Bitmap icon) {
+ boolean setIcon(Bitmap icon) {
if (icon != null && input != null) {
input.icon = icon;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
index 06b36a4..bfde616 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
@@ -635,7 +635,7 @@ class CommandParamsFactory extends Handler {
/**
* Processes SET_UP_EVENT_LIST proactive command from the SIM card.
- *
+ *
* @param cmdDet Command Details object retrieved.
* @param ctlvs List of ComprehensionTlv objects following Command Details
* object and Device Identities object within the proactive command
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
index 4f746ac..ffde6a3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
@@ -33,7 +33,7 @@ class ComprehensionTlv {
private int mLength;
private int mValueIndex;
private byte[] mRawValue;
-
+
/**
* Constructor. Private on purpose. Use
* {@link #decodeMany(byte[], int) decodeMany} or
@@ -165,9 +165,9 @@ class ComprehensionTlv {
} else {
throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
}
-
+
return new ComprehensionTlv(tag, cr, length, data, curIndex);
-
+
} catch (IndexOutOfBoundsException e) {
throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
index 1f0d971..19f724b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
@@ -21,13 +21,13 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Container class for STK GET INPUT, GET IN KEY commands parameters.
+ * Container class for STK GET INPUT, GET IN KEY commands parameters.
*
*/
public class Input implements Parcelable {
public String text;
public String defaultText;
- public Bitmap icon;
+ public Bitmap icon;
public int minLen;
public int maxLen;
public boolean ucs2;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
index 40a6b37..331f69d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
@@ -24,7 +24,7 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
+ * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
*
*/
public class Menu implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
index 810afd2..afd1bba 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2006-2007 Google Inc.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -56,7 +56,7 @@ class GetInkeyInputResponseData extends ResponseData {
private boolean mIsYesNo;
private boolean mYesNoResponse;
public String mInData;
-
+
// GetInKey Yes/No response characters constants.
protected static final byte GET_INKEY_YES = 0x01;
protected static final byte GET_INKEY_NO = 0x00;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
index 62a778e..5425a43 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
@@ -20,9 +20,9 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Class used to pass STK messages from telephony to application. Application
+ * Class used to pass STK messages from telephony to application. Application
* should call getXXX() to get commands's specific values.
- *
+ *
*/
public class StkCmdMessage implements Parcelable {
// members
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
index f6e5685..bd6bc8f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
@@ -30,7 +30,7 @@ public abstract class StkLog {
Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": "
+ msg);
}
-
+
public static void d(String caller, String msg) {
if (!DEBUG) {
return;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
index 8f0addc..9268037 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
@@ -25,8 +25,6 @@ import android.os.Message;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.EncodeException;
-import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.gsm.SimCard;
import com.android.internal.telephony.gsm.SIMFileHandler;
import com.android.internal.telephony.gsm.SIMRecords;
@@ -34,8 +32,6 @@ import com.android.internal.telephony.gsm.SIMRecords;
import android.util.Config;
import java.io.ByteArrayOutputStream;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
/**
* Enumeration for representing the tag value of COMPREHENSION-TLV objects. If
@@ -119,7 +115,7 @@ public class StkService extends Handler implements AppInterface {
// Class members
private static SIMRecords mSimRecords;
-
+
// Service members.
private static StkService sInstance;
private CommandsInterface mCmdIf;
@@ -174,6 +170,9 @@ public class StkService extends Handler implements AppInterface {
// Register for SIM ready event.
mSimRecords.registerForRecordsLoaded(this, MSG_ID_SIM_LOADED, null);
+
+ mCmdIf.reportStkServiceIsRunning(null);
+ StkLog.d(this, "StkService: is running");
}
public void dispose() {
@@ -557,15 +556,15 @@ public class StkService extends Handler implements AppInterface {
}
private void handleCmdResponse(StkResponseMessage resMsg) {
- // Make sure the response details match the last valid command. An invalid
+ // Make sure the response details match the last valid command. An invalid
// response is a one that doesn't have a corresponding proactive command
- // and sending it can "confuse" the baseband/ril.
- // One reason for out of order responses can be UI glitches. For example,
- // if the application launch an activity, and that activity is stored
+ // and sending it can "confuse" the baseband/ril.
+ // One reason for out of order responses can be UI glitches. For example,
+ // if the application launch an activity, and that activity is stored
// by the framework inside the history stack. That activity will be
- // available for relaunch using the latest application dialog
- // (long press on the home button). Relaunching that activity can send
- // the same command's result again to the StkService and can cause it to
+ // available for relaunch using the latest application dialog
+ // (long press on the home button). Relaunching that activity can send
+ // the same command's result again to the StkService and can cause it to
// get out of sync with the SIM.
if (!validateResponse(resMsg)) {
return;
@@ -618,7 +617,7 @@ public class StkService extends Handler implements AppInterface {
mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null);
// No need to send terminal response for SET UP CALL. The user's
// confirmation result is send back using a dedicated ril message
- // invoked by the CommandInterface call above.
+ // invoked by the CommandInterface call above.
mCurrntCmd = null;
return;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
index bbc925e..90cc6c1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
@@ -20,7 +20,7 @@ import android.os.Parcel;
import android.os.Parcelable;
/**
- * Container class for PlayTone commands parameters.
+ * Container class for PlayTone commands parameters.
*
*/
public class ToneSettings implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
index 8c8f977..09a860e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
+++ b/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
@@ -1,12 +1,12 @@
/*
* Copyright (C) 2006-2007 Google Inc.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -28,7 +28,7 @@ abstract class ValueParser {
/**
* Search for a Command Details object from a list.
- *
+ *
* @param ctlvs List of ComprehensionTlv objects used for search
* @return An CtlvCommandDetails object found from the objects. If no
* Command Details object is found, ResultException is thrown.
@@ -53,7 +53,7 @@ abstract class ValueParser {
/**
* Search for a Device Identities object from a list.
- *
+ *
* @param ctlvs List of ComprehensionTlv objects used for search
* @return An CtlvDeviceIdentities object found from the objects. If no
* Command Details object is found, ResultException is thrown.
@@ -77,7 +77,7 @@ abstract class ValueParser {
/**
* Retrieves Duration information from the Duration COMPREHENSION-TLV
* object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return A Duration object
* @throws ResultException
@@ -100,7 +100,7 @@ abstract class ValueParser {
/**
* Retrieves Item information from the COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return An Item
* @throws ResultException
@@ -130,7 +130,7 @@ abstract class ValueParser {
/**
* Retrieves Item id information from the COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return An Item id
* @throws ResultException
@@ -152,7 +152,7 @@ abstract class ValueParser {
/**
* Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object
- *
+ *
* @param ctlv An Icon Identifier COMPREHENSION-TLV object
* @return IconId instance
* @throws ResultException
@@ -175,7 +175,7 @@ abstract class ValueParser {
/**
* Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV
* object
- *
+ *
* @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object
* @return ItemsIconId instance
* @throws ResultException
@@ -206,7 +206,7 @@ abstract class ValueParser {
/**
* Retrieves text attribute information from the Text Attribute
* COMPREHENSION-TLV object.
- *
+ *
* @param ctlv A Text Attribute COMPREHENSION-TLV object
* @return A list of TextAttribute objects
* @throws ResultException
@@ -266,7 +266,7 @@ abstract class ValueParser {
/**
* Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV
* object.
- *
+ *
* @param ctlv An Alpha Identifier COMPREHENSION-TLV object
* @return String corresponding to the alpha identifier
* @throws ResultException
@@ -290,7 +290,7 @@ abstract class ValueParser {
/**
* Retrieves text from the Text COMPREHENSION-TLV object, and decodes it
* into a Java String.
- *
+ *
* @param ctlv A Text COMPREHENSION-TLV object
* @return A Java String object decoded from the Text object
* @throws ResultException
diff --git a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
index 25d2026..b116c35 100644
--- a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
+++ b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java
@@ -75,7 +75,7 @@ class LineReader
* Returns NULL on EOF
*/
- String
+ String
getNextLine(boolean ctrlZ)
{
int i = 0;
@@ -131,7 +131,7 @@ class InterpreterEx extends Exception
String result;
}
-public class ModelInterpreter
+public class ModelInterpreter
implements Runnable, SimulatedRadioControl
{
static final int MAX_CALLS = 6;
@@ -153,14 +153,14 @@ public class ModelInterpreter
SimulatedGsmCallState simulatedCallState;
HandlerThread mHandlerThread;
-
+
int pausedResponseCount;
Object pausedResponseMonitor = new Object();
//***** Events
static final int PROGRESS_CALL_STATE = 1;
-
+
//***** Constructor
public
@@ -181,7 +181,7 @@ public class ModelInterpreter
ss.bind(sa);
init();
- }
+ }
private void
init()
@@ -190,7 +190,7 @@ public class ModelInterpreter
mHandlerThread = new HandlerThread("ModelInterpreter");
mHandlerThread.start();
Looper looper = mHandlerThread.getLooper();
- simulatedCallState = new SimulatedGsmCallState(looper);
+ simulatedCallState = new SimulatedGsmCallState(looper);
}
//***** Runnable Implementation
@@ -204,7 +204,7 @@ public class ModelInterpreter
try {
s = ss.accept();
} catch (java.io.IOException ex) {
- Log.w(LOG_TAG,
+ Log.w(LOG_TAG,
"IOException on socket.accept(); stopping", ex);
return;
}
@@ -213,15 +213,15 @@ public class ModelInterpreter
in = s.getInputStream();
out = s.getOutputStream();
} catch (java.io.IOException ex) {
- Log.w(LOG_TAG,
+ Log.w(LOG_TAG,
"IOException on accepted socket(); re-listening", ex);
continue;
}
Log.i(LOG_TAG, "New connection accepted");
}
-
-
+
+
lineReader = new LineReader (in);
println ("Welcome");
@@ -271,14 +271,14 @@ public class ModelInterpreter
//***** Instance Methods
-
+
/** Start the simulated phone ringing */
public void
triggerRing(String number)
{
synchronized (this) {
boolean success;
-
+
success = simulatedCallState.triggerRing(number);
if (success) {
@@ -307,10 +307,10 @@ public class ModelInterpreter
*/
public void
setAutoProgressConnectingCall(boolean b)
- {
+ {
simulatedCallState.setAutoProgressConnectingCall(b);
}
-
+
public void
setNextDialFailImmediately(boolean b)
{
@@ -321,7 +321,7 @@ public class ModelInterpreter
{
//FIXME implement
}
-
+
/** hangup ringing, dialing, or actuve calls */
public void
@@ -373,7 +373,7 @@ public class ModelInterpreter
public void triggerSsn(int a, int b) {}
public void triggerIncomingUssd(String statusCode, String message) {}
-
+
public void
triggerIncomingSMS(String message)
{
@@ -386,7 +386,7 @@ public class ModelInterpreter
// source address: +18005551212
pdu.append("918100551521F0");
-
+
// protocol ID and data coding scheme
pdu.append("0000");
@@ -421,7 +421,7 @@ public class ModelInterpreter
pausedResponseMonitor.notifyAll();
}
}
- }
+ }
//***** Private Instance Methods
@@ -429,11 +429,11 @@ public class ModelInterpreter
onAnswer() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.onAnswer();
if (!success) {
- throw new InterpreterEx("ERROR");
+ throw new InterpreterEx("ERROR");
}
}
@@ -445,7 +445,7 @@ public class ModelInterpreter
success = simulatedCallState.onAnswer();
if (!success) {
- throw new InterpreterEx("ERROR");
+ throw new InterpreterEx("ERROR");
}
finalResponse = "NO CARRIER";
@@ -471,12 +471,12 @@ public class ModelInterpreter
throw new InterpreterEx("ERROR");
}
}
-
+
private void
releaseHeldOrUDUB() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.releaseHeldOrUDUB();
if (!success) {
@@ -488,19 +488,19 @@ public class ModelInterpreter
releaseActiveAcceptHeldOrWaiting() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.releaseActiveAcceptHeldOrWaiting();
if (!success) {
throw new InterpreterEx("ERROR");
}
- }
+ }
private void
switchActiveAndHeldOrWaiting() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.switchActiveAndHeldOrWaiting();
if (!success) {
@@ -512,7 +512,7 @@ public class ModelInterpreter
separateCall(int index) throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.separateCall(index);
if (!success) {
@@ -524,7 +524,7 @@ public class ModelInterpreter
conference() throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.conference();
if (!success) {
@@ -536,7 +536,7 @@ public class ModelInterpreter
onDial(String command) throws InterpreterEx
{
boolean success;
-
+
success = simulatedCallState.onDial(command.substring(1));
if (!success) {
@@ -566,7 +566,7 @@ public class ModelInterpreter
println("+CMGS: 1");
}
-
+
void
processLine (String line) throws InterpreterEx
{
@@ -645,8 +645,8 @@ public class ModelInterpreter
}
***/
}
-
- void
+
+ void
println (String s)
{
synchronized(this) {
@@ -663,7 +663,7 @@ public class ModelInterpreter
}
}
- void
+ void
print (String s)
{
synchronized(this) {
@@ -714,8 +714,8 @@ public class ModelInterpreter
{"+CIMI", "320720000000000\r"},
{"+CSCS=?", "+CSCS: (\"HEX\",\"UCS2\")\r"},
{"+CFUN?", "+CFUN: 1\r"},
- {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
- "+COPS: 0,0,\"Android\"\r"
+ {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
+ "+COPS: 0,0,\"Android\"\r"
+ "+COPS: 0,1,\"Android\"\r"
+ "+COPS: 0,2,\"310995\"\r"},
{"+CREG?", "+CREG: 2,5, \"0113\", \"6614\"\r"},
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 9fb9be8..22adc19 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -28,6 +28,7 @@ import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.gsm.CallFailCause;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.Phone;
@@ -1022,6 +1023,10 @@ public final class SimulatedCommands extends BaseCommands
unimplemented(result);
}
+ public void reportStkServiceIsRunning(Message result) {
+ resultSuccess(result, null);
+ }
+
private boolean isSimLocked() {
if (mSimLockedState != SimLockState.NONE) {
return true;
@@ -1449,22 +1454,36 @@ public final class SimulatedCommands extends BaseCommands
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
}
- public void activateCdmaBroadcastSms(int activate, Message result) {
- // TODO Auto-generated method stub
+ public void setCdmaBroadcastActivation(boolean activate, Message response) {
+ unimplemented(response);
}
- public void getCdmaBroadcastConfig(Message result) {
- // TODO Auto-generated method stub
+ public void getCdmaBroadcastConfig(Message response) {
+ unimplemented(response);
}
- public void setCdmaBroadcastConfig(int[] configValuesArray, Message result) {
- // TODO Auto-generated method stub
+ public void setCdmaBroadcastConfig(int[] configValuesArray, Message response) {
+ unimplemented(response);
}
public void forceDataDormancy(Message response) {
- // TODO method stub
+ unimplemented(response);
+ }
+
+
+ public void setGsmBroadcastActivation(boolean activate, Message response) {
+ unimplemented(response);
+ }
+
+
+ public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
+ unimplemented(response);
+ }
+
+ public void getGsmBroadcastConfig(Message response) {
+ unimplemented(response);
}
}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
index 803735c..c6c301d 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java
@@ -37,7 +37,7 @@ class CallInfo {
WAITING(5); // MT call only
State (int value) {this.value = value;}
-
+
private final int value;
public int value() {return value;};
};
@@ -73,7 +73,7 @@ class CallInfo {
String
toCLCCLine(int index) {
- return
+ return
"+CLCC: "
+ index + "," + (isMT ? "1" : "0") +","
+ state.value() + ",0," + (isMpty ? "1" : "0")
@@ -82,7 +82,7 @@ class CallInfo {
DriverCall
toDriverCall(int index) {
- DriverCall ret;
+ DriverCall ret;
ret = new DriverCall();
@@ -136,7 +136,7 @@ class SimulatedGsmCallState extends Handler {
private boolean autoProgressConnecting = true;
private boolean nextDialFailImmediately;
-
+
//***** Event Constants
@@ -169,8 +169,8 @@ class SimulatedGsmCallState extends Handler {
//***** Public Methods
- /**
- * Start the simulated phone ringing
+ /**
+ * Start the simulated phone ringing
* true if succeeded, false if failed
*/
public boolean
@@ -185,7 +185,7 @@ class SimulatedGsmCallState extends Handler {
if (call == null && empty < 0) {
empty = i;
- } else if (call != null
+ } else if (call != null
&& (call.state == CallInfo.State.INCOMING
|| call.state == CallInfo.State.WAITING)
) {
@@ -208,7 +208,7 @@ class SimulatedGsmCallState extends Handler {
if (isCallWaiting) {
calls[empty].state = CallInfo.State.WAITING;
}
-
+
}
return true;
}
@@ -225,11 +225,11 @@ class SimulatedGsmCallState extends Handler {
if (autoProgressConnecting) {
sendMessageDelayed(
- obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
+ obtainMessage(EVENT_PROGRESS_CALL_STATE, call),
CONNECTING_PAUSE_MSEC);
}
break;
- } else if (call != null
+ } else if (call != null
&& call.state == CallInfo.State.ALERTING
) {
call.state = CallInfo.State.ACTIVE;
@@ -246,7 +246,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null && (call.state == CallInfo.State.DIALING
+ if (call != null && (call.state == CallInfo.State.DIALING
|| call.state == CallInfo.State.ALERTING)
) {
call.state = CallInfo.State.ACTIVE;
@@ -263,13 +263,13 @@ class SimulatedGsmCallState extends Handler {
setAutoProgressConnectingCall(boolean b) {
autoProgressConnecting = b;
}
-
+
public void
setNextDialFailImmediately(boolean b) {
nextDialFailImmediately = b;
}
- /**
+ /**
* hangup ringing, dialing, or active calls
* returns true if call was hung up, false if not
*/
@@ -283,7 +283,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null
+ if (call != null
&& (call.state == CallInfo.State.INCOMING
|| call.state == CallInfo.State.WAITING)
) {
@@ -295,7 +295,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null
+ if (call != null
&& (call.state == CallInfo.State.DIALING
|| call.state == CallInfo.State.ACTIVE
|| call.state == CallInfo.State.ALERTING)
@@ -308,7 +308,7 @@ class SimulatedGsmCallState extends Handler {
}
}
- /**
+ /**
* hangup holding calls
* returns true if call was hung up, false if not
*/
@@ -330,7 +330,7 @@ class SimulatedGsmCallState extends Handler {
}
}
- /**
+ /**
* hangup all
* returns true if call was hung up, false if not
*/
@@ -359,7 +359,7 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo call = calls[i];
- if (call != null
+ if (call != null
&& (call.state == CallInfo.State.INCOMING
|| call.state == CallInfo.State.WAITING)
) {
@@ -399,7 +399,7 @@ class SimulatedGsmCallState extends Handler {
return false;
}
}
-
+
switch (c0) {
case '0':
ret = releaseHeldOrUDUB();
@@ -442,7 +442,7 @@ class SimulatedGsmCallState extends Handler {
return ret;
}
-
+
public boolean
releaseHeldOrUDUB() {
boolean found = false;
@@ -493,8 +493,8 @@ class SimulatedGsmCallState extends Handler {
for (int i = 0 ; i < calls.length ; i++) {
CallInfo c = calls[i];
- if (c != null
- && (c.state == CallInfo.State.DIALING
+ if (c != null
+ && (c.state == CallInfo.State.DIALING
|| c.state == CallInfo.State.ALERTING)
) {
calls[i] = null;
@@ -531,7 +531,7 @@ class SimulatedGsmCallState extends Handler {
public boolean
switchActiveAndHeldOrWaiting() {
boolean hasHeld = false;
-
+
// first, are there held calls?
for (int i = 0 ; i < calls.length ; i++) {
CallInfo c = calls[i];
@@ -595,7 +595,7 @@ class SimulatedGsmCallState extends Handler {
}
return true;
- } catch (InvalidStateEx ex) {
+ } catch (InvalidStateEx ex) {
return false;
}
}
@@ -612,7 +612,7 @@ class SimulatedGsmCallState extends Handler {
if (c != null) {
countCalls++;
-
+
if (c.isConnecting()) {
return false;
}
@@ -624,7 +624,7 @@ class SimulatedGsmCallState extends Handler {
if (c != null) {
c.state = CallInfo.State.ACTIVE;
if (countCalls > 0) {
- c.isMpty = true;
+ c.isMpty = true;
}
}
}
@@ -659,12 +659,12 @@ class SimulatedGsmCallState extends Handler {
int freeSlot = -1;
Log.d("GSM", "SC> dial '" + address + "'");
-
+
if (nextDialFailImmediately) {
nextDialFailImmediately = false;
Log.d("GSM", "SC< dial fail (per request)");
- return false;
+ return false;
}
String phNum = PhoneNumberUtils.extractNetworkPortion(address);
@@ -696,15 +696,15 @@ class SimulatedGsmCallState extends Handler {
if (freeSlot < 0 && calls[i] == null) {
freeSlot = i;
}
-
+
if (calls[i] != null && !calls[i].isActiveOrHeld()) {
- // Can't make outgoing calls when there is a ringing or
+ // Can't make outgoing calls when there is a ringing or
// connecting outgoing call
Log.d("GSM", "SC< dial fail (invalid call state)");
return false;
} else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) {
// All active calls behome held
- calls[i].state = CallInfo.State.HOLDING;
+ calls[i].state = CallInfo.State.HOLDING;
}
}
@@ -717,7 +717,7 @@ class SimulatedGsmCallState extends Handler {
if (autoProgressConnecting) {
sendMessageDelayed(
- obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
+ obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]),
CONNECTING_PAUSE_MSEC);
}
@@ -776,7 +776,7 @@ class SimulatedGsmCallState extends Handler {
if (call != null) {
if (!hasMpty && call.isMpty) {
mptyIsHeld = call.state == CallInfo.State.HOLDING;
- } else if (call.isMpty && mptyIsHeld
+ } else if (call.isMpty && mptyIsHeld
&& call.state == CallInfo.State.ACTIVE
) {
Log.e("ModelInterpreter", "Invalid state");
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
index 9e1a7c5..054d370 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java
@@ -45,7 +45,7 @@ public interface SimulatedRadioControl
/** see pauseResponses */
public void resumeResponses();
-
+
public void triggerSsn(int type, int code);
/** Generates an incoming USSD message. */
diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java
index e733dd1..9e0cf2c 100644
--- a/test-runner/android/test/mock/MockContext.java
+++ b/test-runner/android/test/mock/MockContext.java
@@ -105,6 +105,11 @@ public class MockContext extends Context {
}
@Override
+ public File getSharedPrefsFile(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public String getPackageCodePath() {
throw new UnsupportedOperationException();
}
diff --git a/tests/AndroidTests/AndroidManifest.xml b/tests/AndroidTests/AndroidManifest.xml
index fd6e6d8..55d4d64 100644
--- a/tests/AndroidTests/AndroidManifest.xml
+++ b/tests/AndroidTests/AndroidManifest.xml
@@ -219,7 +219,20 @@
</service>
<!-- Application components used for search manager tests -->
- <!-- TODO: Removed temporarily - need to be replaced using mocks -->
+
+ <activity android:name=".SearchableActivity"
+ android:label="Searchable Activity">
+ <intent-filter>
+ <action android:name="android.intent.action.SEARCH" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="android.app.searchable"
+ android:resource="@xml/searchable" />
+ </activity>
+
+ <provider android:name=".SuggestionProvider"
+ android:authorities="com.android.unit_tests.SuggestionProvider">
+ </provider>
<!-- Used to test IPC. -->
<service android:name=".binder.BinderTestService"
diff --git a/tests/AndroidTests/res/values/strings.xml b/tests/AndroidTests/res/values/strings.xml
index 21c72cf..49d8ae7 100644
--- a/tests/AndroidTests/res/values/strings.xml
+++ b/tests/AndroidTests/res/values/strings.xml
@@ -50,5 +50,8 @@
<item quantity="other">Some dogs</item>
</plurals>
+ <string name="searchable_label">SearchManager Test</string>
+ <string name="searchable_hint">A search hint</string>
+
<!-- <string name="layout_six_text_text">F</string> -->
</resources>
diff --git a/tests/AndroidTests/res/xml/searchable.xml b/tests/AndroidTests/res/xml/searchable.xml
index a40d53d..9d293b5 100644
--- a/tests/AndroidTests/res/xml/searchable.xml
+++ b/tests/AndroidTests/res/xml/searchable.xml
@@ -15,7 +15,12 @@
-->
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
- android:label="SearchManagerTest"
- android:hint="SearchManagerTest Hint"
-/>
+ android:label="@string/searchable_label"
+ android:hint="@string/searchable_hint"
+ android:searchSuggestAuthority="com.android.unit_tests.SuggestionProvider"
+ >
+ <actionkey android:keycode="KEYCODE_CALL"
+ android:suggestActionMsgColumn="suggest_action_msg_call" />
+
+</searchable> \ No newline at end of file
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
index f3c1542..f03a779 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
@@ -23,7 +23,10 @@ import android.app.ISearchManager;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
+import android.os.Bundle;
+import android.os.RemoteException;
import android.os.ServiceManager;
+import android.server.search.SearchableInfo;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
@@ -37,12 +40,11 @@ import android.util.AndroidRuntimeException;
* com.android.unit_tests/android.test.InstrumentationTestRunner
*/
public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalActivity> {
-
- // If non-zero, enable a set of tests that start and stop the search manager.
- // This is currently disabled because it's causing an unwanted jump from the unit test
- // activity into the contacts activity. We'll put this back after we disable that jump.
- private static final int TEST_SEARCH_START = 0;
-
+
+ private ComponentName SEARCHABLE_ACTIVITY =
+ new ComponentName("com.android.unit_tests",
+ "com.android.unit_tests.SearchableActivity");
+
/*
* Bug list of test ideas.
*
@@ -88,7 +90,30 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct
super.setUp();
Activity testActivity = getActivity();
- mContext = (Context)testActivity;
+ mContext = testActivity;
+ }
+
+ private ISearchManager getSearchManagerService() {
+ return ISearchManager.Stub.asInterface(
+ ServiceManager.getService(Context.SEARCH_SERVICE));
+ }
+
+ // Checks that the search UI is visible.
+ private void assertSearchVisible() {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertTrue("SearchManager thinks search UI isn't visible when it should be",
+ searchManager.isVisible());
+ }
+
+ // Checks that the search UI is not visible.
+ // This checks both the SearchManager and the SearchManagerService,
+ // since SearchManager keeps a local variable for the visibility.
+ private void assertSearchNotVisible() {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertFalse("SearchManager thinks search UI is visible when it shouldn't be",
+ searchManager.isVisible());
}
/**
@@ -97,9 +122,7 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct
*/
@MediumTest
public void testSearchManagerInterfaceAvailable() {
- ISearchManager searchManager1 = ISearchManager.Stub.asInterface(
- ServiceManager.getService(Context.SEARCH_SERVICE));
- assertNotNull(searchManager1);
+ assertNotNull(getSearchManagerService());
}
/**
@@ -135,38 +158,127 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct
SearchManager searchManager2 = (SearchManager)
mContext.getSystemService(Context.SEARCH_SERVICE);
assertNotNull(searchManager2);
- assertSame( searchManager1, searchManager2 );
+ assertSame(searchManager1, searchManager2 );
}
-
+
+ @MediumTest
+ public void testSearchables() {
+ SearchableInfo si;
+
+ si = SearchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, false);
+ assertNotNull(si);
+ assertFalse(SearchManager.isDefaultSearchable(si));
+ si = SearchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, true);
+ assertNotNull(si);
+ assertTrue(SearchManager.isDefaultSearchable(si));
+ si = SearchManager.getSearchableInfo(null, true);
+ assertNotNull(si);
+ assertTrue(SearchManager.isDefaultSearchable(si));
+ }
+
+ /**
+ * Tests that rapid calls to start-stop-start doesn't cause problems.
+ */
+ @MediumTest
+ public void testSearchManagerFastInvocations() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+ assertSearchNotVisible();
+
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+ }
+
+ /**
+ * Tests that startSearch() is idempotent.
+ */
+ @MediumTest
+ public void testStartSearchIdempotent() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+ assertSearchNotVisible();
+
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+ }
+
+ /**
+ * Tests that stopSearch() is idempotent and can be called when the search UI is not visible.
+ */
+ @MediumTest
+ public void testStopSearchIdempotent() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+ assertSearchNotVisible();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+ }
+
/**
* The goal of this test is to confirm that we can start and then
* stop a simple search.
*/
-
- @MediumTest
- public void testSearchManagerInvocations() {
+ @MediumTest
+ public void testSearchManagerInvocations() throws Exception {
SearchManager searchManager = (SearchManager)
mContext.getSystemService(Context.SEARCH_SERVICE);
assertNotNull(searchManager);
-
- // TODO: make a real component name, or remove this need
- final ComponentName cn = new ComponentName("", "");
-
- if (TEST_SEARCH_START != 0) {
- // These tests should simply run to completion w/o exceptions
- searchManager.startSearch(null, false, cn, null, false);
- searchManager.stopSearch();
-
- searchManager.startSearch("", false, cn, null, false);
- searchManager.stopSearch();
-
- searchManager.startSearch("test search string", false, cn, null, false);
- searchManager.stopSearch();
-
- searchManager.startSearch("test search string", true, cn, null, false);
- searchManager.stopSearch();
- }
- }
+ assertSearchNotVisible();
-}
+ // These tests should simply run to completion w/o exceptions
+ searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+
+ searchManager.startSearch("", false, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+
+ searchManager.startSearch("test search string", false, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+
+ searchManager.startSearch("test search string", true, SEARCHABLE_ACTIVITY, null, false);
+ assertSearchVisible();
+ searchManager.stopSearch();
+ assertSearchNotVisible();
+ }
+ @MediumTest
+ public void testSearchDialogState() throws Exception {
+ SearchManager searchManager = (SearchManager)
+ mContext.getSystemService(Context.SEARCH_SERVICE);
+ assertNotNull(searchManager);
+
+ Bundle searchState;
+
+ // search dialog not visible, so no state should be stored
+ searchState = searchManager.saveSearchDialog();
+ assertNull(searchState);
+
+ searchManager.startSearch("test search string", true, SEARCHABLE_ACTIVITY, null, false);
+ searchState = searchManager.saveSearchDialog();
+ assertNotNull(searchState);
+ searchManager.stopSearch();
+ }
+
+}
diff --git a/tests/sketch/src/com/android/gesture/example/ContactItem.java b/tests/AndroidTests/src/com/android/unit_tests/SearchableActivity.java
index 557c4d9..53f40e9 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactItem.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchableActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,21 +14,17 @@
* limitations under the License.
*/
-package com.android.gesture.example;
+package com.android.unit_tests;
+import android.app.Activity;
+import android.os.Bundle;
-class ContactItem {
- final String itemName;
-
- final long itemID;
-
- public ContactItem(long id, String name) {
- itemID = id;
- itemName = name;
- }
+public class SearchableActivity extends Activity {
@Override
- public String toString() {
- return itemName;
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ finish();
}
+
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
index 6b56e6c..ecc8dfe 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
@@ -72,19 +72,19 @@ public class SearchablesTest extends AndroidTestCase {
* TODO: The metadata source needs to be mocked out because adding
* searchability metadata via this test is causing it to leak into the
* real system. So for now I'm just going to test for existence of the
- * GoogleSearch app (which is searchable).
+ * GlobalSearch app (which is searchable).
*/
- public void testSearchableGoogleSearch() {
+ public void testSearchableGlobalSearch() {
// test basic array & hashmap
Searchables searchables = new Searchables(mContext);
searchables.buildSearchableList();
// test linkage from another activity
// TODO inject this via mocking into the package manager.
- // TODO for now, just check for searchable GoogleSearch app (this isn't really a unit test)
+ // TODO for now, just check for searchable GlobalSearch app (this isn't really a unit test)
ComponentName thisActivity = new ComponentName(
- "com.android.googlesearch",
- "com.android.googlesearch.GoogleSearch");
+ "com.android.globalsearch",
+ "com.android.globalsearch.GlobalSearch");
SearchableInfo si = searchables.getSearchableInfo(thisActivity);
assertNotNull(si);
@@ -93,7 +93,7 @@ public class SearchablesTest extends AndroidTestCase {
Context appContext = si.getActivityContext(mContext);
assertNotNull(appContext);
MoreAsserts.assertNotEqual(appContext, mContext);
- assertEquals("Google Search", appContext.getString(si.getHintId()));
+ assertEquals("Android Search", appContext.getString(si.getHintId()));
assertEquals("Google", appContext.getString(si.getLabelId()));
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java b/tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java
new file mode 100644
index 0000000..bc61e27
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.unit_tests;
+
+import android.app.SearchManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+
+/** Simple test provider that runs in the local process.
+ *
+ * Used by {@link SearchManagerTest}.
+ */
+public class SuggestionProvider extends ContentProvider {
+ private static final String TAG = "SuggestionProvider";
+
+ private static final int SEARCH_SUGGESTIONS = 1;
+
+ private static final UriMatcher sURLMatcher = new UriMatcher(
+ UriMatcher.NO_MATCH);
+
+ static {
+ sURLMatcher.addURI("*", SearchManager.SUGGEST_URI_PATH_QUERY,
+ SEARCH_SUGGESTIONS);
+ sURLMatcher.addURI("*", SearchManager.SUGGEST_URI_PATH_QUERY + "/*",
+ SEARCH_SUGGESTIONS);
+ }
+
+ private static final String[] COLUMNS = new String[] {
+ "_id",
+ SearchManager.SUGGEST_COLUMN_TEXT_1,
+ SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+ SearchManager.SUGGEST_COLUMN_QUERY
+ };
+
+ public SuggestionProvider() {
+ }
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri url, String[] projectionIn, String selection,
+ String[] selectionArgs, String sort) {
+ int match = sURLMatcher.match(url);
+ switch (match) {
+ case SEARCH_SUGGESTIONS:
+ String query = url.getLastPathSegment();
+ MatrixCursor cursor = new MatrixCursor(COLUMNS);
+ String[] suffixes = { "", "a", " foo", "XXXXXXXXXXXXXXXXX" };
+ for (String suffix : suffixes) {
+ addRow(cursor, query + suffix);
+ }
+ return cursor;
+ default:
+ throw new IllegalArgumentException("Unknown URL: " + url);
+ }
+ }
+
+ private void addRow(MatrixCursor cursor, String string) {
+ long id = cursor.getCount();
+ cursor.newRow().add(id).add(string).add(Intent.ACTION_SEARCH).add(string);
+ }
+
+ @Override
+ public String getType(Uri url) {
+ int match = sURLMatcher.match(url);
+ switch (match) {
+ case SEARCH_SUGGESTIONS:
+ return SearchManager.SUGGEST_MIME_TYPE;
+ default:
+ throw new IllegalArgumentException("Unknown URL: " + url);
+ }
+ }
+
+ @Override
+ public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
+ throw new UnsupportedOperationException("update not supported");
+ }
+
+ @Override
+ public Uri insert(Uri url, ContentValues initialValues) {
+ throw new UnsupportedOperationException("insert not supported");
+ }
+
+ @Override
+ public int delete(Uri url, String where, String[] whereArgs) {
+ throw new UnsupportedOperationException("delete not supported");
+ }
+}
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_failed.txt b/tests/DumpRenderTree/assets/results/layout_tests_failed.txt
index 3cec40d..651b324 100644
--- a/tests/DumpRenderTree/assets/results/layout_tests_failed.txt
+++ b/tests/DumpRenderTree/assets/results/layout_tests_failed.txt
@@ -1,280 +1,698 @@
-/sdcard/android/layout_tests/fast/replaced/image-map-bug16782.html : different length
-/sdcard/android/layout_tests/fast/replaced/table-percent-height.html : different length
-/sdcard/android/layout_tests/fast/replaced/image-map.html : different length
-/sdcard/android/layout_tests/fast/dynamic/paused-event-dispatch.html : @offset: 117
-/sdcard/android/layout_tests/fast/text/plain-text-line-breaks.html : different length
-/sdcard/android/layout_tests/fast/text/zero-width-characters.html : different length
-/sdcard/android/layout_tests/fast/text/reset-drag-on-mouse-down.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/encoding/invalid-xml.html : different length
-/sdcard/android/layout_tests/fast/encoding/char-decoding-mac.html : different length
-/sdcard/android/layout_tests/fast/encoding/frame-default-enc.html : @offset: 0
-/sdcard/android/layout_tests/fast/encoding/mailto-always-utf-8.html : different length
-/sdcard/android/layout_tests/fast/encoding/char-decoding.html : different length
-/sdcard/android/layout_tests/fast/encoding/url-host-name-non-ascii.html : different length
-/sdcard/android/layout_tests/fast/encoding/idn-security.html : different length
-/sdcard/android/layout_tests/fast/encoding/percent-escaping.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/encoding/xml-utf-8-default.xml : different length
-/sdcard/android/layout_tests/fast/encoding/char-encoding-mac.html : different length
-/sdcard/android/layout_tests/fast/encoding/charset-koi8-u.html : @offset: 147
-/sdcard/android/layout_tests/fast/encoding/preload-encoding.html : different length
-/sdcard/android/layout_tests/fast/workers/worker-location.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/workers/worker-constructor.html : different length
-/sdcard/android/layout_tests/fast/workers/worker-terminate.html : different length
-/sdcard/android/layout_tests/fast/workers/worker-gc.html : different length
-/sdcard/android/layout_tests/fast/workers/worker-navigator.html : different length
-/sdcard/android/layout_tests/fast/workers/worker-replace-global-constructor.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/workers/worker-replace-self.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/workers/worker-event-listener.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/overflow/scroll-vertical-not-horizontal.html : different length
-/sdcard/android/layout_tests/fast/events/onunload.html : different length
-/sdcard/android/layout_tests/fast/events/mouseup-outside-document.html : different length
-/sdcard/android/layout_tests/fast/events/offsetX-offsetY.html : different length
-/sdcard/android/layout_tests/fast/events/scroll-event-does-not-bubble.html : different length
-/sdcard/android/layout_tests/fast/events/mouseover-mouseout.html : different length
-/sdcard/android/layout_tests/fast/events/option-tab.html : different length
-/sdcard/android/layout_tests/fast/events/popup-blocking-click-in-iframe.html : different length
-/sdcard/android/layout_tests/fast/events/onchange-passwordfield.html : different length
-/sdcard/android/layout_tests/fast/events/drag-in-frames.html : different length
-/sdcard/android/layout_tests/fast/events/frame-tab-focus.html : different length
-/sdcard/android/layout_tests/fast/events/autoscroll-in-textfield.html : different length
-/sdcard/android/layout_tests/fast/events/arrow-navigation.html : different length
-/sdcard/android/layout_tests/fast/events/fire-scroll-event.html : different length
-/sdcard/android/layout_tests/fast/events/mouseclick-target-and-positioning.html : different length
-/sdcard/android/layout_tests/fast/events/keydown-keypress-focus-change.html : @offset: 172
-/sdcard/android/layout_tests/fast/events/input-image-scrolled-x-y.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/events/dblclick-addEventListener.html : different length
-/sdcard/android/layout_tests/fast/events/frame-programmatic-focus.html : different length
-/sdcard/android/layout_tests/fast/events/related-target.html : different length
-/sdcard/android/layout_tests/fast/events/content-changed-during-drop.html : different length
-/sdcard/android/layout_tests/fast/events/onload-fires-twice.html : different length
-/sdcard/android/layout_tests/fast/events/autoscroll-with-non-scrollable-parent.html : different length
-/sdcard/android/layout_tests/fast/events/window-events-capture.html : different length
-/sdcard/android/layout_tests/fast/events/onchange-click-hang.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/events/onload-webkit-before-webcore.html : @offset: 105
-/sdcard/android/layout_tests/fast/events/window-events-bubble2.html : different length
-/sdcard/android/layout_tests/fast/events/js-keyboard-event-creation.html : different length
-/sdcard/android/layout_tests/fast/events/event-view-toString.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/events/onchange-select-popup.html : different length
-/sdcard/android/layout_tests/fast/events/access-key-self-destruct.html : different length
-/sdcard/android/layout_tests/fast/events/scrollbar-double-click.html : different length
-/sdcard/android/layout_tests/fast/events/onunload-clears-onbeforeunload.html : different length
-/sdcard/android/layout_tests/fast/events/tabindex-focus-chain.html : @offset: 0
-/sdcard/android/layout_tests/fast/events/capture-on-target.html : different length
-/sdcard/android/layout_tests/fast/events/window-events-bubble.html : different length
-/sdcard/android/layout_tests/fast/events/mouseup-from-button2.html : different length
-/sdcard/android/layout_tests/fast/events/frame-click-focus.html : different length
-/sdcard/android/layout_tests/fast/events/mouseout-on-window.html : different length
-/sdcard/android/layout_tests/fast/events/keypress-insert-tab.html : @offset: 85
-/sdcard/android/layout_tests/fast/events/mouseout-dead-subframe.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/events/iframe-object-onload.html : different length
-/sdcard/android/layout_tests/fast/events/onunload-not-on-body.html : different length
-/sdcard/android/layout_tests/fast/events/mousemove-after-drag-over-scrollbar.html : different length
-/sdcard/android/layout_tests/fast/events/contextmenu-scrolled-page-with-frame.html : different length
-/sdcard/android/layout_tests/fast/events/key-events-in-input-button.html : different length
-/sdcard/android/layout_tests/fast/events/arrow-keys-on-body.html : different length
-/sdcard/android/layout_tests/fast/events/ondragenter.html : different length
-/sdcard/android/layout_tests/fast/events/scroll-to-anchor-in-overflow-hidden.html : different length
-/sdcard/android/layout_tests/fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html : different length
-/sdcard/android/layout_tests/fast/events/keypress-focus-change.html : different length
-/sdcard/android/layout_tests/fast/events/key-events-in-input-text.html : different length
-/sdcard/android/layout_tests/fast/events/drag-outside-window.html : @offset: 20
-/sdcard/android/layout_tests/fast/events/selectstart-during-autoscroll.html : different length
-/sdcard/android/layout_tests/fast/events/click-count.html : different length
-/sdcard/android/layout_tests/fast/events/onchange-searchfield.html : different length
-/sdcard/android/layout_tests/fast/events/special-key-events-in-input-text.html : different length
-/sdcard/android/layout_tests/fast/events/keydown-keypress-preventDefault.html : @offset: 228
-/sdcard/android/layout_tests/fast/events/mouse-click-events.html : different length
-/sdcard/android/layout_tests/fast/events/onsearch-enter.html : different length
-/sdcard/android/layout_tests/fast/events/mouseover-mouseout2.html : different length
-/sdcard/android/layout_tests/fast/events/open-window-from-another-frame.html : different length
-/sdcard/android/layout_tests/fast/events/init-events.html : different length
-/sdcard/android/layout_tests/fast/events/onchange-textfield.html : different length
-/sdcard/android/layout_tests/fast/events/onclick-list-marker.html : different length
-/sdcard/android/layout_tests/fast/events/anchor-image-scrolled-x-y.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/html/tab-order.html : @offset: 246
-/sdcard/android/layout_tests/fast/js/exception-sequencing-binops.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/recursion-limit-equal.html : different length
-/sdcard/android/layout_tests/fast/js/exception-sequencing-binops2.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/math-transforms.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/try-catch-crash.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/navigator-mimeTypes-length.html : different length
-/sdcard/android/layout_tests/fast/js/global-constructors.html : different length
-/sdcard/android/layout_tests/fast/js/uncaught-exception-line-number.html : different length
-/sdcard/android/layout_tests/fast/js/exceptions-thrown-in-callbacks.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/toString-and-valueOf-override.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/exception-sequencing.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/js/exception-codegen-crash.html : different length
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/activeElement.html : different length
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/hasFocus.html : different length
-/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/listbox-select-reset.html : different length
-/sdcard/android/layout_tests/fast/dom/Element/offsetLeft-offsetTop-body-quirk.html : different length
-/sdcard/android/layout_tests/fast/dom/DOMException/XPathException.html : different length
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/010.xml : different length
-/sdcard/android/layout_tests/fast/dom/getElementsByClassName/011.xml : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-resize-and-move-arguments.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-function-name-getter-precedence.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-xy-properties.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/console-functions.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-screen-properties.html : @offset: 65
-/sdcard/android/layout_tests/fast/dom/Window/window-properties.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/dom/Window/window-onFocus.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/new-window-opener.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/dom/Window/window-open-pending-url.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/setting-properties-on-closed-window.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/dom/Window/dom-access-from-closure-window.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-resize.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-custom-prototype.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/dom-access-from-closure-iframe.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/Plug-ins.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/get-set-properties.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-scroll-arguments.html : different length
-/sdcard/android/layout_tests/fast/dom/Window/window-early-properties.html : different length
-/sdcard/android/layout_tests/fast/dom/StyleSheet/ownerNode-lifetime-2.html : different length
-/sdcard/android/layout_tests/fast/dom/dom-constructors.html : different length
-/sdcard/android/layout_tests/fast/dom/assign-to-window-status.html : different length
-/sdcard/android/layout_tests/fast/dom/gc-8.html : different length
-/sdcard/android/layout_tests/fast/dom/object-embed-plugin-scripting.html : different length
-/sdcard/android/layout_tests/fast/dom/gc-9.html : different length
-/sdcard/android/layout_tests/fast/dom/NamedNodeMap-setNamedItem-crash.html : different length
-/sdcard/android/layout_tests/fast/dom/wrapper-classes.html : different length
-/sdcard/android/layout_tests/fast/dom/select-selectedIndex.html : different length
-/sdcard/android/layout_tests/fast/dom/document-width-height-force-layout.html : @offset: 142
-/sdcard/android/layout_tests/fast/dom/client-width-height.html : @offset: 119
-/sdcard/android/layout_tests/fast/dom/clone-node-form-elements-with-attr.html : different length
-/sdcard/android/layout_tests/fast/dom/dom-add-optionelement.html : different length
-/sdcard/android/layout_tests/fast/dom/location-assign.html : different length
-/sdcard/android/layout_tests/fast/dom/javascript-backslash.html : different length
-/sdcard/android/layout_tests/fast/dom/global-constructors.html : different length
-/sdcard/android/layout_tests/fast/dom/client-width-height-quirks.html : @offset: 115
-/sdcard/android/layout_tests/fast/dom/javascript-url-crash-function.html : different length
-/sdcard/android/layout_tests/fast/dom/location-hash.html : different length
-/sdcard/android/layout_tests/fast/dom/constructors-cached.html : different length
-/sdcard/android/layout_tests/fast/dom/documenturi-can-hold-arbitrary-string.html : different length
-/sdcard/android/layout_tests/fast/dom/documenturi-not-affected-by-base-tag.html : different length
-/sdcard/android/layout_tests/fast/dom/open-and-close-by-DOM.html : different length
-/sdcard/android/layout_tests/fast/dom/document_write_params.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/dom/tabindex-clamp.html : different length
-/sdcard/android/layout_tests/fast/dom/constructors-cached-navigate.html : different length
-/sdcard/android/layout_tests/fast/dom/frame-loading-via-document-write.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/dom/ImageDocument-image-deletion.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-text-plain.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/advanced-get.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-text-plain-latin-1.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-multipart-form-data.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-always-utf-8.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-append-query.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items-x-www-form-urlencoded.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-overwrite-query.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-x-www-form-urlencoded.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items-text-plain.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-text-plain.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-text-plain-with-accept-charset.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/post-text-plain.html : different length
-/sdcard/android/layout_tests/fast/forms/mailto/advanced-put.html : different length
-/sdcard/android/layout_tests/fast/forms/listbox-typeahead-scroll.html : different length
-/sdcard/android/layout_tests/fast/forms/select-empty-list.html : different length
-/sdcard/android/layout_tests/fast/forms/select-accesskey.html : different length
-/sdcard/android/layout_tests/fast/forms/focus2.html : different length
-/sdcard/android/layout_tests/fast/forms/password-doubleclick-selection.html : different length
-/sdcard/android/layout_tests/fast/forms/textfield-inside-anchor.html : different length
-/sdcard/android/layout_tests/fast/forms/input-maxlength.html : different length
-/sdcard/android/layout_tests/fast/forms/input-text-option-delete.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/forms/selection-functions.html : @offset: 306
-/sdcard/android/layout_tests/fast/forms/textfield-to-password-on-focus.html : different length
-/sdcard/android/layout_tests/fast/forms/focus-selection-textarea.html : different length
-/sdcard/android/layout_tests/fast/forms/enter-clicks-buttons.html : different length
-/sdcard/android/layout_tests/fast/forms/menulist-no-renderer-onmousedown.html : different length
-/sdcard/android/layout_tests/fast/forms/select-display-none-style-resolve.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/forms/radio_checked_name.html : @offset: 303
-/sdcard/android/layout_tests/fast/forms/select-double-onchange.html : different length
-/sdcard/android/layout_tests/fast/forms/button-enter-click.html : different length
-/sdcard/android/layout_tests/fast/forms/11423.html : different length
-/sdcard/android/layout_tests/fast/forms/search-click-in-placeholder.html : @offset: 1
-/sdcard/android/layout_tests/fast/forms/autofocus-opera-003.html : @offset: 51
-/sdcard/android/layout_tests/fast/forms/search-hidden-cancel-button.html : different length
-/sdcard/android/layout_tests/fast/forms/willvalidate-004.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-paste-newline.html : different length
-/sdcard/android/layout_tests/fast/forms/drag-into-textarea.html : different length
-/sdcard/android/layout_tests/fast/forms/onselect-textfield.html : different length
-/sdcard/android/layout_tests/fast/forms/input-implicit-length-limit.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/forms/form-and-frame-interaction-retains-values.html : different length
-/sdcard/android/layout_tests/fast/forms/input-appearance-focus.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/forms/slider-transformed.html : different length
-/sdcard/android/layout_tests/fast/forms/listbox-select-all.html : different length
-/sdcard/android/layout_tests/fast/forms/textfield-onchange-deletion.html : different length
-/sdcard/android/layout_tests/fast/forms/focus-control-to-page.html : different length
-/sdcard/android/layout_tests/fast/forms/select-type-ahead-non-latin.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-no-scroll-on-blur.html : @offset: 79
-/sdcard/android/layout_tests/fast/forms/focus-selection-input.html : different length
-/sdcard/android/layout_tests/fast/forms/listbox-onchange.html : different length
-/sdcard/android/layout_tests/fast/forms/button-spacebar-click.html : different length
-/sdcard/android/layout_tests/fast/forms/search-event-delay.html : different length
-/sdcard/android/layout_tests/fast/forms/search-cancel-button-mouseup.html : different length
-/sdcard/android/layout_tests/fast/forms/select-enter-key.html : different length
-/sdcard/android/layout_tests/fast/forms/drag-out-of-textarea.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-hard-linewrap.html : different length
-/sdcard/android/layout_tests/fast/forms/input-type-change-in-onfocus-keyboard.html : different length
-/sdcard/android/layout_tests/fast/forms/dragging-to-disabled-file-input.html : different length
-/sdcard/android/layout_tests/fast/forms/input-radio-checked-tab.html : @offset: 115
-/sdcard/android/layout_tests/fast/forms/plaintext-mode-1.html : different length
-/sdcard/android/layout_tests/fast/forms/option-in-optgroup-removal.html : different length
-/sdcard/android/layout_tests/fast/forms/search-display-none-cancel-button.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/forms/check-box-enter-key.html : different length
-/sdcard/android/layout_tests/fast/forms/input-select-on-click.html : different length
-/sdcard/android/layout_tests/fast/forms/button-state-restore.html : different length
-/sdcard/android/layout_tests/fast/forms/access-key.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-scrolled-endline-caret.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-type-spaces.html : different length
-/sdcard/android/layout_tests/fast/forms/slider-mouse-events.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-selection-preservation.html : different length
-/sdcard/android/layout_tests/fast/forms/slider-onchange-event.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-appearance-wrap.html : different length
-/sdcard/android/layout_tests/fast/forms/onselect-textarea.html : different length
-/sdcard/android/layout_tests/fast/forms/textarea-initial-caret-position.html : different length
-/sdcard/android/layout_tests/fast/forms/listbox-selection.html : different length
-/sdcard/android/layout_tests/fast/css/variables/color-hex-test.html : different length
-/sdcard/android/layout_tests/fast/css/dashboard-region-parser.html : different length
-/sdcard/android/layout_tests/fast/css/hover-affects-child.html : different length
-/sdcard/android/layout_tests/fast/css/html-attr-case-sensitivity.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/css/computed-style.html : different length
-/sdcard/android/layout_tests/fast/css/getComputedStyle-transform.html : different length
-/sdcard/android/layout_tests/fast/css/computed-style-without-renderer.html : different length
-/sdcard/android/layout_tests/fast/parser/entity-comment-in-iframe.html : @offset: 0
-/sdcard/android/layout_tests/fast/parser/external-entities.xml : different length
-/sdcard/android/layout_tests/fast/parser/script-tag-with-trailing-slash.html : different length
-/sdcard/android/layout_tests/fast/parser/comment-in-iframe.html : @offset: 0
-/sdcard/android/layout_tests/fast/parser/xml-declaration-missing-ending-mark.html : different length
-/sdcard/android/layout_tests/fast/parser/entity-end-script-tag.html : different length
-/sdcard/android/layout_tests/fast/parser/tabindex-parsing.html : different length
-/sdcard/android/layout_tests/fast/history/subframe-is-visited.html : different length
-/sdcard/android/layout_tests/fast/history/window-open.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/history/go-back-to-changed-name.html : different length
-/sdcard/android/layout_tests/fast/loader/cancel-load-during-port-block-timer.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/loader/local-iFrame-source-from-local.html : different length
-/sdcard/android/layout_tests/fast/loader/null-request-after-willSendRequest.html : different length
-/sdcard/android/layout_tests/fast/loader/stop-provisional-loads.html : different length
-/sdcard/android/layout_tests/fast/loader/xmlhttprequest-missing-file-exception.html : different length
-/sdcard/android/layout_tests/fast/loader/onunload-form-submit-crash-2.html : different length
-/sdcard/android/layout_tests/fast/loader/plain-text-document.html : different length
-/sdcard/android/layout_tests/fast/loader/onunload-form-submit-crash.html : different length
-/sdcard/android/layout_tests/fast/loader/local-image-from-local.html : different length
-/sdcard/android/layout_tests/fast/loader/local-CSS-from-local.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/loader/local-JavaScript-from-local.html : different length
-/sdcard/android/layout_tests/fast/loader/data-url-encoding-svg.html : different length
-/sdcard/android/layout_tests/fast/loader/opaque-base-url.html : @offset: 129
-/sdcard/android/layout_tests/fast/canvas/canvas-alphaImageData-behavior.html : different length
-/sdcard/android/layout_tests/fast/canvas/pointInPath.html : different length
-/sdcard/android/layout_tests/fast/canvas/toDataURL-supportedTypes.html : different length
-/sdcard/android/layout_tests/fast/canvas/canvas-getImageData.html : different length
-/sdcard/android/layout_tests/fast/canvas/canvas-longlived-context.html : TIMEDOUT
-/sdcard/android/layout_tests/fast/canvas/canvas-save-restore-with-path.html : different length
-/sdcard/android/layout_tests/fast/canvas/set-colors.html : different length
-/sdcard/android/layout_tests/fast/frames/viewsource-empty-attribute-value.html : different length
-/sdcard/android/layout_tests/fast/frames/frame-deep-nested-resize.html : different length
-/sdcard/android/layout_tests/fast/frames/iframe-window-focus.html : different length
-/sdcard/android/layout_tests/fast/frames/frameElement-widthheight.html : different length
-/sdcard/android/layout_tests/fast/frames/removal-before-attach-crash.html : different length
-/sdcard/android/layout_tests/fast/frames/frame-js-url-clientWidth.html : different length
+/sdcard/android/layout_tests/webarchive/loading/test-loading-archive.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement16.html
+/sdcard/android/layout_tests/media/video-error-does-not-exist.html
+/sdcard/android/layout_tests/media/audio-constructor.html
+/sdcard/android/layout_tests/media/video-start.html
+/sdcard/android/layout_tests/media/video-loopend.html
+/sdcard/android/layout_tests/media/video-play-empty-events.html
+/sdcard/android/layout_tests/media/constructors.html
+/sdcard/android/layout_tests/media/video-append-source.html
+/sdcard/android/layout_tests/media/unsupported-rtsp.html
+/sdcard/android/layout_tests/media/video-dom-autoplay.html
+/sdcard/android/layout_tests/media/video-currentTime-set2.html
+/sdcard/android/layout_tests/media/video-poster.html
+/sdcard/android/layout_tests/media/video-source-media.html
+/sdcard/android/layout_tests/media/video-muted.html
+/sdcard/android/layout_tests/media/progress-event.html
+/sdcard/android/layout_tests/media/video-source-type.html
+/sdcard/android/layout_tests/media/video-seek-past-end-playing.html
+/sdcard/android/layout_tests/media/video-dom-src.html
+/sdcard/android/layout_tests/media/remove-from-document.html
+/sdcard/android/layout_tests/media/video-end.html
+/sdcard/android/layout_tests/media/video-src-change.html
+/sdcard/android/layout_tests/media/video-seekable.html
+/sdcard/android/layout_tests/media/video-click-dblckick-standalone.html
+/sdcard/android/layout_tests/media/video-src-set.html
+/sdcard/android/layout_tests/media/video-seeking.html
+/sdcard/android/layout_tests/media/video-controls-transformed.html
+/sdcard/android/layout_tests/media/loopend-limits.html
+/sdcard/android/layout_tests/media/video-volume.html
+/sdcard/android/layout_tests/media/video-size.html
+/sdcard/android/layout_tests/media/video-width-height.html
+/sdcard/android/layout_tests/media/video-loopstart.html
+/sdcard/android/layout_tests/media/video-source.html
+/sdcard/android/layout_tests/media/video-currentTime.html
+/sdcard/android/layout_tests/media/video-dom-loopstart.html
+/sdcard/android/layout_tests/media/broken-video.html
+/sdcard/android/layout_tests/media/video-buffered.html
+/sdcard/android/layout_tests/media/video-load-readyState.html
+/sdcard/android/layout_tests/media/video-dom-end.html
+/sdcard/android/layout_tests/media/fallback.html
+/sdcard/android/layout_tests/media/video-load-networkState.html
+/sdcard/android/layout_tests/media/unsupported-tracks.html
+/sdcard/android/layout_tests/media/video-dom-start.html
+/sdcard/android/layout_tests/media/video-seek-past-end-paused.html
+/sdcard/android/layout_tests/media/video-play-pause-events.html
+/sdcard/android/layout_tests/media/video-autoplay.html
+/sdcard/android/layout_tests/media/video-controls.html
+/sdcard/android/layout_tests/media/loopstart-limits.html
+/sdcard/android/layout_tests/media/video-src-source.html
+/sdcard/android/layout_tests/media/video-currentTime-set.html
+/sdcard/android/layout_tests/media/video-source-type-params.html
+/sdcard/android/layout_tests/media/video-no-autoplay.html
+/sdcard/android/layout_tests/media/video-pause-empty-events.html
+/sdcard/android/layout_tests/media/video-play-pause-exception.html
+/sdcard/android/layout_tests/media/video-dom-loopend.html
+/sdcard/android/layout_tests/media/video-loopcount.html
+/sdcard/android/layout_tests/media/video-src-remove.html
+/sdcard/android/layout_tests/media/video-src.html
+/sdcard/android/layout_tests/media/video-error-abort.html
+/sdcard/android/layout_tests/media/video-dom-loopcount.html
+/sdcard/android/layout_tests/media/progress-event-total.html
+/sdcard/android/layout_tests/media/audio-constructor-src.html
+/sdcard/android/layout_tests/plugins/throw-on-dealloc.html
+/sdcard/android/layout_tests/plugins/invoke.html
+/sdcard/android/layout_tests/plugins/plugin-remove-subframe.html
+/sdcard/android/layout_tests/plugins/netscape-identifier-conversion.html
+/sdcard/android/layout_tests/plugins/call-as-function-test.html
+/sdcard/android/layout_tests/plugins/npruntime.html
+/sdcard/android/layout_tests/plugins/netscape-construct.html
+/sdcard/android/layout_tests/plugins/root-object-premature-delete-crash.html
+/sdcard/android/layout_tests/plugins/netscape-get-property-return-value.html
+/sdcard/android/layout_tests/plugins/mouse-events.html
+/sdcard/android/layout_tests/plugins/return-error-from-new-stream-doesnt-invoke-destroy-stream.html
+/sdcard/android/layout_tests/plugins/destroy-stream-twice.html
+/sdcard/android/layout_tests/plugins/jsobjc-simple.html
+/sdcard/android/layout_tests/plugins/embed-attributes-setting.html
+/sdcard/android/layout_tests/plugins/inner-html-display-none.html
+/sdcard/android/layout_tests/plugins/netscape-invoke-default.html
+/sdcard/android/layout_tests/plugins/undefined-property-crash.html
+/sdcard/android/layout_tests/plugins/netscape-plugin-setwindow-size-2.html
+/sdcard/android/layout_tests/plugins/jsobjc-dom-wrappers.html
+/sdcard/android/layout_tests/plugins/plugin-javascript-access.html
+/sdcard/android/layout_tests/plugins/getintidentifier-special-values.html
+/sdcard/android/layout_tests/plugins/geturl-replace-query.html
+/sdcard/android/layout_tests/plugins/netscape-destroy-plugin-script-objects.html
+/sdcard/android/layout_tests/plugins/open-and-close-window-with-plugin.html
+/sdcard/android/layout_tests/plugins/netscape-enumerate.html
+/sdcard/android/layout_tests/plugins/get-url-that-the-resource-load-delegate-will-disallow.html
+/sdcard/android/layout_tests/plugins/netscape-plugin-setwindow-size.html
+/sdcard/android/layout_tests/plugins/embed-inside-object.html
+/sdcard/android/layout_tests/plugins/netscape-throw-exception.html
+/sdcard/android/layout_tests/plugins/get-url-with-blank-target.html
+/sdcard/android/layout_tests/plugins/bindings-test.html
+/sdcard/android/layout_tests/editing/input/textarea-arrow-navigation.html
+/sdcard/android/layout_tests/editing/inserting/typing-tab-designmode.html
+/sdcard/android/layout_tests/editing/inserting/5994480-2.html
+/sdcard/android/layout_tests/editing/execCommand/queryCommandState-01.html
+/sdcard/android/layout_tests/editing/execCommand/5543472-3.html
+/sdcard/android/layout_tests/editing/execCommand/enabling-and-selection.html
+/sdcard/android/layout_tests/editing/execCommand/5658933-2.html
+/sdcard/android/layout_tests/editing/execCommand/insert-line-break-no-scroll.html
+/sdcard/android/layout_tests/editing/execCommand/enabling-and-selection-2.html
+/sdcard/android/layout_tests/editing/execCommand/delete-no-scroll.html
+/sdcard/android/layout_tests/editing/execCommand/forward-delete-no-scroll.html
+/sdcard/android/layout_tests/editing/execCommand/19089.html
+/sdcard/android/layout_tests/editing/execCommand/unlink.html
+/sdcard/android/layout_tests/editing/execCommand/5543472-2.html
+/sdcard/android/layout_tests/editing/execCommand/copy-without-selection.html
+/sdcard/android/layout_tests/editing/execCommand/findString-diacriticals.html
+/sdcard/android/layout_tests/editing/execCommand/5658933-3.html
+/sdcard/android/layout_tests/editing/execCommand/createLink.html
+/sdcard/android/layout_tests/editing/execCommand/5543472-1.html
+/sdcard/android/layout_tests/editing/execCommand/5939887.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-into-anchor-text.html
+/sdcard/android/layout_tests/editing/pasteboard/copy-crash.html
+/sdcard/android/layout_tests/editing/pasteboard/5665299.html
+/sdcard/android/layout_tests/editing/pasteboard/5761530-1.html
+/sdcard/android/layout_tests/editing/pasteboard/copy-in-password-field.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-plaintext-user-select-none.html
+/sdcard/android/layout_tests/editing/pasteboard/drag-image-in-about-blank-frame.html
+/sdcard/android/layout_tests/editing/pasteboard/4744008.html
+/sdcard/android/layout_tests/editing/pasteboard/4922709.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-013.html
+/sdcard/android/layout_tests/editing/pasteboard/5780697-2.html
+/sdcard/android/layout_tests/editing/pasteboard/4840662.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-table-002.html
+/sdcard/android/layout_tests/editing/selection/drag-text-delay.html
+/sdcard/android/layout_tests/editing/selection/skip-non-editable-1.html
+/sdcard/android/layout_tests/editing/selection/move-by-line-003.html
+/sdcard/android/layout_tests/editing/selection/anchor-focus1.html
+/sdcard/android/layout_tests/editing/selection/getRangeAt.html
+/sdcard/android/layout_tests/editing/selection/select-all-textarea.html
+/sdcard/android/layout_tests/editing/selection/doubleclick-whitespace.html
+/sdcard/android/layout_tests/editing/selection/after-line-break.html
+/sdcard/android/layout_tests/editing/selection/legal-positions.html
+/sdcard/android/layout_tests/editing/selection/anchor-focus3.html
+/sdcard/android/layout_tests/editing/selection/toString.html
+/sdcard/android/layout_tests/editing/selection/extend-selection-bidi.html
+/sdcard/android/layout_tests/editing/selection/inactive-selection.html
+/sdcard/android/layout_tests/editing/selection/removeAllRanges.html
+/sdcard/android/layout_tests/editing/selection/5209984.html
+/sdcard/android/layout_tests/editing/selection/skip-non-editable-2.html
+/sdcard/android/layout_tests/editing/selection/toString-1.html
+/sdcard/android/layout_tests/editing/selection/anchor-focus2.html
+/sdcard/android/layout_tests/editing/selection/move-begin-end.html
+/sdcard/android/layout_tests/editing/selection/move-left-right.html
+/sdcard/android/layout_tests/editing/selection/click-before-and-after-table.html
+/sdcard/android/layout_tests/editing/undo/undo-iframe-location-change.html
+/sdcard/android/layout_tests/editing/deleting/pruning-after-merge-1.html
+/sdcard/android/layout_tests/editing/deleting/5546763.html
+/sdcard/android/layout_tests/editing/deleting/5729680.html
+/sdcard/android/layout_tests/editing/deleting/4916235-1.html
+/sdcard/android/layout_tests/editing/deleting/delete-ligature-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-ligature-003.html
+/sdcard/android/layout_tests/editing/deleting/5890684.html
+/sdcard/android/layout_tests/editing/deleting/smart-editing-disabled.html
+/sdcard/android/layout_tests/editing/deleting/delete-ligature-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-all-text-in-text-field-assertion.html
+/sdcard/android/layout_tests/accessibility/image-map1.html
+/sdcard/android/layout_tests/accessibility/aria-labelledby-on-input.html
+/sdcard/android/layout_tests/accessibility/content-editable.html
+/sdcard/android/layout_tests/accessibility/frame-with-title.html
+/sdcard/android/layout_tests/accessibility/textarea-insertion-point-line-number.html
+/sdcard/android/layout_tests/accessibility/table-with-rules.html
+/sdcard/android/layout_tests/accessibility/aria-describedby-on-input.html
+/sdcard/android/layout_tests/accessibility/radio-button-checkbox-size.html
+/sdcard/android/layout_tests/accessibility/table-detection.html
+/sdcard/android/layout_tests/accessibility/th-as-title-ui.html
+/sdcard/android/layout_tests/accessibility/table-with-aria-role.html
+/sdcard/android/layout_tests/accessibility/accesskey.html
+/sdcard/android/layout_tests/accessibility/image-map2.html
+/sdcard/android/layout_tests/accessibility/iframe-bastardization.html
+/sdcard/android/layout_tests/accessibility/aria-spinbutton.html
+/sdcard/android/layout_tests/accessibility/button-press-action.html
+/sdcard/android/layout_tests/accessibility/table-cell-spans.html
+/sdcard/android/layout_tests/accessibility/table-cells.html
+/sdcard/android/layout_tests/accessibility/double-title.html
+/sdcard/android/layout_tests/accessibility/lists.html
+/sdcard/android/layout_tests/accessibility/plugin.html
+/sdcard/android/layout_tests/accessibility/table-sections.html
+/sdcard/android/layout_tests/accessibility/textarea-selected-text-range.html
+/sdcard/android/layout_tests/accessibility/input-image-url.html
+/sdcard/android/layout_tests/accessibility/aria-range-value.html
+/sdcard/android/layout_tests/accessibility/table-one-cell.html
+/sdcard/android/layout_tests/accessibility/internal-link-anchors2.html
+/sdcard/android/layout_tests/accessibility/table-nofirstbody.html
+/sdcard/android/layout_tests/accessibility/table-modification-crash.html
+/sdcard/android/layout_tests/accessibility/radio-button-group-members.html
+/sdcard/android/layout_tests/accessibility/aria-link-supports-press.html
+/sdcard/android/layout_tests/accessibility/document-attributes.html
+/sdcard/android/layout_tests/accessibility/table-notbody.html
+/sdcard/android/layout_tests/accessibility/aria-range.html
+/sdcard/android/layout_tests/accessibility/bounds-for-range.html
+/sdcard/android/layout_tests/accessibility/table-attributes.html
+/sdcard/android/layout_tests/accessibility/textarea-line-for-index.html
+/sdcard/android/layout_tests/accessibility/aria-slider.html
+/sdcard/android/layout_tests/accessibility/document-links.html
+/sdcard/android/layout_tests/accessibility/legend.html
+/sdcard/android/layout_tests/accessibility/aria-roles.html
+/sdcard/android/layout_tests/accessibility/nochildren-elements.html
+/sdcard/android/layout_tests/accessibility/internal-link-anchors.html
+/sdcard/android/layout_tests/fast/replaced/image-map-bug16782.html
+/sdcard/android/layout_tests/fast/replaced/table-percent-height.html
+/sdcard/android/layout_tests/fast/replaced/image-map.html
+/sdcard/android/layout_tests/fast/dynamic/paused-event-dispatch.html
+/sdcard/android/layout_tests/fast/text/plain-text-line-breaks.html
+/sdcard/android/layout_tests/fast/text/zero-width-characters.html
+/sdcard/android/layout_tests/fast/text/reset-drag-on-mouse-down.html
+/sdcard/android/layout_tests/fast/encoding/invalid-xml.html
+/sdcard/android/layout_tests/fast/encoding/char-decoding-mac.html
+/sdcard/android/layout_tests/fast/encoding/frame-default-enc.html
+/sdcard/android/layout_tests/fast/encoding/mailto-always-utf-8.html
+/sdcard/android/layout_tests/fast/encoding/char-decoding.html
+/sdcard/android/layout_tests/fast/encoding/url-host-name-non-ascii.html
+/sdcard/android/layout_tests/fast/encoding/idn-security.html
+/sdcard/android/layout_tests/fast/encoding/percent-escaping.html
+/sdcard/android/layout_tests/fast/encoding/xml-utf-8-default.xml
+/sdcard/android/layout_tests/fast/encoding/char-encoding-mac.html
+/sdcard/android/layout_tests/fast/encoding/yahoo-mail.html
+/sdcard/android/layout_tests/fast/encoding/charset-koi8-u.html
+/sdcard/android/layout_tests/fast/encoding/ahram-org-eg.html
+/sdcard/android/layout_tests/fast/encoding/noscript-in-head.html
+/sdcard/android/layout_tests/fast/workers/worker-location.html
+/sdcard/android/layout_tests/fast/workers/worker-constructor.html
+/sdcard/android/layout_tests/fast/workers/stress-js-execution.html
+/sdcard/android/layout_tests/fast/workers/worker-terminate.html
+/sdcard/android/layout_tests/fast/workers/worker-gc.html
+/sdcard/android/layout_tests/fast/workers/worker-navigator.html
+/sdcard/android/layout_tests/fast/workers/worker-replace-global-constructor.html
+/sdcard/android/layout_tests/fast/workers/worker-replace-self.html
+/sdcard/android/layout_tests/fast/workers/worker-event-listener.html
+/sdcard/android/layout_tests/fast/selectors/lang-inheritance.html
+/sdcard/android/layout_tests/fast/selectors/lang-vs-xml-lang.html
+/sdcard/android/layout_tests/fast/selectors/lang-inheritance2.html
+/sdcard/android/layout_tests/fast/overflow/scroll-vertical-not-horizontal.html
+/sdcard/android/layout_tests/fast/events/onunload.html
+/sdcard/android/layout_tests/fast/events/mouseup-outside-document.html
+/sdcard/android/layout_tests/fast/events/offsetX-offsetY.html
+/sdcard/android/layout_tests/fast/events/scroll-event-does-not-bubble.html
+/sdcard/android/layout_tests/fast/events/mouseover-mouseout.html
+/sdcard/android/layout_tests/fast/events/option-tab.html
+/sdcard/android/layout_tests/fast/events/popup-blocking-click-in-iframe.html
+/sdcard/android/layout_tests/fast/events/tabindex-focus-blur-all.html
+/sdcard/android/layout_tests/fast/events/onchange-passwordfield.html
+/sdcard/android/layout_tests/fast/events/drag-in-frames.html
+/sdcard/android/layout_tests/fast/events/frame-tab-focus.html
+/sdcard/android/layout_tests/fast/events/autoscroll-in-textfield.html
+/sdcard/android/layout_tests/fast/events/arrow-navigation.html
+/sdcard/android/layout_tests/fast/events/fire-scroll-event.html
+/sdcard/android/layout_tests/fast/events/attempt-scroll-with-no-scrollbars.html
+/sdcard/android/layout_tests/fast/events/mouseclick-target-and-positioning.html
+/sdcard/android/layout_tests/fast/events/keydown-keypress-focus-change.html
+/sdcard/android/layout_tests/fast/events/input-image-scrolled-x-y.html
+/sdcard/android/layout_tests/fast/events/dblclick-addEventListener.html
+/sdcard/android/layout_tests/fast/events/frame-programmatic-focus.html
+/sdcard/android/layout_tests/fast/events/context-onmousedown-event.html
+/sdcard/android/layout_tests/fast/events/content-changed-during-drop.html
+/sdcard/android/layout_tests/fast/events/autoscroll-with-non-scrollable-parent.html
+/sdcard/android/layout_tests/fast/events/window-events-capture.html
+/sdcard/android/layout_tests/fast/events/onchange-click-hang.html
+/sdcard/android/layout_tests/fast/events/onload-webkit-before-webcore.html
+/sdcard/android/layout_tests/fast/events/window-events-bubble2.html
+/sdcard/android/layout_tests/fast/events/js-keyboard-event-creation.html
+/sdcard/android/layout_tests/fast/events/event-view-toString.html
+/sdcard/android/layout_tests/fast/events/onchange-select-popup.html
+/sdcard/android/layout_tests/fast/events/access-key-self-destruct.html
+/sdcard/android/layout_tests/fast/events/scrollbar-double-click.html
+/sdcard/android/layout_tests/fast/events/onunload-clears-onbeforeunload.html
+/sdcard/android/layout_tests/fast/events/tabindex-focus-chain.html
+/sdcard/android/layout_tests/fast/events/capture-on-target.html
+/sdcard/android/layout_tests/fast/events/window-events-bubble.html
+/sdcard/android/layout_tests/fast/events/mouseup-from-button2.html
+/sdcard/android/layout_tests/fast/events/frame-click-focus.html
+/sdcard/android/layout_tests/fast/events/mouseout-on-window.html
+/sdcard/android/layout_tests/fast/events/keypress-insert-tab.html
+/sdcard/android/layout_tests/fast/events/mouseout-dead-subframe.html
+/sdcard/android/layout_tests/fast/events/iframe-object-onload.html
+/sdcard/android/layout_tests/fast/events/onunload-not-on-body.html
+/sdcard/android/layout_tests/fast/events/mousemove-after-drag-over-scrollbar.html
+/sdcard/android/layout_tests/fast/events/contextmenu-scrolled-page-with-frame.html
+/sdcard/android/layout_tests/fast/events/key-events-in-input-button.html
+/sdcard/android/layout_tests/fast/events/arrow-keys-on-body.html
+/sdcard/android/layout_tests/fast/events/ondragenter.html
+/sdcard/android/layout_tests/fast/events/pointer-events.html
+/sdcard/android/layout_tests/fast/events/scroll-to-anchor-in-overflow-hidden.html
+/sdcard/android/layout_tests/fast/events/autoscroll-nonscrollable-iframe-in-scrollable-div.html
+/sdcard/android/layout_tests/fast/events/keypress-focus-change.html
+/sdcard/android/layout_tests/fast/events/key-events-in-input-text.html
+/sdcard/android/layout_tests/fast/events/pointer-events-2.html
+/sdcard/android/layout_tests/fast/events/drag-outside-window.html
+/sdcard/android/layout_tests/fast/events/click-count.html
+/sdcard/android/layout_tests/fast/events/onchange-searchfield.html
+/sdcard/android/layout_tests/fast/events/special-key-events-in-input-text.html
+/sdcard/android/layout_tests/fast/events/keydown-keypress-preventDefault.html
+/sdcard/android/layout_tests/fast/events/mouse-click-events.html
+/sdcard/android/layout_tests/fast/events/onsearch-enter.html
+/sdcard/android/layout_tests/fast/events/mouseover-mouseout2.html
+/sdcard/android/layout_tests/fast/events/open-window-from-another-frame.html
+/sdcard/android/layout_tests/fast/events/init-events.html
+/sdcard/android/layout_tests/fast/events/onchange-textfield.html
+/sdcard/android/layout_tests/fast/events/onclick-list-marker.html
+/sdcard/android/layout_tests/fast/events/anchor-image-scrolled-x-y.html
+/sdcard/android/layout_tests/fast/html/tab-order.html
+/sdcard/android/layout_tests/fast/regex/test1.html
+/sdcard/android/layout_tests/fast/js/kde/garbage-n.html
+/sdcard/android/layout_tests/fast/js/kde/Number.html
+/sdcard/android/layout_tests/fast/js/kde/string-2-n.html
+/sdcard/android/layout_tests/fast/js/kde/encode_decode_uri.html
+/sdcard/android/layout_tests/fast/js/kde/string-1-n.html
+/sdcard/android/layout_tests/fast/js/exception-sequencing-binops.html
+/sdcard/android/layout_tests/fast/js/recursion-limit-equal.html
+/sdcard/android/layout_tests/fast/js/exception-sequencing-binops2.html
+/sdcard/android/layout_tests/fast/js/math-transforms.html
+/sdcard/android/layout_tests/fast/js/try-catch-crash.html
+/sdcard/android/layout_tests/fast/js/array-iterate-backwards.html
+/sdcard/android/layout_tests/fast/js/navigator-mimeTypes-length.html
+/sdcard/android/layout_tests/fast/js/global-constructors.html
+/sdcard/android/layout_tests/fast/js/uncaught-exception-line-number.html
+/sdcard/android/layout_tests/fast/js/exceptions-thrown-in-callbacks.html
+/sdcard/android/layout_tests/fast/js/toString-and-valueOf-override.html
+/sdcard/android/layout_tests/fast/js/function-toString-parentheses.html
+/sdcard/android/layout_tests/fast/js/large-expressions.html
+/sdcard/android/layout_tests/fast/js/exception-sequencing.html
+/sdcard/android/layout_tests/fast/js/exception-codegen-crash.html
+/sdcard/android/layout_tests/fast/dom/HTMLDocument/activeElement.html
+/sdcard/android/layout_tests/fast/dom/HTMLDocument/document-special-properties.html
+/sdcard/android/layout_tests/fast/dom/HTMLDocument/url-getset.html
+/sdcard/android/layout_tests/fast/dom/HTMLDocument/hasFocus.html
+/sdcard/android/layout_tests/fast/dom/HTMLSelectElement/listbox-select-reset.html
+/sdcard/android/layout_tests/fast/dom/Document/early-document-access.html
+/sdcard/android/layout_tests/fast/dom/Element/offsetLeft-offsetTop-body-quirk.html
+/sdcard/android/layout_tests/fast/dom/DOMException/XPathException.html
+/sdcard/android/layout_tests/fast/dom/getElementsByClassName/010.xml
+/sdcard/android/layout_tests/fast/dom/getElementsByClassName/011.xml
+/sdcard/android/layout_tests/fast/dom/Window/window-resize-and-move-arguments.html
+/sdcard/android/layout_tests/fast/dom/Window/timeout-released-on-close.html
+/sdcard/android/layout_tests/fast/dom/Window/window-function-name-getter-precedence.html
+/sdcard/android/layout_tests/fast/dom/Window/window-xy-properties.html
+/sdcard/android/layout_tests/fast/dom/Window/console-functions.html
+/sdcard/android/layout_tests/fast/dom/Window/window-screen-properties.html
+/sdcard/android/layout_tests/fast/dom/Window/window-properties.html
+/sdcard/android/layout_tests/fast/dom/Window/window-onFocus.html
+/sdcard/android/layout_tests/fast/dom/Window/new-window-opener.html
+/sdcard/android/layout_tests/fast/dom/Window/window-open-pending-url.html
+/sdcard/android/layout_tests/fast/dom/Window/setting-properties-on-closed-window.html
+/sdcard/android/layout_tests/fast/dom/Window/dom-access-from-closure-window.html
+/sdcard/android/layout_tests/fast/dom/Window/window-resize.html
+/sdcard/android/layout_tests/fast/dom/Window/closure-access-after-navigation-window.html
+/sdcard/android/layout_tests/fast/dom/Window/window-special-properties.html
+/sdcard/android/layout_tests/fast/dom/Window/dom-access-from-closure-iframe.html
+/sdcard/android/layout_tests/fast/dom/Window/Plug-ins.html
+/sdcard/android/layout_tests/fast/dom/Window/get-set-properties.html
+/sdcard/android/layout_tests/fast/dom/Window/window-scroll-arguments.html
+/sdcard/android/layout_tests/fast/dom/Window/window-early-properties.html
+/sdcard/android/layout_tests/fast/dom/StyleSheet/ownerNode-lifetime-2.html
+/sdcard/android/layout_tests/fast/dom/dom-constructors.html
+/sdcard/android/layout_tests/fast/dom/assign-to-window-status.html
+/sdcard/android/layout_tests/fast/dom/gc-8.html
+/sdcard/android/layout_tests/fast/dom/object-embed-plugin-scripting.html
+/sdcard/android/layout_tests/fast/dom/node-filter-gc.html
+/sdcard/android/layout_tests/fast/dom/noscript-canvas-in-created-html-document.html
+/sdcard/android/layout_tests/fast/dom/DOMParser-assign-variable.html
+/sdcard/android/layout_tests/fast/dom/timer-clear-interval-in-handler.html
+/sdcard/android/layout_tests/fast/dom/implementation-createHTMLDocument.html
+/sdcard/android/layout_tests/fast/dom/iframe-document.html
+/sdcard/android/layout_tests/fast/dom/document-all-input.html
+/sdcard/android/layout_tests/fast/dom/null-document-location-href-put-crash.html
+/sdcard/android/layout_tests/fast/dom/getelementsbytagnamens-mixed-namespaces.html
+/sdcard/android/layout_tests/fast/dom/object-plugin-hides-properties.html
+/sdcard/android/layout_tests/fast/dom/gc-2.html
+/sdcard/android/layout_tests/fast/dom/computed-style-set-property.html
+/sdcard/android/layout_tests/fast/dom/inner-text-001.html
+/sdcard/android/layout_tests/fast/dom/css-selectorText.html
+/sdcard/android/layout_tests/fast/dom/replace-first-child.html
+/sdcard/android/layout_tests/fast/dom/importNode-null.html
+/sdcard/android/layout_tests/fast/dom/select-selectedIndex-multiple.html
+/sdcard/android/layout_tests/fast/dom/gc-9.html
+/sdcard/android/layout_tests/fast/dom/NamedNodeMap-setNamedItem-crash.html
+/sdcard/android/layout_tests/fast/dom/wrapper-classes.html
+/sdcard/android/layout_tests/fast/dom/select-selectedIndex.html
+/sdcard/android/layout_tests/fast/dom/document-width-height-force-layout.html
+/sdcard/android/layout_tests/fast/dom/gc-acid3.html
+/sdcard/android/layout_tests/fast/dom/client-width-height.html
+/sdcard/android/layout_tests/fast/dom/global-constructors.html
+/sdcard/android/layout_tests/fast/dom/client-width-height-quirks.html
+/sdcard/android/layout_tests/fast/dom/javascript-url-crash-function.html
+/sdcard/android/layout_tests/fast/dom/location-hash.html
+/sdcard/android/layout_tests/fast/dom/constructors-cached.html
+/sdcard/android/layout_tests/fast/dom/non-numeric-values-numeric-parameters.html
+/sdcard/android/layout_tests/fast/dom/documenturi-can-hold-arbitrary-string.html
+/sdcard/android/layout_tests/fast/dom/documenturi-not-affected-by-base-tag.html
+/sdcard/android/layout_tests/fast/dom/open-and-close-by-DOM.html
+/sdcard/android/layout_tests/fast/dom/set-frame-src-while-running-script-in-frame.html
+/sdcard/android/layout_tests/fast/dom/document_write_params.html
+/sdcard/android/layout_tests/fast/dom/namednodemap-namelookup.html
+/sdcard/android/layout_tests/fast/dom/null-document-location-replace-crash.html
+/sdcard/android/layout_tests/fast/dom/htmlcollection-detectability.html
+/sdcard/android/layout_tests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html
+/sdcard/android/layout_tests/fast/dom/collection-namedItem-via-item.html
+/sdcard/android/layout_tests/fast/dom/set-inner-text-newlines.html
+/sdcard/android/layout_tests/fast/dom/document-dir-property.html
+/sdcard/android/layout_tests/fast/dom/undetectable-style-filter.html
+/sdcard/android/layout_tests/fast/dom/tabindex-clamp.html
+/sdcard/android/layout_tests/fast/dom/constructors-cached-navigate.html
+/sdcard/android/layout_tests/fast/dom/frame-loading-via-document-write.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/od_20000608.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/namespace-nodes.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/rs_20010831.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/sr_20021217.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/kd_20010423.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Borrowed/cz_20030217.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_boolean_expr.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_core_functions.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_location_path.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_node_test.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_literal_expr.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_predicate_list.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_parser.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_nodeset_expr.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_numeric_expr.html
+/sdcard/android/layout_tests/fast/xpath/4XPath/Core/test_step.html
+/sdcard/android/layout_tests/fast/xpath/ancestor-axis.html
+/sdcard/android/layout_tests/fast/xpath/string-value.html
+/sdcard/android/layout_tests/fast/xpath/name-null-namespace.html
+/sdcard/android/layout_tests/fast/xpath/id-simple.html
+/sdcard/android/layout_tests/fast/xpath/id-path.html
+/sdcard/android/layout_tests/fast/xpath/implicit-node-args.html
+/sdcard/android/layout_tests/fast/xpath/text-nodes.html
+/sdcard/android/layout_tests/fast/xpath/invalid-functions.html
+/sdcard/android/layout_tests/fast/xpath/xpath-namespaces.html
+/sdcard/android/layout_tests/fast/xpath/xpath-functional-test.html
+/sdcard/android/layout_tests/fast/xpath/complex-id.html
+/sdcard/android/layout_tests/fast/xpath/attr-namespace.html
+/sdcard/android/layout_tests/fast/xpath/substring-after.html
+/sdcard/android/layout_tests/fast/xpath/evaluate-twice.html
+/sdcard/android/layout_tests/fast/xpath/empty-string-substring.html
+/sdcard/android/layout_tests/fast/xpath/document-order.html
+/sdcard/android/layout_tests/fast/xpath/nodeset-duplicates.html
+/sdcard/android/layout_tests/fast/xpath/nan-to-boolean.html
+/sdcard/android/layout_tests/fast/xpath/reverse-axes.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-text-plain.html
+/sdcard/android/layout_tests/fast/forms/mailto/advanced-get.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-text-plain-latin-1.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-multipart-form-data.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii-always-utf-8.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-append-query.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items-x-www-form-urlencoded.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-overwrite-query.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-x-www-form-urlencoded.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-multiple-items-text-plain.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-multiple-items-text-plain.html
+/sdcard/android/layout_tests/fast/forms/mailto/get-non-ascii.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-text-plain-with-accept-charset.html
+/sdcard/android/layout_tests/fast/forms/mailto/post-text-plain.html
+/sdcard/android/layout_tests/fast/forms/mailto/advanced-put.html
+/sdcard/android/layout_tests/fast/forms/listbox-typeahead-scroll.html
+/sdcard/android/layout_tests/fast/forms/select-empty-list.html
+/sdcard/android/layout_tests/fast/forms/select-accesskey.html
+/sdcard/android/layout_tests/fast/forms/focus2.html
+/sdcard/android/layout_tests/fast/forms/password-doubleclick-selection.html
+/sdcard/android/layout_tests/fast/forms/textfield-inside-anchor.html
+/sdcard/android/layout_tests/fast/forms/textarea-trailing-newline.html
+/sdcard/android/layout_tests/fast/forms/legend-access-key.html
+/sdcard/android/layout_tests/fast/forms/input-maxlength.html
+/sdcard/android/layout_tests/fast/forms/selection-functions.html
+/sdcard/android/layout_tests/fast/forms/textfield-to-password-on-focus.html
+/sdcard/android/layout_tests/fast/forms/select-reset.html
+/sdcard/android/layout_tests/fast/forms/focus-selection-textarea.html
+/sdcard/android/layout_tests/fast/forms/enter-clicks-buttons.html
+/sdcard/android/layout_tests/fast/forms/radio_checked_name.html
+/sdcard/android/layout_tests/fast/forms/radio-check-click-and-drag.html
+/sdcard/android/layout_tests/fast/forms/select-double-onchange.html
+/sdcard/android/layout_tests/fast/forms/button-enter-click.html
+/sdcard/android/layout_tests/fast/forms/search-click-in-placeholder.html
+/sdcard/android/layout_tests/fast/forms/autofocus-opera-003.html
+/sdcard/android/layout_tests/fast/forms/search-hidden-cancel-button.html
+/sdcard/android/layout_tests/fast/forms/dragging-to-file-input.html
+/sdcard/android/layout_tests/fast/forms/textarea-paste-newline.html
+/sdcard/android/layout_tests/fast/forms/drag-into-textarea.html
+/sdcard/android/layout_tests/fast/forms/onselect-textfield.html
+/sdcard/android/layout_tests/fast/forms/input-implicit-length-limit.html
+/sdcard/android/layout_tests/fast/forms/form-and-frame-interaction-retains-values.html
+/sdcard/android/layout_tests/fast/forms/slider-transformed.html
+/sdcard/android/layout_tests/fast/forms/listbox-select-all.html
+/sdcard/android/layout_tests/fast/forms/textfield-onchange-deletion.html
+/sdcard/android/layout_tests/fast/forms/focus-control-to-page.html
+/sdcard/android/layout_tests/fast/forms/select-type-ahead-non-latin.html
+/sdcard/android/layout_tests/fast/forms/textarea-no-scroll-on-blur.html
+/sdcard/android/layout_tests/fast/forms/focus-selection-input.html
+/sdcard/android/layout_tests/fast/forms/listbox-onchange.html
+/sdcard/android/layout_tests/fast/forms/button-spacebar-click.html
+/sdcard/android/layout_tests/fast/forms/search-event-delay.html
+/sdcard/android/layout_tests/fast/forms/search-cancel-button-mouseup.html
+/sdcard/android/layout_tests/fast/forms/select-enter-key.html
+/sdcard/android/layout_tests/fast/forms/drag-out-of-textarea.html
+/sdcard/android/layout_tests/fast/forms/textarea-hard-linewrap.html
+/sdcard/android/layout_tests/fast/forms/dragging-to-disabled-file-input.html
+/sdcard/android/layout_tests/fast/forms/input-radio-checked-tab.html
+/sdcard/android/layout_tests/fast/forms/plaintext-mode-1.html
+/sdcard/android/layout_tests/fast/forms/check-box-enter-key.html
+/sdcard/android/layout_tests/fast/forms/input-select-on-click.html
+/sdcard/android/layout_tests/fast/forms/button-state-restore.html
+/sdcard/android/layout_tests/fast/forms/input-appearance-elementFromPoint.html
+/sdcard/android/layout_tests/fast/forms/select-set-inner.html
+/sdcard/android/layout_tests/fast/forms/missing-action.html
+/sdcard/android/layout_tests/fast/forms/access-key.html
+/sdcard/android/layout_tests/fast/forms/textarea-scrolled-endline-caret.html
+/sdcard/android/layout_tests/fast/forms/textarea-scrollbar-height.html
+/sdcard/android/layout_tests/fast/forms/textarea-type-spaces.html
+/sdcard/android/layout_tests/fast/forms/slider-mouse-events.html
+/sdcard/android/layout_tests/fast/forms/textarea-selection-preservation.html
+/sdcard/android/layout_tests/fast/forms/slider-onchange-event.html
+/sdcard/android/layout_tests/fast/forms/add-remove-form-elements-stress-test.html
+/sdcard/android/layout_tests/fast/forms/onchange-enter-submit.html
+/sdcard/android/layout_tests/fast/forms/textarea-appearance-wrap.html
+/sdcard/android/layout_tests/fast/forms/willvalidate-006.html
+/sdcard/android/layout_tests/fast/forms/onselect-textarea.html
+/sdcard/android/layout_tests/fast/forms/textarea-initial-caret-position.html
+/sdcard/android/layout_tests/fast/forms/listbox-selection.html
+/sdcard/android/layout_tests/fast/css/variables/color-hex-test.html
+/sdcard/android/layout_tests/fast/css/dashboard-region-parser.html
+/sdcard/android/layout_tests/fast/css/text-align.html
+/sdcard/android/layout_tests/fast/css/hover-affects-child.html
+/sdcard/android/layout_tests/fast/css/html-attr-case-sensitivity.html
+/sdcard/android/layout_tests/fast/css/computed-style.html
+/sdcard/android/layout_tests/fast/css/getComputedStyle-transform.html
+/sdcard/android/layout_tests/fast/css/computed-style-without-renderer.html
+/sdcard/android/layout_tests/fast/css/invalid-percentage-property.html
+/sdcard/android/layout_tests/fast/parser/entity-comment-in-iframe.html
+/sdcard/android/layout_tests/fast/parser/external-entities.xml
+/sdcard/android/layout_tests/fast/parser/script-tag-with-trailing-slash.html
+/sdcard/android/layout_tests/fast/parser/comment-in-iframe.html
+/sdcard/android/layout_tests/fast/parser/external-entities-in-xslt.xml
+/sdcard/android/layout_tests/fast/parser/xml-declaration-missing-ending-mark.html
+/sdcard/android/layout_tests/fast/parser/entity-end-script-tag.html
+/sdcard/android/layout_tests/fast/parser/tabindex-parsing.html
+/sdcard/android/layout_tests/fast/history/subframe-is-visited.html
+/sdcard/android/layout_tests/fast/history/window-open.html
+/sdcard/android/layout_tests/fast/history/history_reload.html
+/sdcard/android/layout_tests/fast/history/go-back-to-changed-name.html
+/sdcard/android/layout_tests/fast/loader/cancel-load-during-port-block-timer.html
+/sdcard/android/layout_tests/fast/loader/local-iFrame-source-from-local.html
+/sdcard/android/layout_tests/fast/loader/null-request-after-willSendRequest.html
+/sdcard/android/layout_tests/fast/loader/stop-provisional-loads.html
+/sdcard/android/layout_tests/fast/loader/xmlhttprequest-missing-file-exception.html
+/sdcard/android/layout_tests/fast/loader/onunload-form-submit-crash-2.html
+/sdcard/android/layout_tests/fast/loader/plain-text-document.html
+/sdcard/android/layout_tests/fast/loader/onunload-form-submit-crash.html
+/sdcard/android/layout_tests/fast/loader/frame-creation-removal.html
+/sdcard/android/layout_tests/fast/loader/local-image-from-local.html
+/sdcard/android/layout_tests/fast/loader/local-CSS-from-local.html
+/sdcard/android/layout_tests/fast/loader/local-JavaScript-from-local.html
+/sdcard/android/layout_tests/fast/loader/data-url-encoding-svg.html
+/sdcard/android/layout_tests/fast/loader/opaque-base-url.html
+/sdcard/android/layout_tests/fast/xsl/sort-locale.xml
+/sdcard/android/layout_tests/fast/xsl/transformToFragment-XML-declaration.html
+/sdcard/android/layout_tests/fast/xsl/extra-lf-at-end.html
+/sdcard/android/layout_tests/fast/xsl/xslt-doc-noenc.xml
+/sdcard/android/layout_tests/fast/xsl/import-after-comment.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-processor.html
+/sdcard/android/layout_tests/fast/xsl/sort-unicode.xml
+/sdcard/android/layout_tests/fast/xsl/default-html.html
+/sdcard/android/layout_tests/fast/xsl/nbsp-in-stylesheet.html
+/sdcard/android/layout_tests/fast/xsl/xslt-string-parameters.html
+/sdcard/android/layout_tests/fast/xsl/xslt-entity-enc.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-text.html
+/sdcard/android/layout_tests/fast/xsl/xslt-nested-stylesheets.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-url.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-doc-enc.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-recursion.xml
+/sdcard/android/layout_tests/fast/xsl/exslt-node-set.xml
+/sdcard/android/layout_tests/fast/xsl/subframe-location.html
+/sdcard/android/layout_tests/fast/xsl/xslt-second-level-import.xml
+/sdcard/android/layout_tests/fast/xsl/dtd-in-source-document.xml
+/sdcard/android/layout_tests/fast/xsl/mozilla-tests.xml
+/sdcard/android/layout_tests/fast/canvas/canvas-alphaImageData-behavior.html
+/sdcard/android/layout_tests/fast/canvas/canvas-transform-non-invertible.html
+/sdcard/android/layout_tests/fast/canvas/pointInPath.html
+/sdcard/android/layout_tests/fast/canvas/canvas-transform-infinity.html
+/sdcard/android/layout_tests/fast/canvas/toDataURL-supportedTypes.html
+/sdcard/android/layout_tests/fast/canvas/canvas-getImageData.html
+/sdcard/android/layout_tests/fast/canvas/canvas-transform-skewed.html
+/sdcard/android/layout_tests/fast/canvas/canvas-longlived-context.html
+/sdcard/android/layout_tests/fast/canvas/canvas-save-restore-with-path.html
+/sdcard/android/layout_tests/fast/canvas/set-colors.html
+/sdcard/android/layout_tests/fast/canvas/canvas-transform-nan.html
+/sdcard/android/layout_tests/fast/canvas/canvas-transform-identity.html
+/sdcard/android/layout_tests/fast/canvas/canvas-transform-multiply.html
+/sdcard/android/layout_tests/fast/frames/viewsource-empty-attribute-value.html
+/sdcard/android/layout_tests/fast/frames/frame-deep-nested-resize.html
+/sdcard/android/layout_tests/fast/frames/iframe-window-focus.html
+/sdcard/android/layout_tests/fast/frames/frameElement-widthheight.html
+/sdcard/android/layout_tests/fast/frames/removal-before-attach-crash.html
+/sdcard/android/layout_tests/fast/frames/frame-js-url-clientWidth.html
+/sdcard/android/layout_tests/fast/frames/frame-length-fractional.html
+/sdcard/android/layout_tests/fast/frames/frame-limit.html
+/sdcard/android/layout_tests/fast/frames/frame-display-none-focus.html
+/sdcard/android/layout_tests/fast/frames/iframe-name-and-id.html
+/sdcard/android/layout_tests/fast/reflections/teardown-crash.html
+/sdcard/android/layout_tests/fast/reflections/reflection-computed-style.html
+/sdcard/android/layout_tests/transforms/2d/transform-2d.html
+/sdcard/android/layout_tests/transforms/2d/compound-2d-transforms.html
+/sdcard/android/layout_tests/transforms/2d/transform-value-types.html
+/sdcard/android/layout_tests/transforms/2d/computed-style-origin.html
+/sdcard/android/layout_tests/transforms/2d/transform-accuracy.html
+/sdcard/android/layout_tests/wml/variable-reference-valid.html
+/sdcard/android/layout_tests/wml/go-task-get-method-external-deck-with-href.html
+/sdcard/android/layout_tests/wml/variable-reference-invalid-character.html
+/sdcard/android/layout_tests/wml/go-task-animation.html
+/sdcard/android/layout_tests/wml/go-task-get-method-external-deck.html
+/sdcard/android/layout_tests/wml/go-task-get-method-same-deck.html
+/sdcard/android/layout_tests/animations/animation-css-rule-types.html
+/sdcard/android/layout_tests/animations/animation-events-create.html
+/sdcard/android/layout_tests/animations/animation-start-event-destroy-renderer.html
+/sdcard/android/layout_tests/animations/combo-transform-translate+scale.html
+/sdcard/android/layout_tests/animations/simultaneous-start-transform.html
+/sdcard/android/layout_tests/animations/lineheight-animation.html
+/sdcard/android/layout_tests/animations/import.html
+/sdcard/android/layout_tests/animations/simultaneous-start-left.html
+/sdcard/android/layout_tests/animations/fill-unset-properties.html
+/sdcard/android/layout_tests/animations/keyframes-to-missing.html
+/sdcard/android/layout_tests/animations/multiple-keyframes.html
+/sdcard/android/layout_tests/animations/matrix-anim.html
+/sdcard/android/layout_tests/animations/keyframes-comma-separated.html
+/sdcard/android/layout_tests/animations/change-one-anim.html
+/sdcard/android/layout_tests/animations/keyframes-rule.html
+/sdcard/android/layout_tests/animations/generic-from-to.html
+/sdcard/android/layout_tests/animations/big-rotation.html
+/sdcard/android/layout_tests/animations/animation-controller-drt-api.html
+/sdcard/android/layout_tests/animations/keyframe-timing-functions.html
+/sdcard/android/layout_tests/animations/keyframes-from-missing.html
+/sdcard/android/layout_tests/animations/transition-and-animation-1.html
+/sdcard/android/layout_tests/animations/computed-style.html
+/sdcard/android/layout_tests/animations/animation-iteration-event-destroy-renderer.html
+/sdcard/android/layout_tests/animations/keyframes.html
+/sdcard/android/layout_tests/animations/multiple-animations.html
+/sdcard/android/layout_tests/animations/animation-end-event-destroy-renderer.html
+/sdcard/android/layout_tests/animations/change-keyframes-name.html
+/sdcard/android/layout_tests/animations/combo-transform-rotate+scale.html
+/sdcard/android/layout_tests/animations/change-keyframes.html
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/010.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/001.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/002.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/003.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/004.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/005.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/006.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/007.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/008.xml
+/sdcard/android/layout_tests/traversal/hixie-node-iterator/009.xml
+/sdcard/android/layout_tests/storage/domstorage/localstorage/index-get-and-set.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/onstorage-attribute-setattribute.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/clear.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/enumerate-storage.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/simple-usage.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/simple-events.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/onstorage-attribute-markup.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/iframe-events.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/delete-removal.html
+/sdcard/android/layout_tests/storage/domstorage/localstorage/window-open.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/index-get-and-set.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/onstorage-attribute-setattribute.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/clear.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/enumerate-storage.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/simple-usage.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/simple-events.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/onstorage-attribute-markup.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/iframe-events.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/delete-removal.html
+/sdcard/android/layout_tests/storage/domstorage/sessionstorage/window-open.html
+/sdcard/android/layout_tests/storage/domstorage/window-attributes-exist.html
+/sdcard/android/layout_tests/storage/open-database-empty-version.html
+/sdcard/android/layout_tests/storage/close-during-stress-test.html
+/sdcard/android/layout_tests/storage/execute-sql-args.html
+/sdcard/android/layout_tests/storage/quota-tracking.html
+/sdcard/android/layout_tests/storage/transaction_callback_exception_crash.html
+/sdcard/android/layout_tests/storage/multiple-databases-garbage-collection.html
+/sdcard/android/layout_tests/storage/empty-statement.html
+/sdcard/android/layout_tests/storage/multiple-transactions.html
+/sdcard/android/layout_tests/storage/success-callback.html
+/sdcard/android/layout_tests/storage/sql-data-types.html
+/sdcard/android/layout_tests/security/set-form-autocomplete-attribute.html
+/sdcard/android/layout_tests/security/autocomplete-cleared-on-back.html
+/sdcard/android/layout_tests/security/block-test.html
+/sdcard/android/layout_tests/transitions/transition-shorthand-delay.html
+/sdcard/android/layout_tests/transitions/transition-drt-api-delay.html
+/sdcard/android/layout_tests/transitions/opacity-transition-zindex.html
+/sdcard/android/layout_tests/transitions/shorthand-transitions.html
+/sdcard/android/layout_tests/transitions/hang-with-bad-transition-list.html
+/sdcard/android/layout_tests/transitions/zero-duration-in-list.html
+/sdcard/android/layout_tests/transitions/shorthand-border-transitions.html
+/sdcard/android/layout_tests/transitions/zero-duration-with-non-zero-delay-end.html
+/sdcard/android/layout_tests/transitions/repeated-firing-background-color.html
+/sdcard/android/layout_tests/transitions/start-transform-transition.html
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt b/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt
index c9e166c..eb5b6e0 100644
--- a/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt
+++ b/tests/DumpRenderTree/assets/results/layout_tests_nontext.txt
@@ -1,3 +1,770 @@
+/sdcard/android/layout_tests/webarchive/loading/cache-expired-subresource.html
+/sdcard/android/layout_tests/webarchive/test-css-import.html
+/sdcard/android/layout_tests/webarchive/test-img-src.html
+/sdcard/android/layout_tests/webarchive/archive-empty-frame-dom.html
+/sdcard/android/layout_tests/webarchive/test-frameset.html
+/sdcard/android/layout_tests/webarchive/test-body-background.html
+/sdcard/android/layout_tests/webarchive/test-input-src.html
+/sdcard/android/layout_tests/webarchive/archive-empty-frame-source.html
+/sdcard/android/layout_tests/webarchive/doctype.html
+/sdcard/android/layout_tests/webarchive/test-css-url-resources-inline-styles.html
+/sdcard/android/layout_tests/webarchive/test-table-background.html
+/sdcard/android/layout_tests/webarchive/test-object-data.html
+/sdcard/android/layout_tests/webarchive/test-css-url-resources-in-stylesheets.html
+/sdcard/android/layout_tests/webarchive/archive-with-unencoded-url.html
+/sdcard/android/layout_tests/webarchive/test-link-href.html
+/sdcard/android/layout_tests/webarchive/test-duplicate-resources.html
+/sdcard/android/layout_tests/webarchive/test-xml-stylesheet.xml
+/sdcard/android/layout_tests/webarchive/test-td-background.html
+/sdcard/android/layout_tests/webarchive/test-script-src.html
+/sdcard/android/layout_tests/media/video-transformed.html
+/sdcard/android/layout_tests/media/video-display-toggle.html
+/sdcard/android/layout_tests/media/audio-controls-rendering.html
+/sdcard/android/layout_tests/media/video-controls-visible-audio-only.html
+/sdcard/android/layout_tests/media/video-zoom.html
+/sdcard/android/layout_tests/media/video-controls-rendering.html
+/sdcard/android/layout_tests/media/video-aspect-ratio.html
+/sdcard/android/layout_tests/media/video-layer-crash.html
+/sdcard/android/layout_tests/plugins/netscape-dom-access.html
+/sdcard/android/layout_tests/plugins/embed-attributes-style.html
+/sdcard/android/layout_tests/editing/input/emacs-ctrl-o.html
+/sdcard/android/layout_tests/editing/style/style-3681552-fix-001.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-013.html
+/sdcard/android/layout_tests/editing/style/style-3690704-fix.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-005.html
+/sdcard/android/layout_tests/editing/style/style-boundary-002.html
+/sdcard/android/layout_tests/editing/style/remove-underline-after-paragraph.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-009.html
+/sdcard/android/layout_tests/editing/style/5228141.html
+/sdcard/android/layout_tests/editing/style/block-style-004.html
+/sdcard/android/layout_tests/editing/style/apple-style-editable-mix.html
+/sdcard/android/layout_tests/editing/style/unbold-in-bold.html
+/sdcard/android/layout_tests/editing/style/typing-style-001.html
+/sdcard/android/layout_tests/editing/style/remove-underline-from-stylesheet.html
+/sdcard/android/layout_tests/editing/style/relative-font-size-change-004.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-010.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-002.html
+/sdcard/android/layout_tests/editing/style/style-3681552-fix-002.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-006.html
+/sdcard/android/layout_tests/editing/style/style-boundary-003.html
+/sdcard/android/layout_tests/editing/style/block-style-001.html
+/sdcard/android/layout_tests/editing/style/smoosh-styles-001.html
+/sdcard/android/layout_tests/editing/style/font-family-with-space.html
+/sdcard/android/layout_tests/editing/style/5084241.html
+/sdcard/android/layout_tests/editing/style/5065910.html
+/sdcard/android/layout_tests/editing/style/block-style-005.html
+/sdcard/android/layout_tests/editing/style/remove-underline-across-paragraph-in-bold.html
+/sdcard/android/layout_tests/editing/style/5279521.html
+/sdcard/android/layout_tests/editing/style/non-inheritable-styles.html
+/sdcard/android/layout_tests/editing/style/5046875-1.html
+/sdcard/android/layout_tests/editing/style/style-3998892-fix.html
+/sdcard/android/layout_tests/editing/style/remove-underline-in-bold.html
+/sdcard/android/layout_tests/editing/style/typing-style-002.html
+/sdcard/android/layout_tests/editing/style/relative-font-size-change-001.html
+/sdcard/android/layout_tests/editing/style/4916887.html
+/sdcard/android/layout_tests/editing/style/remove-underline-across-paragraph.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-011.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-003.html
+/sdcard/android/layout_tests/editing/style/remove-underline.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-007.html
+/sdcard/android/layout_tests/editing/style/style-boundary-004.html
+/sdcard/android/layout_tests/editing/style/5017613-1.html
+/sdcard/android/layout_tests/editing/style/block-style-002.html
+/sdcard/android/layout_tests/editing/style/smoosh-styles-002.html
+/sdcard/android/layout_tests/editing/style/block-style-006.html
+/sdcard/android/layout_tests/editing/style/fontsize-1.html
+/sdcard/android/layout_tests/editing/style/5046875-2.html
+/sdcard/android/layout_tests/editing/style/typing-style-003.html
+/sdcard/android/layout_tests/editing/style/relative-font-size-change-002.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-012.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-004.html
+/sdcard/android/layout_tests/editing/style/designmode.html
+/sdcard/android/layout_tests/editing/style/block-styles-007.html
+/sdcard/android/layout_tests/editing/style/style-boundary-001.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-008.html
+/sdcard/android/layout_tests/editing/style/style-boundary-005.html
+/sdcard/android/layout_tests/editing/style/underline.html
+/sdcard/android/layout_tests/editing/style/5017613-2.html
+/sdcard/android/layout_tests/editing/style/block-style-003.html
+/sdcard/android/layout_tests/editing/style/smoosh-styles-003.html
+/sdcard/android/layout_tests/editing/style/remove-underline-after-paragraph-in-bold.html
+/sdcard/android/layout_tests/editing/style/highlight.html
+/sdcard/android/layout_tests/editing/style/table-selection.html
+/sdcard/android/layout_tests/editing/style/relative-font-size-change-003.html
+/sdcard/android/layout_tests/editing/style/create-block-for-style-001.html
+/sdcard/android/layout_tests/editing/unsupported-content/table-delete-001.html
+/sdcard/android/layout_tests/editing/unsupported-content/table-type-after.html
+/sdcard/android/layout_tests/editing/unsupported-content/table-delete-002.html
+/sdcard/android/layout_tests/editing/unsupported-content/table-type-before.html
+/sdcard/android/layout_tests/editing/unsupported-content/table-delete-003.html
+/sdcard/android/layout_tests/editing/unsupported-content/list-delete-001.html
+/sdcard/android/layout_tests/editing/unsupported-content/list-type-after.html
+/sdcard/android/layout_tests/editing/unsupported-content/list-type-before.html
+/sdcard/android/layout_tests/editing/unsupported-content/list-delete-003.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-011.html
+/sdcard/android/layout_tests/editing/inserting/4960120-1.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-023.html
+/sdcard/android/layout_tests/editing/inserting/insert-paragraph-04.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-007.html
+/sdcard/android/layout_tests/editing/inserting/5058163-2.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-019.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-at-tabspan-003.html
+/sdcard/android/layout_tests/editing/inserting/5607069-2.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-003.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-003.html
+/sdcard/android/layout_tests/editing/inserting/4875189-1.html
+/sdcard/android/layout_tests/editing/inserting/typing-003.html
+/sdcard/android/layout_tests/editing/inserting/insert-3907422-fix.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-020.html
+/sdcard/android/layout_tests/editing/inserting/before-after-input-element.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-004.html
+/sdcard/android/layout_tests/editing/inserting/insert-paragraph-01.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-016.html
+/sdcard/android/layout_tests/editing/inserting/4959067.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-008.html
+/sdcard/android/layout_tests/editing/inserting/insert-text-at-tabspan-001.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-001.html
+/sdcard/android/layout_tests/editing/inserting/paragraph-separator-02.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-013.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-025.html
+/sdcard/android/layout_tests/editing/inserting/insert-3654864-fix.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-009.html
+/sdcard/android/layout_tests/editing/inserting/return-key-with-selection-002.html
+/sdcard/android/layout_tests/editing/inserting/editable-html-element.html
+/sdcard/android/layout_tests/editing/inserting/5418891.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-005.html
+/sdcard/android/layout_tests/editing/inserting/insert-tab-002.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-005.html
+/sdcard/android/layout_tests/editing/inserting/line-break.html
+/sdcard/android/layout_tests/editing/inserting/5549929-3.html
+/sdcard/android/layout_tests/editing/inserting/typing-tab-designmode-forms.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-010.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-022.html
+/sdcard/android/layout_tests/editing/inserting/insert-paragraph-03.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-006.html
+/sdcard/android/layout_tests/editing/inserting/5058163-1.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-018.html
+/sdcard/android/layout_tests/editing/inserting/paragraph-separator-in-table-2.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-at-tabspan-002.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-002.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-002.html
+/sdcard/android/layout_tests/editing/inserting/typing-002.html
+/sdcard/android/layout_tests/editing/inserting/insert-3800346-fix.html
+/sdcard/android/layout_tests/editing/inserting/insert-text-at-tabspan-003.html
+/sdcard/android/layout_tests/editing/inserting/typing-around-image-001.html
+/sdcard/android/layout_tests/editing/inserting/insert-text-with-newlines.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-003.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-015.html
+/sdcard/android/layout_tests/editing/inserting/insert-at-end-02.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-027.html
+/sdcard/android/layout_tests/editing/inserting/insert-3659587-fix.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-007.html
+/sdcard/android/layout_tests/editing/inserting/insert-tab-004.html
+/sdcard/android/layout_tests/editing/inserting/editable-inline-element.html
+/sdcard/android/layout_tests/editing/inserting/insert-3851164-fix.html
+/sdcard/android/layout_tests/editing/inserting/paragraph-separator-01.html
+/sdcard/android/layout_tests/editing/inserting/5156401-2.html
+/sdcard/android/layout_tests/editing/inserting/4960120-2.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-012.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-024.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-008.html
+/sdcard/android/layout_tests/editing/inserting/insert-paragraph-05.html
+/sdcard/android/layout_tests/editing/inserting/multiple-lines-selected.html
+/sdcard/android/layout_tests/editing/inserting/insert-3778059-fix.html
+/sdcard/android/layout_tests/editing/inserting/return-key-with-selection-001.html
+/sdcard/android/layout_tests/editing/inserting/5607069-3.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-004.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-004.html
+/sdcard/android/layout_tests/editing/inserting/insert-tab-001.html
+/sdcard/android/layout_tests/editing/inserting/4875189-2.html
+/sdcard/android/layout_tests/editing/inserting/5549929-2.html
+/sdcard/android/layout_tests/editing/inserting/editing-empty-divs.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-021.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-005.html
+/sdcard/android/layout_tests/editing/inserting/insert-paragraph-02.html
+/sdcard/android/layout_tests/editing/inserting/insert-3786362-fix.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-017.html
+/sdcard/android/layout_tests/editing/inserting/paragraph-separator-in-table-1.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-at-tabspan-001.html
+/sdcard/android/layout_tests/editing/inserting/insert-space-in-empty-doc.html
+/sdcard/android/layout_tests/editing/inserting/insert-after-delete-001.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-001.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-001.html
+/sdcard/android/layout_tests/editing/inserting/typing-001.html
+/sdcard/android/layout_tests/editing/inserting/4278698.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-009.html
+/sdcard/android/layout_tests/editing/inserting/insert-text-at-tabspan-002.html
+/sdcard/android/layout_tests/editing/inserting/5002441.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-002.html
+/sdcard/android/layout_tests/editing/inserting/paragraph-separator-03.html
+/sdcard/android/layout_tests/editing/inserting/12882.html
+/sdcard/android/layout_tests/editing/inserting/insert-3775316-fix.html
+/sdcard/android/layout_tests/editing/inserting/edited-whitespace-1.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-014.html
+/sdcard/android/layout_tests/editing/inserting/insert-at-end-01.html
+/sdcard/android/layout_tests/editing/inserting/redo.html
+/sdcard/android/layout_tests/editing/inserting/insert-div-026.html
+/sdcard/android/layout_tests/editing/inserting/4840662.html
+/sdcard/android/layout_tests/editing/inserting/typing-around-br-001.html
+/sdcard/android/layout_tests/editing/inserting/return-key-with-selection-003.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-quoted-006.html
+/sdcard/android/layout_tests/editing/inserting/insert-tab-003.html
+/sdcard/android/layout_tests/editing/inserting/insert-br-006.html
+/sdcard/android/layout_tests/editing/execCommand/5142012-1.html
+/sdcard/android/layout_tests/editing/execCommand/hilitecolor.html
+/sdcard/android/layout_tests/editing/execCommand/5120591.html
+/sdcard/android/layout_tests/editing/execCommand/format-block-with-braces.html
+/sdcard/android/layout_tests/editing/execCommand/4920742-1.html
+/sdcard/android/layout_tests/editing/execCommand/4924441.html
+/sdcard/android/layout_tests/editing/execCommand/create-list-with-hr.html
+/sdcard/android/layout_tests/editing/execCommand/5207369.html
+/sdcard/android/layout_tests/editing/execCommand/format-block-with-trailing-br.html
+/sdcard/android/layout_tests/editing/execCommand/4916583.html
+/sdcard/android/layout_tests/editing/execCommand/remove-formatting-2.html
+/sdcard/android/layout_tests/editing/execCommand/outdent-selection.html
+/sdcard/android/layout_tests/editing/execCommand/strikethroughSelection.html
+/sdcard/android/layout_tests/editing/execCommand/insert-list-with-id.html
+/sdcard/android/layout_tests/editing/execCommand/5432254-1.html
+/sdcard/android/layout_tests/editing/execCommand/5482023.html
+/sdcard/android/layout_tests/editing/execCommand/5062376.html
+/sdcard/android/layout_tests/editing/execCommand/4786404-1.html
+/sdcard/android/layout_tests/editing/execCommand/remove-formatting.html
+/sdcard/android/layout_tests/editing/execCommand/findString.html
+/sdcard/android/layout_tests/editing/execCommand/5142012-3.html
+/sdcard/android/layout_tests/editing/execCommand/5700414-1.html
+/sdcard/android/layout_tests/editing/execCommand/italicizeByCharacter.html
+/sdcard/android/layout_tests/editing/execCommand/switch-list-type.html
+/sdcard/android/layout_tests/editing/execCommand/create-list-from-range-selection.html
+/sdcard/android/layout_tests/editing/execCommand/5190926.html
+/sdcard/android/layout_tests/editing/execCommand/remove-list-1.html
+/sdcard/android/layout_tests/editing/execCommand/insertHorizontalRule.html
+/sdcard/android/layout_tests/editing/execCommand/paste-1.html
+/sdcard/android/layout_tests/editing/execCommand/nsresponder-outdent.html
+/sdcard/android/layout_tests/editing/execCommand/5080333-2.html
+/sdcard/android/layout_tests/editing/execCommand/5119244.html
+/sdcard/android/layout_tests/editing/execCommand/5049671.html
+/sdcard/android/layout_tests/editing/execCommand/4920488.html
+/sdcard/android/layout_tests/editing/execCommand/5164796.html
+/sdcard/android/layout_tests/editing/execCommand/nsresponder-indent.html
+/sdcard/android/layout_tests/editing/execCommand/indent-list-item.html
+/sdcard/android/layout_tests/editing/execCommand/insert-list-empty-div.html
+/sdcard/android/layout_tests/editing/execCommand/5138441.html
+/sdcard/android/layout_tests/editing/execCommand/4916402.html
+/sdcard/android/layout_tests/editing/execCommand/5481523.html
+/sdcard/android/layout_tests/editing/execCommand/print.html
+/sdcard/android/layout_tests/editing/execCommand/4641880-2.html
+/sdcard/android/layout_tests/editing/execCommand/4580583-2.html
+/sdcard/android/layout_tests/editing/execCommand/remove-list-item-1.html
+/sdcard/android/layout_tests/editing/execCommand/5569741.html
+/sdcard/android/layout_tests/editing/execCommand/findString-2.html
+/sdcard/android/layout_tests/editing/execCommand/modifyForeColorByCharacter.html
+/sdcard/android/layout_tests/editing/execCommand/5142012-2.html
+/sdcard/android/layout_tests/editing/execCommand/find-after-replace.html
+/sdcard/android/layout_tests/editing/execCommand/format-block.html
+/sdcard/android/layout_tests/editing/execCommand/5080333-1.html
+/sdcard/android/layout_tests/editing/execCommand/remove-list-from-range-selection.html
+/sdcard/android/layout_tests/editing/execCommand/remove-list-items.html
+/sdcard/android/layout_tests/editing/execCommand/5432254-2.html
+/sdcard/android/layout_tests/editing/execCommand/5144139-1.html
+/sdcard/android/layout_tests/editing/execCommand/5136770.html
+/sdcard/android/layout_tests/editing/execCommand/4916541.html
+/sdcard/android/layout_tests/editing/execCommand/4786404-2.html
+/sdcard/android/layout_tests/editing/execCommand/insertImage.html
+/sdcard/android/layout_tests/editing/execCommand/insert-list-and-stitch.html
+/sdcard/android/layout_tests/editing/execCommand/5573879.html
+/sdcard/android/layout_tests/editing/execCommand/5210032.html
+/sdcard/android/layout_tests/editing/execCommand/5700414-2.html
+/sdcard/android/layout_tests/editing/execCommand/boldSelection.html
+/sdcard/android/layout_tests/editing/execCommand/insertHTML.html
+/sdcard/android/layout_tests/editing/execCommand/4641880-1.html
+/sdcard/android/layout_tests/editing/execCommand/4747450.html
+/sdcard/android/layout_tests/editing/execCommand/4580583-1.html
+/sdcard/android/layout_tests/editing/execCommand/format-block-from-range-selection.html
+/sdcard/android/layout_tests/editing/execCommand/indent-empty-root.html
+/sdcard/android/layout_tests/editing/execCommand/indent-selection.html
+/sdcard/android/layout_tests/editing/execCommand/selectAll.html
+/sdcard/android/layout_tests/editing/execCommand/paste-2.html
+/sdcard/android/layout_tests/editing/pasteboard/subframe-dragndrop-1.html
+/sdcard/android/layout_tests/editing/pasteboard/innerText-inline-table.html
+/sdcard/android/layout_tests/editing/pasteboard/5156401-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-list-001.html
+/sdcard/android/layout_tests/editing/pasteboard/5032095.html
+/sdcard/android/layout_tests/editing/pasteboard/4242293-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-004.html
+/sdcard/android/layout_tests/editing/pasteboard/5247341.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-4035648-fix.html
+/sdcard/android/layout_tests/editing/pasteboard/4700297.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-003.html
+/sdcard/android/layout_tests/editing/pasteboard/drop-link.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote-3.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote.html
+/sdcard/android/layout_tests/editing/pasteboard/4944770-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-015.html
+/sdcard/android/layout_tests/editing/pasteboard/5075944.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-match-style-001.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-4039777-fix.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-3.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-007.html
+/sdcard/android/layout_tests/editing/pasteboard/5483567.html
+/sdcard/android/layout_tests/editing/pasteboard/7955.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-blockquote.html
+/sdcard/android/layout_tests/editing/pasteboard/testcase-9507.html
+/sdcard/android/layout_tests/editing/pasteboard/input-field-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-001.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-at-tabspan-001.html
+/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-2.html
+/sdcard/android/layout_tests/editing/pasteboard/block-wrappers-necessary.html
+/sdcard/android/layout_tests/editing/pasteboard/4861080.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-009.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-after-delete.html
+/sdcard/android/layout_tests/editing/pasteboard/5478250.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-012.html
+/sdcard/android/layout_tests/editing/pasteboard/prevent-block-nesting-01.html
+/sdcard/android/layout_tests/editing/pasteboard/8145-2.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-borders.html
+/sdcard/android/layout_tests/editing/pasteboard/5027857.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-004.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-start-list.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-008.html
+/sdcard/android/layout_tests/editing/pasteboard/4806874.html
+/sdcard/android/layout_tests/editing/pasteboard/emacs-ctrl-a-k-y.html
+/sdcard/android/layout_tests/editing/pasteboard/bad-placeholder.html
+/sdcard/android/layout_tests/editing/pasteboard/displaced-placeholder.html
+/sdcard/android/layout_tests/editing/pasteboard/5387578.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-010.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-006.html
+/sdcard/android/layout_tests/editing/pasteboard/5601583-1.html
+/sdcard/android/layout_tests/editing/pasteboard/4947130.html
+/sdcard/android/layout_tests/editing/pasteboard/pasting-tabs.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-after-delete-2.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-001.html
+/sdcard/android/layout_tests/editing/pasteboard/4076267-2.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-table-001.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-005.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-017.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-5.html
+/sdcard/android/layout_tests/editing/pasteboard/drop-text-without-selection.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-at-tabspan-003.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-003.html
+/sdcard/android/layout_tests/editing/pasteboard/drag-drop-modifies-page.html
+/sdcard/android/layout_tests/editing/pasteboard/emacs-ctrl-k-y-001.html
+/sdcard/android/layout_tests/editing/pasteboard/5071074.html
+/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-4.html
+/sdcard/android/layout_tests/editing/pasteboard/styled-element-markup.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-4038267-fix.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-002.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote-2.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-pre-002.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-014.html
+/sdcard/android/layout_tests/editing/pasteboard/drag-drop-dead-frame.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-2.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-006.html
+/sdcard/android/layout_tests/editing/pasteboard/5368833.html
+/sdcard/android/layout_tests/editing/pasteboard/select-element-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-3.html
+/sdcard/android/layout_tests/editing/pasteboard/4641033.html
+/sdcard/android/layout_tests/editing/pasteboard/drag-image-to-contenteditable-in-iframe.html
+/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-1.html
+/sdcard/android/layout_tests/editing/pasteboard/copy-paste-bidi.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-008.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-011.html
+/sdcard/android/layout_tests/editing/pasteboard/8145-1.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-003.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-table-003.html
+/sdcard/android/layout_tests/editing/pasteboard/5075944-3.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-007.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-TIFF.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-019.html
+/sdcard/android/layout_tests/editing/pasteboard/undoable-fragment-removes.html
+/sdcard/android/layout_tests/editing/pasteboard/nested-blocks-with-text-field.html
+/sdcard/android/layout_tests/editing/pasteboard/4989774.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-unrendered-select.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-005.html
+/sdcard/android/layout_tests/editing/pasteboard/emacs-cntl-y-001.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-after-delete-1.html
+/sdcard/android/layout_tests/editing/pasteboard/unrendered-br.html
+/sdcard/android/layout_tests/editing/pasteboard/4631972.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-004.html
+/sdcard/android/layout_tests/editing/pasteboard/quirks-mode-br-1.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-into-blockquote-4.html
+/sdcard/android/layout_tests/editing/pasteboard/4944770-2.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-table-cells.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-016.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-match-style-002.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-4.html
+/sdcard/android/layout_tests/editing/pasteboard/drag-selected-image-to-contenteditable.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-008.html
+/sdcard/android/layout_tests/editing/pasteboard/3976872.html
+/sdcard/android/layout_tests/editing/pasteboard/pasting-object.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-list.html
+/sdcard/android/layout_tests/editing/pasteboard/copy-standalone-image.html
+/sdcard/android/layout_tests/editing/pasteboard/displaced-generic-placeholder.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-002.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-at-tabspan-002.html
+/sdcard/android/layout_tests/editing/pasteboard/interchange-newline-3.html
+/sdcard/android/layout_tests/editing/pasteboard/5071074-2.html
+/sdcard/android/layout_tests/editing/pasteboard/display-block-on-spans.html
+/sdcard/android/layout_tests/editing/pasteboard/4242293.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-001.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-pre-001.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-start-blockquote.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-1.html
+/sdcard/android/layout_tests/editing/pasteboard/8145-3.html
+/sdcard/android/layout_tests/editing/pasteboard/5006779.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-005.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-009.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-blockquote-2.html
+/sdcard/android/layout_tests/editing/pasteboard/merge-end-table.html
+/sdcard/android/layout_tests/editing/pasteboard/5065605.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-line-endings-007.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-010.html
+/sdcard/android/layout_tests/editing/pasteboard/5028447.html
+/sdcard/android/layout_tests/editing/pasteboard/nested-blocks-with-text-area.html
+/sdcard/android/layout_tests/editing/pasteboard/4076267-3.html
+/sdcard/android/layout_tests/editing/pasteboard/4076267.html
+/sdcard/android/layout_tests/editing/pasteboard/smart-paste-002.html
+/sdcard/android/layout_tests/editing/pasteboard/5075944-2.html
+/sdcard/android/layout_tests/editing/pasteboard/5134759.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-006.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-text-018.html
+/sdcard/android/layout_tests/editing/pasteboard/paste-RTFD.html
+/sdcard/android/layout_tests/editing/pasteboard/cut-text-001.html
+/sdcard/android/layout_tests/editing/selection/image-before-linebreak.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-9.html
+/sdcard/android/layout_tests/editing/selection/move-between-blocks-no-001.html
+/sdcard/android/layout_tests/editing/selection/fake-drag.html
+/sdcard/android/layout_tests/editing/selection/wrapped-line-caret-2.html
+/sdcard/android/layout_tests/editing/selection/5131716-3.html
+/sdcard/android/layout_tests/editing/selection/5081257-2.html
+/sdcard/android/layout_tests/editing/selection/3690703-2.html
+/sdcard/android/layout_tests/editing/selection/unrendered-002.html
+/sdcard/android/layout_tests/editing/selection/extend-by-character-005.html
+/sdcard/android/layout_tests/editing/selection/5354455-1.html
+/sdcard/android/layout_tests/editing/selection/caret-rtl-2.html
+/sdcard/android/layout_tests/editing/selection/paragraph-granularity.html
+/sdcard/android/layout_tests/editing/selection/expanding-selections2.html
+/sdcard/android/layout_tests/editing/selection/clear-selection.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-6.html
+/sdcard/android/layout_tests/editing/selection/display-table-text.html
+/sdcard/android/layout_tests/editing/selection/13804.html
+/sdcard/android/layout_tests/editing/selection/drag-in-iframe.html
+/sdcard/android/layout_tests/editing/selection/table-caret-2.html
+/sdcard/android/layout_tests/editing/selection/expanding-selections.html
+/sdcard/android/layout_tests/editing/selection/unrendered-space.html
+/sdcard/android/layout_tests/editing/selection/node-removal-1.html
+/sdcard/android/layout_tests/editing/selection/5240265.html
+/sdcard/android/layout_tests/editing/selection/select-all-005.html
+/sdcard/android/layout_tests/editing/selection/extend-by-character-002.html
+/sdcard/android/layout_tests/editing/selection/4932260-2.html
+/sdcard/android/layout_tests/editing/selection/5076323-3.html
+/sdcard/android/layout_tests/editing/selection/select-element-paragraph-boundary.html
+/sdcard/android/layout_tests/editing/selection/line-wrap-1.html
+/sdcard/android/layout_tests/editing/selection/replace-selection-1.html
+/sdcard/android/layout_tests/editing/selection/caret-rtl.html
+/sdcard/android/layout_tests/editing/selection/5109817.html
+/sdcard/android/layout_tests/editing/selection/extend-by-sentence-001.html
+/sdcard/android/layout_tests/editing/selection/3690719.html
+/sdcard/android/layout_tests/editing/selection/5136696.html
+/sdcard/android/layout_tests/editing/selection/editable-non-editable-crash.html
+/sdcard/android/layout_tests/editing/selection/4397952.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-3.html
+/sdcard/android/layout_tests/editing/selection/caret-and-focus-ring.html
+/sdcard/android/layout_tests/editing/selection/4895428-4.html
+/sdcard/android/layout_tests/editing/selection/replaced-boundaries-3.html
+/sdcard/android/layout_tests/editing/selection/4947387.html
+/sdcard/android/layout_tests/editing/selection/move-by-sentence-linebreak.html
+/sdcard/android/layout_tests/editing/selection/move-by-character-005.html
+/sdcard/android/layout_tests/editing/selection/select-from-textfield-outwards.html
+/sdcard/android/layout_tests/editing/selection/leave-requested-block.html
+/sdcard/android/layout_tests/editing/selection/select-all-002.html
+/sdcard/android/layout_tests/editing/selection/end-of-document.html
+/sdcard/android/layout_tests/editing/selection/selectNode.html
+/sdcard/android/layout_tests/editing/selection/editable-links.html
+/sdcard/android/layout_tests/editing/selection/unrendered-004.html
+/sdcard/android/layout_tests/editing/selection/7152-2.html
+/sdcard/android/layout_tests/editing/selection/5195166-1.html
+/sdcard/android/layout_tests/editing/selection/editable-html-element.html
+/sdcard/android/layout_tests/editing/selection/4895428-1.html
+/sdcard/android/layout_tests/editing/selection/4866671.html
+/sdcard/android/layout_tests/editing/selection/move-by-character-002.html
+/sdcard/android/layout_tests/editing/selection/extend-by-word-002.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-8.html
+/sdcard/android/layout_tests/editing/selection/wrapped-line-caret-1.html
+/sdcard/android/layout_tests/editing/selection/selection-actions.html
+/sdcard/android/layout_tests/editing/selection/14971.html
+/sdcard/android/layout_tests/editing/selection/5131716-2.html
+/sdcard/android/layout_tests/editing/selection/4402375.html
+/sdcard/android/layout_tests/editing/selection/unrendered-001.html
+/sdcard/android/layout_tests/editing/selection/move-3875641-fix.html
+/sdcard/android/layout_tests/editing/selection/5081257-1.html
+/sdcard/android/layout_tests/editing/selection/extend-by-character-004.html
+/sdcard/android/layout_tests/editing/selection/5099303.html
+/sdcard/android/layout_tests/editing/selection/contenteditable-click-inside.html
+/sdcard/android/layout_tests/editing/selection/move-by-line-002.html
+/sdcard/android/layout_tests/editing/selection/addRange.html
+/sdcard/android/layout_tests/editing/selection/select-missing-image.html
+/sdcard/android/layout_tests/editing/selection/selection-3748164-fix.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-5.html
+/sdcard/android/layout_tests/editing/selection/4983858.html
+/sdcard/android/layout_tests/editing/selection/move-by-sentence-001.html
+/sdcard/android/layout_tests/editing/selection/table-caret-1.html
+/sdcard/android/layout_tests/editing/selection/5007143.html
+/sdcard/android/layout_tests/editing/selection/fake-doubleclick.html
+/sdcard/android/layout_tests/editing/selection/move-by-word-001.html
+/sdcard/android/layout_tests/editing/selection/select-all-004.html
+/sdcard/android/layout_tests/editing/selection/extend-by-character-001.html
+/sdcard/android/layout_tests/editing/selection/4932260-1.html
+/sdcard/android/layout_tests/editing/selection/5076323-2.html
+/sdcard/android/layout_tests/editing/selection/5234383-2.html
+/sdcard/android/layout_tests/editing/selection/5057506.html
+/sdcard/android/layout_tests/editing/selection/focus_editable_html.html
+/sdcard/android/layout_tests/editing/selection/move-3875618-fix.html
+/sdcard/android/layout_tests/editing/selection/4818145.html
+/sdcard/android/layout_tests/editing/selection/move-backwords-by-word-001.html
+/sdcard/android/layout_tests/editing/selection/inline-table.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-2.html
+/sdcard/android/layout_tests/editing/selection/4895428-3.html
+/sdcard/android/layout_tests/editing/selection/replaced-boundaries-2.html
+/sdcard/android/layout_tests/editing/selection/move-by-character-004.html
+/sdcard/android/layout_tests/editing/selection/caret-before-select.html
+/sdcard/android/layout_tests/editing/selection/4889598.html
+/sdcard/android/layout_tests/editing/selection/select-all-001.html
+/sdcard/android/layout_tests/editing/selection/5131716-4.html
+/sdcard/android/layout_tests/editing/selection/3690703.html
+/sdcard/android/layout_tests/editing/selection/5333725.html
+/sdcard/android/layout_tests/editing/selection/unrendered-003.html
+/sdcard/android/layout_tests/editing/selection/extend-by-character-006.html
+/sdcard/android/layout_tests/editing/selection/7152-1.html
+/sdcard/android/layout_tests/editing/selection/5213963.html
+/sdcard/android/layout_tests/editing/selection/5354455-2.html
+/sdcard/android/layout_tests/editing/selection/selection-background.html
+/sdcard/android/layout_tests/editing/selection/iframe.html
+/sdcard/android/layout_tests/editing/selection/extend-by-word-001.html
+/sdcard/android/layout_tests/editing/selection/move-by-character-001.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-7.html
+/sdcard/android/layout_tests/editing/selection/doubleclick-crash.html
+/sdcard/android/layout_tests/editing/selection/table-caret-3.html
+/sdcard/android/layout_tests/editing/selection/5131716-1.html
+/sdcard/android/layout_tests/editing/selection/select-all-iframe.html
+/sdcard/android/layout_tests/editing/selection/node-removal-2.html
+/sdcard/android/layout_tests/editing/selection/drag-select-1.html
+/sdcard/android/layout_tests/editing/selection/select-all-006.html
+/sdcard/android/layout_tests/editing/selection/extend-by-character-003.html
+/sdcard/android/layout_tests/editing/selection/4932260-3.html
+/sdcard/android/layout_tests/editing/selection/4960116.html
+/sdcard/android/layout_tests/editing/selection/after-line-wrap.html
+/sdcard/android/layout_tests/editing/selection/line-wrap-2.html
+/sdcard/android/layout_tests/editing/selection/drag-to-contenteditable-iframe.html
+/sdcard/android/layout_tests/editing/selection/move-by-line-001.html
+/sdcard/android/layout_tests/editing/selection/selectNodeContents.html
+/sdcard/android/layout_tests/editing/selection/move-between-blocks-yes-001.html
+/sdcard/android/layout_tests/editing/selection/6476.html
+/sdcard/android/layout_tests/editing/selection/contains-boundaries.html
+/sdcard/android/layout_tests/editing/selection/click-start-of-line.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-4.html
+/sdcard/android/layout_tests/editing/selection/focus-body.html
+/sdcard/android/layout_tests/editing/selection/triple-click-in-pre.html
+/sdcard/android/layout_tests/editing/selection/move-past-trailing-space.html
+/sdcard/android/layout_tests/editing/selection/inline-closest-leaf-child.html
+/sdcard/android/layout_tests/editing/selection/5007143-2.html
+/sdcard/android/layout_tests/editing/selection/designmode-no-caret.html
+/sdcard/android/layout_tests/editing/selection/select-all-003.html
+/sdcard/android/layout_tests/editing/selection/5076323-1.html
+/sdcard/android/layout_tests/editing/selection/5234383-1.html
+/sdcard/android/layout_tests/editing/selection/5057506-2.html
+/sdcard/android/layout_tests/editing/selection/5232159.html
+/sdcard/android/layout_tests/editing/selection/4975120.html
+/sdcard/android/layout_tests/editing/selection/4960137.html
+/sdcard/android/layout_tests/editing/selection/unrendered-005.html
+/sdcard/android/layout_tests/editing/selection/5195166-2.html
+/sdcard/android/layout_tests/editing/selection/contenteditable-click-outside.html
+/sdcard/android/layout_tests/editing/selection/previous-line-position.html
+/sdcard/android/layout_tests/editing/selection/mixed-editability-1.html
+/sdcard/android/layout_tests/editing/selection/select-box.html
+/sdcard/android/layout_tests/editing/selection/4895428-2.html
+/sdcard/android/layout_tests/editing/selection/replaced-boundaries-1.html
+/sdcard/android/layout_tests/editing/selection/4776665.html
+/sdcard/android/layout_tests/editing/selection/move-by-character-003.html
+/sdcard/android/layout_tests/editing/selection/word-granularity.html
+/sdcard/android/layout_tests/editing/selection/move-by-character-6.html
+/sdcard/android/layout_tests/editing/undo/undo-misspellings.html
+/sdcard/android/layout_tests/editing/undo/undo-combined-delete.html
+/sdcard/android/layout_tests/editing/undo/undo-delete-boundary.html
+/sdcard/android/layout_tests/editing/undo/undo-forward-delete-boundary.html
+/sdcard/android/layout_tests/editing/undo/4063751.html
+/sdcard/android/layout_tests/editing/undo/redo-typing-001.html
+/sdcard/android/layout_tests/editing/undo/5378473.html
+/sdcard/android/layout_tests/editing/undo/undo-combined-delete-boundary.html
+/sdcard/android/layout_tests/editing/undo/undo-delete.html
+/sdcard/android/layout_tests/editing/undo/undo-forward-delete.html
+/sdcard/android/layout_tests/editing/undo/undo-typing-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-3608462-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-image-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-3928305-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-012.html
+/sdcard/android/layout_tests/editing/deleting/5115601.html
+/sdcard/android/layout_tests/editing/deleting/deletionUI-single-instance.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-contents-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-024.html
+/sdcard/android/layout_tests/editing/deleting/delete-after-span-ws-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-011.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-008.html
+/sdcard/android/layout_tests/editing/deleting/delete-listitem-001.html
+/sdcard/android/layout_tests/editing/deleting/5300379.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-007.html
+/sdcard/android/layout_tests/editing/deleting/5433862-2.html
+/sdcard/android/layout_tests/editing/deleting/5026848-1.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-012.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-008.html
+/sdcard/android/layout_tests/editing/deleting/5206311-2.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-start-or-end.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-021.html
+/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-004.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-005.html
+/sdcard/android/layout_tests/editing/deleting/delete-select-all-003.html
+/sdcard/android/layout_tests/editing/deleting/smart-delete-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-017.html
+/sdcard/android/layout_tests/editing/deleting/table-cells.html
+/sdcard/android/layout_tests/editing/deleting/5156801-2.html
+/sdcard/android/layout_tests/editing/deleting/delete-leading-ws-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-004.html
+/sdcard/android/layout_tests/editing/deleting/delete-3857753-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-3959464-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-016.html
+/sdcard/android/layout_tests/editing/deleting/delete-trailing-ws-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-005.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-008.html
+/sdcard/android/layout_tests/editing/deleting/delete-tab-004.html
+/sdcard/android/layout_tests/editing/deleting/merge-whitespace-pre.html
+/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-end-ws-002.html
+/sdcard/android/layout_tests/editing/deleting/merge-unrendered-space.html
+/sdcard/android/layout_tests/editing/deleting/delete-by-word-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-image-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-selection-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-014.html
+/sdcard/android/layout_tests/editing/deleting/merge-different-styles.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-contents-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-after-span-ws-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-013.html
+/sdcard/android/layout_tests/editing/deleting/merge-into-empty-block-1.html
+/sdcard/android/layout_tests/editing/deleting/5156801.html
+/sdcard/android/layout_tests/editing/deleting/delete-3865854-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-009.html
+/sdcard/android/layout_tests/editing/deleting/5026848-3.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-005.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-tab-001.html
+/sdcard/android/layout_tests/editing/deleting/4866671.html
+/sdcard/android/layout_tests/editing/deleting/whitespace-pre-1.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-table.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-011.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-023.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-010.html
+/sdcard/android/layout_tests/editing/deleting/5032066.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-007.html
+/sdcard/android/layout_tests/editing/deleting/smart-delete-004.html
+/sdcard/android/layout_tests/editing/deleting/5144139-2.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-019.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-006.html
+/sdcard/android/layout_tests/editing/deleting/5126166.html
+/sdcard/android/layout_tests/editing/deleting/delete-to-end-of-paragraph.html
+/sdcard/android/layout_tests/editing/deleting/5408255.html
+/sdcard/android/layout_tests/editing/deleting/5099303.html
+/sdcard/android/layout_tests/editing/deleting/4845371.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-002.html
+/sdcard/android/layout_tests/editing/deleting/4922367.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-011.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-007.html
+/sdcard/android/layout_tests/editing/deleting/move-nodes-001.html
+/sdcard/android/layout_tests/editing/deleting/merge-no-br.html
+/sdcard/android/layout_tests/editing/deleting/delete-3800834-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-4038408-fix.html
+/sdcard/android/layout_tests/editing/deleting/5206311-1.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-020.html
+/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-004.html
+/sdcard/android/layout_tests/editing/deleting/smart-delete-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-to-select-table.html
+/sdcard/android/layout_tests/editing/deleting/delete-select-all-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-contiguous-ws-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-016.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-015.html
+/sdcard/android/layout_tests/editing/deleting/5390681.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-011.html
+/sdcard/android/layout_tests/editing/deleting/forward-delete.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-007.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-004.html
+/sdcard/android/layout_tests/editing/deleting/delete-tab-003.html
+/sdcard/android/layout_tests/editing/deleting/collapse-whitespace-3587601-fix.html
+/sdcard/android/layout_tests/editing/deleting/pruning-after-merge-2.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-end-ws-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-by-word-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-image-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-013.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-contents-002.html
+/sdcard/android/layout_tests/editing/deleting/paragraph-in-preserveNewline.html
+/sdcard/android/layout_tests/editing/deleting/delete-after-span-ws-002.html
+/sdcard/android/layout_tests/editing/deleting/5272440.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-012.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-009.html
+/sdcard/android/layout_tests/editing/deleting/delete-listitem-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-character-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-008.html
+/sdcard/android/layout_tests/editing/deleting/5483370.html
+/sdcard/android/layout_tests/editing/deleting/5026848-2.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-004.html
+/sdcard/android/layout_tests/editing/deleting/5091898.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-009.html
+/sdcard/android/layout_tests/editing/deleting/transpose-empty.html
+/sdcard/android/layout_tests/editing/deleting/merge-endOfParagraph.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-010.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-022.html
+/sdcard/android/layout_tests/editing/deleting/delete-3775172-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-mixed-editable-content-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-006.html
+/sdcard/android/layout_tests/editing/deleting/smart-delete-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-018.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-005.html
+/sdcard/android/layout_tests/editing/deleting/delete-first-list-item.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-017.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-trailing-ws-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-010.html
+/sdcard/android/layout_tests/editing/deleting/delete-and-undo.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-006.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-009.html
+/sdcard/android/layout_tests/editing/deleting/delete-hr.html
+/sdcard/android/layout_tests/editing/deleting/4875189.html
+/sdcard/android/layout_tests/editing/deleting/delete-4083333-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-3608445-fix.html
+/sdcard/android/layout_tests/editing/deleting/delete-ws-fixup-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-image-004.html
+/sdcard/android/layout_tests/editing/deleting/delete-select-all-001.html
+/sdcard/android/layout_tests/editing/deleting/delete-block-merge-contents-015.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-002.html
+/sdcard/android/layout_tests/editing/deleting/delete-line-014.html
+/sdcard/android/layout_tests/editing/deleting/merge-into-empty-block-2.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-010.html
+/sdcard/android/layout_tests/editing/deleting/5390681-2.html
+/sdcard/android/layout_tests/editing/deleting/5369009.html
+/sdcard/android/layout_tests/editing/deleting/delete-br-003.html
+/sdcard/android/layout_tests/editing/deleting/delete-at-paragraph-boundaries-006.html
+/sdcard/android/layout_tests/editing/deleting/delete-tab-002.html
+/sdcard/android/layout_tests/editing/deleting/list-item-1.html
+/sdcard/android/layout_tests/editing/deleting/5168598.html
+/sdcard/android/layout_tests/editing/deleting/delete-3608430-fix.html
+/sdcard/android/layout_tests/editing/spelling/spelling.html
+/sdcard/android/layout_tests/editing/spelling/inline_spelling_markers.html
+/sdcard/android/layout_tests/printing/media-queries-print.html
/sdcard/android/layout_tests/fast/media/mq-relative-constraints-05.html
/sdcard/android/layout_tests/fast/media/mq-grid-02.html
/sdcard/android/layout_tests/fast/media/mq-compound-query-02.html
@@ -144,6 +911,7 @@
/sdcard/android/layout_tests/fast/dynamic/014.html
/sdcard/android/layout_tests/fast/dynamic/006.html
/sdcard/android/layout_tests/fast/dynamic/flash-replacement-test.html
+/sdcard/android/layout_tests/fast/dynamic/insertAdjacentElement.html
/sdcard/android/layout_tests/fast/dynamic/insert-before-table-part-in-continuation.html
/sdcard/android/layout_tests/fast/dynamic/staticY.html
/sdcard/android/layout_tests/fast/dynamic/anonymous-block-orphaned-lines.html
@@ -306,6 +1074,7 @@
/sdcard/android/layout_tests/fast/encoding/utf-16-big-endian.html
/sdcard/android/layout_tests/fast/encoding/xmacroman-encoding-test.html
/sdcard/android/layout_tests/fast/encoding/invalid-UTF-8.html
+/sdcard/android/layout_tests/fast/multicol/float-avoidance.html
/sdcard/android/layout_tests/fast/multicol/negativeColumnWidth.html
/sdcard/android/layout_tests/fast/multicol/column-rules.html
/sdcard/android/layout_tests/fast/multicol/zeroColumnCount.html
@@ -345,7 +1114,6 @@
/sdcard/android/layout_tests/fast/css-generated-content/007.html
/sdcard/android/layout_tests/fast/css-generated-content/009.html
/sdcard/android/layout_tests/fast/css-generated-content/wbr-with-before-content.html
-/sdcard/android/layout_tests/fast/workers/stress-js-execution.html : has expected results
/sdcard/android/layout_tests/fast/lists/decimal-leading-zero.html
/sdcard/android/layout_tests/fast/lists/ol-display-types.html
/sdcard/android/layout_tests/fast/lists/li-style-alpha-huge-value-crash.html
@@ -446,7 +1214,6 @@
/sdcard/android/layout_tests/fast/selectors/044.html
/sdcard/android/layout_tests/fast/selectors/008.html
/sdcard/android/layout_tests/fast/selectors/072.html
-/sdcard/android/layout_tests/fast/selectors/lang-inheritance.html : has expected results
/sdcard/android/layout_tests/fast/selectors/064.html
/sdcard/android/layout_tests/fast/selectors/056.html
/sdcard/android/layout_tests/fast/selectors/018b.html
@@ -463,8 +1230,6 @@
/sdcard/android/layout_tests/fast/selectors/077b.html
/sdcard/android/layout_tests/fast/selectors/177b.html
/sdcard/android/layout_tests/fast/selectors/169a.html
-/sdcard/android/layout_tests/fast/selectors/lang-vs-xml-lang.html : has expected results
-/sdcard/android/layout_tests/fast/selectors/lang-inheritance2.html : has expected results
/sdcard/android/layout_tests/fast/selectors/001.html
/sdcard/android/layout_tests/fast/selectors/021.html
/sdcard/android/layout_tests/fast/selectors/unqualified-hover-quirks.html
@@ -563,19 +1328,13 @@
/sdcard/android/layout_tests/fast/overflow/hidden-scrollbar-resize.html
/sdcard/android/layout_tests/fast/events/autoscroll.html
/sdcard/android/layout_tests/fast/events/5056619.html
-/sdcard/android/layout_tests/fast/events/attempt-scroll-with-no-scrollbars.html : has expected results
/sdcard/android/layout_tests/fast/events/updateLayoutForHitTest.html
/sdcard/android/layout_tests/fast/events/label-focus.html
-/sdcard/android/layout_tests/fast/events/context-onmousedown-event.html : has expected results
-/sdcard/android/layout_tests/fast/events/onsubmit-bubbling.html : has expected results
/sdcard/android/layout_tests/fast/events/onloadFrameCrash.html
/sdcard/android/layout_tests/fast/events/event-listener-on-link.html
/sdcard/android/layout_tests/fast/events/keydown-1.html
/sdcard/android/layout_tests/fast/events/onload-re-entry.html
/sdcard/android/layout_tests/fast/events/standalone-image-drag-to-editable.html
-/sdcard/android/layout_tests/fast/events/pointer-events.html : has expected results
-/sdcard/android/layout_tests/fast/events/pointer-events-2.html : has expected results
-/sdcard/android/layout_tests/fast/events/nested-window-event.html : has expected results
/sdcard/android/layout_tests/fast/events/focusingUnloadedFrame.html
/sdcard/android/layout_tests/fast/events/event-sender-mouse-moved.html
/sdcard/android/layout_tests/fast/events/mouseout-dead-node.html
@@ -655,6 +1414,8 @@
/sdcard/android/layout_tests/fast/box-shadow/border-radius-big.html
/sdcard/android/layout_tests/fast/box-shadow/basic-shadows.html
/sdcard/android/layout_tests/fast/js/exception-linenums-in-html-3.html
+/sdcard/android/layout_tests/fast/js/missing-style-end-tag-js.html
+/sdcard/android/layout_tests/fast/body-propagation/background-image/010.html
/sdcard/android/layout_tests/fast/body-propagation/background-image/001.html
/sdcard/android/layout_tests/fast/body-propagation/background-image/002.html
/sdcard/android/layout_tests/fast/body-propagation/background-image/003.html
@@ -698,21 +1459,13 @@
/sdcard/android/layout_tests/fast/dom/HTMLTableElement/colSpan.html
/sdcard/android/layout_tests/fast/dom/HTMLTableElement/createCaption.html
/sdcard/android/layout_tests/fast/dom/HTMLDocument/frameless-location-bugzilla10837.html
-/sdcard/android/layout_tests/fast/dom/Document/early-document-access.html : has expected results
/sdcard/android/layout_tests/fast/dom/Element/null-offset-parent.html
/sdcard/android/layout_tests/fast/dom/Element/class-attribute-whitespace.html
/sdcard/android/layout_tests/fast/dom/HTMLLinkElement/pending-stylesheet-count.html
/sdcard/android/layout_tests/fast/dom/HTMLStyleElement/insert-parser-generated.html
/sdcard/android/layout_tests/fast/dom/HTMLInputElement/input-image-alt-text.html
-/sdcard/android/layout_tests/fast/dom/Window/timeout-released-on-close.html : has expected results
/sdcard/android/layout_tests/fast/dom/Window/open-existing-pop-up-blocking.html
-/sdcard/android/layout_tests/fast/dom/Window/global-opener-function.html : has expected results
-/sdcard/android/layout_tests/fast/dom/Window/window-property-shadowing.html : has expected results
-/sdcard/android/layout_tests/fast/dom/Window/closure-access-after-navigation-window.html : has expected results
-/sdcard/android/layout_tests/fast/dom/Window/remove-timeout-crash.html : has expected results
-/sdcard/android/layout_tests/fast/dom/Window/window-special-properties.html : has expected results
-/sdcard/android/layout_tests/fast/dom/Window/timeout-callback-scope.html : has expected results
-/sdcard/android/layout_tests/fast/dom/Window/window-property-shadowing-name.html : has expected results
+/sdcard/android/layout_tests/fast/dom/Window/btoa-pnglet.html
/sdcard/android/layout_tests/fast/dom/HTMLObjectElement/vspace-hspace-as-number.html
/sdcard/android/layout_tests/fast/dom/HTMLElement/bdo.html
/sdcard/android/layout_tests/fast/dom/Range/surroundContents-1.html
@@ -742,10 +1495,7 @@
/sdcard/android/layout_tests/fast/dom/inner-text.html
/sdcard/android/layout_tests/fast/dom/isindex-002.html
/sdcard/android/layout_tests/fast/dom/outerText.html
-/sdcard/android/layout_tests/fast/dom/setAttributeNS.html : has expected results
-/sdcard/android/layout_tests/fast/dom/anchor-toString.html : has expected results
-/sdcard/android/layout_tests/fast/dom/documenturi-affects-relative-paths.html : has expected results
-/sdcard/android/layout_tests/fast/dom/setAttribute-using-initial-input-value.html : has expected results
+/sdcard/android/layout_tests/fast/dom/row-inner-text.html
/sdcard/android/layout_tests/fast/dom/blur-contenteditable.html
/sdcard/android/layout_tests/fast/dom/setPrimitiveValue.html
/sdcard/android/layout_tests/fast/dom/delete-contents.html
@@ -756,11 +1506,13 @@
/sdcard/android/layout_tests/fast/dom/comment-not-documentElement.html
/sdcard/android/layout_tests/fast/dom/clone-node-dynamic-style.html
/sdcard/android/layout_tests/fast/dom/css-mediarule-insertRule-update.html
-/sdcard/android/layout_tests/fast/dom/set-frame-src-while-running-script-in-frame.html : has expected results
+/sdcard/android/layout_tests/fast/dom/css-insert-import-rule.html
/sdcard/android/layout_tests/fast/dom/stripNullFromTextNodes.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-put-crash.html : has expected results
-/sdcard/android/layout_tests/fast/dom/document-scripts.html : has expected results
-/sdcard/android/layout_tests/fast/invalid/test-case-tr-th-td-should-not-close-dl-list.html : has expected results
+/sdcard/android/layout_tests/fast/gradients/generated-gradients.html
+/sdcard/android/layout_tests/fast/gradients/list-item-gradient.html
+/sdcard/android/layout_tests/fast/gradients/border-image-gradient-sides-and-corners.html
+/sdcard/android/layout_tests/fast/gradients/simple-gradients.html
+/sdcard/android/layout_tests/fast/gradients/border-image-gradient.html
/sdcard/android/layout_tests/fast/invalid/table-inside-stray-table-content.html
/sdcard/android/layout_tests/fast/invalid/010.html
/sdcard/android/layout_tests/fast/invalid/002.html
@@ -801,14 +1553,14 @@
/sdcard/android/layout_tests/fast/forms/plaintext-mode-2.html
/sdcard/android/layout_tests/fast/forms/input-double-click-selection-gap-bug.html
/sdcard/android/layout_tests/fast/forms/preserveFormDuringResidualStyle.html
+/sdcard/android/layout_tests/fast/forms/search-rtl.html
/sdcard/android/layout_tests/fast/forms/select-change-popup-to-listbox.html
/sdcard/android/layout_tests/fast/forms/input-text-maxlength.html
/sdcard/android/layout_tests/fast/forms/blankbuttons.html
/sdcard/android/layout_tests/fast/forms/password-placeholder-text-security.html
/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label05.html
/sdcard/android/layout_tests/fast/forms/visual-hebrew-text-field.html
-/sdcard/android/layout_tests/fast/forms/textarea-trailing-newline.html : has expected results
-/sdcard/android/layout_tests/fast/forms/legend-access-key.html : has expected results
+/sdcard/android/layout_tests/fast/forms/input-text-option-delete.html
/sdcard/android/layout_tests/fast/forms/textfield-overflow.html
/sdcard/android/layout_tests/fast/forms/005.html
/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label02.html
@@ -828,13 +1580,13 @@
/sdcard/android/layout_tests/fast/forms/option-text-clip.html
/sdcard/android/layout_tests/fast/forms/textfield-drag-into-disabled.html
/sdcard/android/layout_tests/fast/forms/input-text-paste-maxlength.html
-/sdcard/android/layout_tests/fast/forms/tabs-with-modifiers.html : has expected results
-/sdcard/android/layout_tests/fast/forms/saved-state-adoptNode-crash.html : has expected results
+/sdcard/android/layout_tests/fast/forms/formmove.html
+/sdcard/android/layout_tests/fast/forms/select-display-none-style-resolve.html
/sdcard/android/layout_tests/fast/forms/input-readonly-autoscroll.html
/sdcard/android/layout_tests/fast/forms/thumbslider-no-parent-slider.html
/sdcard/android/layout_tests/fast/forms/textfield-outline.html
/sdcard/android/layout_tests/fast/forms/button-text-transform.html
-/sdcard/android/layout_tests/fast/forms/radio-check-click-and-drag.html : has expected results
+/sdcard/android/layout_tests/fast/forms/listbox-clip.html
/sdcard/android/layout_tests/fast/forms/textarea-scroll-height.html
/sdcard/android/layout_tests/fast/forms/button-table-styles.html
/sdcard/android/layout_tests/fast/forms/textarea-setinnerhtml.html
@@ -842,14 +1594,16 @@
/sdcard/android/layout_tests/fast/forms/box-shadow-override.html
/sdcard/android/layout_tests/fast/forms/button-cannot-be-nested.html
/sdcard/android/layout_tests/fast/forms/input-type-change.html
+/sdcard/android/layout_tests/fast/forms/searchfield-heights.html
/sdcard/android/layout_tests/fast/forms/checkbox-radio-onchange.html
/sdcard/android/layout_tests/fast/forms/input-spaces.html
-/sdcard/android/layout_tests/fast/forms/dragging-to-file-input.html : has expected results
/sdcard/android/layout_tests/fast/forms/menulist-option-wrap.html
+/sdcard/android/layout_tests/fast/forms/select-empty-option-height.html
+/sdcard/android/layout_tests/fast/forms/textarea-scrollbar.html
/sdcard/android/layout_tests/fast/forms/float-before-fieldset.html
/sdcard/android/layout_tests/fast/forms/radio_checked.html
/sdcard/android/layout_tests/fast/forms/minWidthPercent.html
-/sdcard/android/layout_tests/fast/forms/form-post-urlencoded.html : has expected results
+/sdcard/android/layout_tests/fast/forms/input-appearance-focus.html
/sdcard/android/layout_tests/fast/forms/input-value.html
/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label06.html
/sdcard/android/layout_tests/fast/forms/placeholder-pseudo-style.html
@@ -868,11 +1622,16 @@
/sdcard/android/layout_tests/fast/forms/input-text-click-outside.html
/sdcard/android/layout_tests/fast/forms/input-baseline.html
/sdcard/android/layout_tests/fast/forms/targeted-frame-submission.html
+/sdcard/android/layout_tests/fast/forms/input-text-scroll-left-on-blur.html
+/sdcard/android/layout_tests/fast/forms/form-element-geometry.html
/sdcard/android/layout_tests/fast/forms/input-table.html
+/sdcard/android/layout_tests/fast/forms/textarea-scrolled-type.html
/sdcard/android/layout_tests/fast/forms/select-change-listbox-to-popup.html
/sdcard/android/layout_tests/fast/forms/select-align.html
/sdcard/android/layout_tests/fast/forms/radio_checked_dynamic.html
/sdcard/android/layout_tests/fast/forms/select-writing-direction-natural.html
+/sdcard/android/layout_tests/fast/forms/search-cancel-button-style-sharing.html
+/sdcard/android/layout_tests/fast/forms/tabbing-input-iframe.html
/sdcard/android/layout_tests/fast/forms/hidden-input-file.html
/sdcard/android/layout_tests/fast/forms/menulist-deselect-update.html
/sdcard/android/layout_tests/fast/forms/button-sizes.html
@@ -899,9 +1658,11 @@
/sdcard/android/layout_tests/fast/forms/listbox-selection-2.html
/sdcard/android/layout_tests/fast/forms/input-readonly-empty.html
/sdcard/android/layout_tests/fast/forms/input-align-image.html
-/sdcard/android/layout_tests/fast/forms/input-selection-hidden.html : has expected results
+/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label07.html
/sdcard/android/layout_tests/fast/forms/option-index.html
+/sdcard/android/layout_tests/fast/forms/menulist-clip.html
/sdcard/android/layout_tests/fast/forms/indeterminate.html
+/sdcard/android/layout_tests/fast/forms/search-display-none-cancel-button.html
/sdcard/android/layout_tests/fast/forms/negativeLineHeight.html
/sdcard/android/layout_tests/fast/forms/007.html
/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_label04.html
@@ -916,10 +1677,9 @@
/sdcard/android/layout_tests/fast/forms/search-placeholder-value-changed.html
/sdcard/android/layout_tests/fast/forms/input-field-text-truncated.html
/sdcard/android/layout_tests/fast/forms/floating-textfield-relayout.html
-/sdcard/android/layout_tests/fast/forms/add-remove-form-elements-stress-test.html : has expected results
/sdcard/android/layout_tests/fast/forms/button-inner-block-reuse.html
/sdcard/android/layout_tests/fast/forms/input-type-text-min-width.html
-/sdcard/android/layout_tests/fast/forms/onchange-enter-submit.html : has expected results
+/sdcard/android/layout_tests/fast/forms/001.html
/sdcard/android/layout_tests/fast/forms/slider-thumb-shared-style.html
/sdcard/android/layout_tests/fast/forms/option-script.html
/sdcard/android/layout_tests/fast/forms/input-paste-undo.html
@@ -934,6 +1694,7 @@
/sdcard/android/layout_tests/fast/forms/button-submit.html
/sdcard/android/layout_tests/fast/forms/disabled-select-change-index.html
/sdcard/android/layout_tests/fast/forms/formmove3.html
+/sdcard/android/layout_tests/fast/forms/form-hides-table.html
/sdcard/android/layout_tests/fast/forms/listbox-width-change.html
/sdcard/android/layout_tests/fast/forms/input-text-self-emptying-click.html
/sdcard/android/layout_tests/fast/forms/input-appearance-bkcolor.html
@@ -941,7 +1702,7 @@
/sdcard/android/layout_tests/fast/forms/search-transformed.html
/sdcard/android/layout_tests/fast/forms/image-border.html
/sdcard/android/layout_tests/fast/forms/encoding-test.html
-/sdcard/android/layout_tests/fast/forms/input-type-change-in-onfocus-mouse.html : has expected results
+/sdcard/android/layout_tests/fast/forms/control-clip.html
/sdcard/android/layout_tests/fast/compact/001.html
/sdcard/android/layout_tests/fast/compact/002.html
/sdcard/android/layout_tests/fast/compact/003.html
@@ -1138,7 +1899,6 @@
/sdcard/android/layout_tests/fast/css/first-letter-skip-out-of-flow.html
/sdcard/android/layout_tests/fast/css/font-face-multiple-remote-sources.html
/sdcard/android/layout_tests/fast/css/hover-subselector.html
-/sdcard/android/layout_tests/fast/css/text-align.html : has expected results
/sdcard/android/layout_tests/fast/css/margin-bottom-form-element-strict.html
/sdcard/android/layout_tests/fast/css/shadow-multiple.html
/sdcard/android/layout_tests/fast/css/import_with_baseurl.html
@@ -1185,6 +1945,7 @@
/sdcard/android/layout_tests/fast/css/zoom-property-parsing.html
/sdcard/android/layout_tests/fast/css/style-outside-head.html
/sdcard/android/layout_tests/fast/css/first-letter-capitalized.html
+/sdcard/android/layout_tests/fast/css/font-face-locally-installed.html
/sdcard/android/layout_tests/fast/css/word-space-extra.html
/sdcard/android/layout_tests/fast/css/first-letter-float.html
/sdcard/android/layout_tests/fast/css/simple-selector-chain-parsing.html
@@ -1192,6 +1953,7 @@
/sdcard/android/layout_tests/fast/css/continuationCrash.html
/sdcard/android/layout_tests/fast/css/vertical-align-lengths.html
/sdcard/android/layout_tests/fast/css/first-child-pseudo-class.html
+/sdcard/android/layout_tests/fast/css/beforeSelectorOnCodeElement.html
/sdcard/android/layout_tests/fast/css/getFloatValueForUnit.html
/sdcard/android/layout_tests/fast/css/first-letter-detach.html
/sdcard/android/layout_tests/fast/css/line-height-font-order.html
@@ -1210,7 +1972,6 @@
/sdcard/android/layout_tests/fast/css/link-outside-head.html
/sdcard/android/layout_tests/fast/css/font-size-negative.html
/sdcard/android/layout_tests/fast/css/position-negative-top-margin.html
-/sdcard/android/layout_tests/fast/css/invalid-percentage-property.html : has expected results
/sdcard/android/layout_tests/fast/css/ZeroOpacityLayers.html
/sdcard/android/layout_tests/fast/css/only-of-type-pseudo-class.html
/sdcard/android/layout_tests/fast/css/004.html
@@ -1223,6 +1984,7 @@
/sdcard/android/layout_tests/fast/css/textCapitalizeEdgeCases.html
/sdcard/android/layout_tests/fast/css/001.html
/sdcard/android/layout_tests/fast/css/hsl-color.html
+/sdcard/android/layout_tests/fast/css/font-face-implicit-local-font.html
/sdcard/android/layout_tests/fast/css/first-letter-recalculation.html
/sdcard/android/layout_tests/fast/css/inline-properties-important.html
/sdcard/android/layout_tests/fast/css/dynamic-sibling-selector.html
@@ -1502,7 +2264,6 @@
/sdcard/android/layout_tests/fast/parser/001.html
/sdcard/android/layout_tests/fast/parser/open-comment-in-textarea.html
/sdcard/android/layout_tests/fast/parser/tabs-in-scripts.html
-/sdcard/android/layout_tests/fast/parser/external-entities-in-xslt.xml : has expected results
/sdcard/android/layout_tests/fast/parser/parseCommentsInTitles.html
/sdcard/android/layout_tests/fast/parser/remove-block-in-residual-style.html
/sdcard/android/layout_tests/fast/parser/open-comment-in-style.html
@@ -1523,7 +2284,6 @@
/sdcard/android/layout_tests/fast/layers/scroll-rect-to-visible.html
/sdcard/android/layout_tests/fast/layers/opacity-stacking.html
/sdcard/android/layout_tests/fast/history/clicked-link-is-visited.html
-/sdcard/android/layout_tests/fast/history/history_reload.html : has expected results
/sdcard/android/layout_tests/fast/backgrounds/repeat/mask-negative-offset-repeat.html
/sdcard/android/layout_tests/fast/backgrounds/repeat/negative-offset-repeat.html
/sdcard/android/layout_tests/fast/backgrounds/repeat/negative-offset-repeat-transformed.html
@@ -1681,20 +2441,29 @@
/sdcard/android/layout_tests/fast/repaint/layer-child-outline.html
/sdcard/android/layout_tests/fast/loader/start-load-in-unload.html
/sdcard/android/layout_tests/fast/loader/text-document-wrapping.html
+/sdcard/android/layout_tests/fast/xsl/document-function.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-extra-content-at-end.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-enc.xml
+/sdcard/android/layout_tests/fast/xsl/xslt_unicode.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-import-depth.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-enc16.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-enc16to16.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-missing-namespace-in-xslt.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-enc-cyr.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-relative-path.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-mismatched-tags-in-xslt.xml
+/sdcard/android/layout_tests/fast/xsl/xslt-entity.xml
/sdcard/android/layout_tests/fast/canvas/fillrect-gradient-zero-stops.html
/sdcard/android/layout_tests/fast/canvas/canvas-transforms-during-path.html
/sdcard/android/layout_tests/fast/canvas/drawImage.html
/sdcard/android/layout_tests/fast/canvas/shadow-offset-7.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-non-invertible.html : has expected results
/sdcard/android/layout_tests/fast/canvas/shadow-offset-4.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-infinity.html : has expected results
/sdcard/android/layout_tests/fast/canvas/canvas-text-baseline.html
/sdcard/android/layout_tests/fast/canvas/canvas-as-image-incremental-repaint.html
/sdcard/android/layout_tests/fast/canvas/shadow-offset-1.html
/sdcard/android/layout_tests/fast/canvas/canvas-size-change-after-layout.html
/sdcard/android/layout_tests/fast/canvas/canvas-resize-reset.html
/sdcard/android/layout_tests/fast/canvas/canvas-bg.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-skewed.html : has expected results
/sdcard/android/layout_tests/fast/canvas/zero-size-fill-rect.html
/sdcard/android/layout_tests/fast/canvas/shadow-offset-6.html
/sdcard/android/layout_tests/fast/canvas/patternfill-repeat.html
@@ -1704,17 +2473,14 @@
/sdcard/android/layout_tests/fast/canvas/gradient-add-second-start-end-stop.html
/sdcard/android/layout_tests/fast/canvas/quadraticCurveTo.xml
/sdcard/android/layout_tests/fast/canvas/fill-stroke-clip-reset-path.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-nan.html : has expected results
/sdcard/android/layout_tests/fast/canvas/canvas-text-alignment.html
/sdcard/android/layout_tests/fast/canvas/canvas-incremental-repaint.html
/sdcard/android/layout_tests/fast/canvas/canvasDrawingIntoSelf.html
/sdcard/android/layout_tests/fast/canvas/canvas-as-image.html
/sdcard/android/layout_tests/fast/canvas/canvas-before-css.html
/sdcard/android/layout_tests/fast/canvas/canvas-incremental-repaint-2.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-identity.html : has expected results
/sdcard/android/layout_tests/fast/canvas/shadow-offset-5.html
/sdcard/android/layout_tests/fast/canvas/fillrect_gradient.html
-/sdcard/android/layout_tests/fast/canvas/canvas-transform-multiply.html : has expected results
/sdcard/android/layout_tests/fast/canvas/shadow-offset-2.html
/sdcard/android/layout_tests/fast/frames/contentWindow_Frame.html
/sdcard/android/layout_tests/fast/frames/onlyCommentInIFrame.html
@@ -1739,15 +2505,1576 @@
/sdcard/android/layout_tests/fast/frames/iframe-text-contents.html
/sdcard/android/layout_tests/fast/frames/frame-scrolling-attribute.html
/sdcard/android/layout_tests/fast/frames/contentWindow_iFrame.html
-/sdcard/android/layout_tests/fast/frames/frame-length-fractional.html : has expected results
/sdcard/android/layout_tests/fast/frames/calculate-fixed.html
/sdcard/android/layout_tests/fast/frames/frame-element-name.html
/sdcard/android/layout_tests/fast/frames/frame-set-whitespace-attributes.html
/sdcard/android/layout_tests/fast/frames/iframe-with-frameborder.html
/sdcard/android/layout_tests/fast/frames/frameElement-iframe.html
-/sdcard/android/layout_tests/fast/frames/iframe-name-and-id.html : has expected results
/sdcard/android/layout_tests/fast/reflections/inline-crash.html
/sdcard/android/layout_tests/fast/reflections/reflection-nesting.html
/sdcard/android/layout_tests/fast/reflections/reflection-overflow-hidden.html
/sdcard/android/layout_tests/fast/reflections/table-cell.html
+/sdcard/android/layout_tests/fast/reflections/reflection-masks.html
/sdcard/android/layout_tests/fast/reflections/reflection-direction.html
+/sdcard/android/layout_tests/transforms/2d/zoom-menulist.html
+/sdcard/android/layout_tests/transforms/2d/transform-origin-borderbox.html
+/sdcard/android/layout_tests/transforms/2d/transform-borderbox.html
+/sdcard/android/layout_tests/transforms/2d/compound-transforms-vs-containers.html
+/sdcard/android/layout_tests/animations/animation-drt-api-multiple-keyframes.html
+/sdcard/android/layout_tests/animations/animation-drt-api.html
+/sdcard/android/layout_tests/scrollbars/scrollbar-orientation.html
+/sdcard/android/layout_tests/scrollbars/scrollbar-buttons.html
+/sdcard/android/layout_tests/scrollbars/basic-scrollbar.html
+/sdcard/android/layout_tests/scrollbars/overflow-scrollbar-combinations.html
+/sdcard/android/layout_tests/scrollbars/disabled-scrollbar.html
+/sdcard/android/layout_tests/scrollbars/listbox-scrollbar-combinations.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-03-c.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1205-c563-list-type-00-b.html
+/sdcard/android/layout_tests/css2.1/t090402-c42-ibx-pad-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t120401-scope-00-b.html
+/sdcard/android/layout_tests/css2.1/t010403-shand-border-00-c.html
+/sdcard/android/layout_tests/css2.1/t0805-c5518-ibrdr-t-00-a.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-03-b.html
+/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-14-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-34-d.html
+/sdcard/android/layout_tests/css2.1/t1204-implied-00-b.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-03-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-54-d.html
+/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-00-c-a.html
+/sdcard/android/layout_tests/css2.1/t0905-c5526-fltclr-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/bogus-color-span.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-74-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-03-b-a.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-04-c-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-94-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-03-b-a.html
+/sdcard/android/layout_tests/css2.1/t040307-syntax-01-b.html
+/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-04-d-ag.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-06-b.html
+/sdcard/android/layout_tests/css2.1/t040306-c63-color-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-02-b.html
+/sdcard/android/layout_tests/css2.1/t080301-c411-vt-mrgn-00-b.html
+/sdcard/android/layout_tests/css2.1/t010403-shand-font-03-b.html
+/sdcard/android/layout_tests/css2.1/t051103-c21-focus-ln-00-e-i.html
+/sdcard/android/layout_tests/css2.1/t120403-display-none-00-c.html
+/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-12-c.html
+/sdcard/android/layout_tests/css2.1/t0805-c5515-ibrdr-00-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5520-brdr-b-00-a.html
+/sdcard/android/layout_tests/css2.1/t1505-c524-font-var-00-b.html
+/sdcard/android/layout_tests/css2.1/t0509-c15-ids-00-a.html
+/sdcard/android/layout_tests/css2.1/t060403-c21-pseu-cls-00-e-i.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-03-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-12-b.html
+/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-04-f.html
+/sdcard/android/layout_tests/css2.1/t040303-c62-percent-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-23-d.html
+/sdcard/android/layout_tests/css2.1/t140201-c535-bg-fixd-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-43-d.html
+/sdcard/android/layout_tests/css2.1/t1204-increment-02-c-o.html
+/sdcard/android/layout_tests/css2.1/t0602-c13-inh-underlin-00-e.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-63-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-83-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-16-f.html
+/sdcard/android/layout_tests/css2.1/t040302-c61-phys-len-00-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5516-ibrdr-c-00-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5521-brdr-l-01-e.html
+/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-03-d-agi.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-06-b.html
+/sdcard/android/layout_tests/css2.1/t0402-syntax-03-f.html
+/sdcard/android/layout_tests/css2.1/t050803-c14-classes-00-e.html
+/sdcard/android/layout_tests/css2.1/t140201-c537-bgfxps-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t1002-c5523-width-02-b-g.html
+/sdcard/android/layout_tests/css2.1/t1004-c5524-width-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-11-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-06-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0805-c5522-brdr-02-e.html
+/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-anch-00-e-i.html
+/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-01-f-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-04-b-ag.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-01-c.html
+/sdcard/android/layout_tests/css2.1/t040102-keywords-00-b.html
+/sdcard/android/layout_tests/css2.1/t0505-c16-descendant-02-e.html
+/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-03-f-a.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-09-b.html
+/sdcard/android/layout_tests/css2.1/t1204-root-e.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-fit-01-d-g.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-01-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-12-d.html
+/sdcard/android/layout_tests/css2.1/t090501-c5525-flt-r-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-32-d.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-01-b.html
+/sdcard/android/layout_tests/css2.1/t1004-c43-rpl-bbx-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgre-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-02-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-52-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-02-b.html
+/sdcard/android/layout_tests/css2.1/t040109-c17-comments-00-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-72-d.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-01-c-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-92-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-01-d-g.html
+/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-03-b-g.html
+/sdcard/android/layout_tests/css2.1/t1204-multiple-01-c.html
+/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-03-c-ag.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-04-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-00-b.html
+/sdcard/android/layout_tests/css2.1/t1602-c43-center-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t140201-c532-bgcolor-00-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-03-c.html
+/sdcard/android/layout_tests/css2.1/t010403-shand-font-01-b.html
+/sdcard/android/layout_tests/css2.1/t1005-c5524-width-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t1601-c547-indent-01-d.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-10-c.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-01-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-02-c.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-04-c.html
+/sdcard/android/layout_tests/css2.1/t051103-dom-hover-01-c-io.html
+/sdcard/android/layout_tests/css2.1/t1604-c542-letter-sp-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-08-c.html
+/sdcard/android/layout_tests/css2.1/t120401-scope-02-c.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-01-d.html
+/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-02-f.html
+/sdcard/android/layout_tests/css2.1/t1204-reset-00-c-o.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-21-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-41-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-01-c-g.html
+/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-61-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-08-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-81-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-19-d.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-04-b.html
+/sdcard/android/layout_tests/css2.1/t1604-c541-word-sp-01-b-a.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-39-d.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-08-b.html
+/sdcard/android/layout_tests/css2.1/t0402-syntax-01-f.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-59-d.html
+/sdcard/android/layout_tests/css2.1/t1205-c565-list-pos-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-79-d.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-10-c.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-99-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t040306-syntax-01-f.html
+/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-01-b-a.html
+/sdcard/android/layout_tests/css2.1/t040105-atrule-04-b.html
+/sdcard/android/layout_tests/css2.1/t0505-c16-descendant-00-e.html
+/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-02-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5519-brdr-r-01-e.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-07-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5510-padn-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0805-c5517-ibrdr-s-00-a.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-10-d.html
+/sdcard/android/layout_tests/css2.1/t040105-import-00-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-03-b-a.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-30-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-02-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-50-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-03-b-a.html
+/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-02-d-ag.html
+/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-70-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-08-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-90-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-28-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-48-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-68-d.html
+/sdcard/android/layout_tests/css2.1/t1402-c45-bg-canvas-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-88-d.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-02-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5521-ibrdr-l-00-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5522-brdr-00-b.html
+/sdcard/android/layout_tests/css2.1/t1606-c562-white-sp-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-02-c.html
+/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-00-a-ag.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-06-c.html
+/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-00-f.html
+/sdcard/android/layout_tests/css2.1/t1204-reset-02-c-o.html
+/sdcard/android/layout_tests/css2.1/t0602-c13-inheritance-00-e.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-02-d.html
+/sdcard/android/layout_tests/css2.1/t1205-c566-list-stl-01-c-g.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-06-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-17-d.html
+/sdcard/android/layout_tests/css2.1/t100304-c43-rpl-bbx-00-d-g.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t1205-c566-list-stl-00-e-ag.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-03-c-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-37-d.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-06-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-57-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5510-padn-02-f.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-77-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-97-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t090204-display-change-01-b-ao.html
+/sdcard/android/layout_tests/css2.1/t040302-c61-ex-len-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t040105-atrule-02-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-00-b.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-09-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-05-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-02-c.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-06-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-01-c-a.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-00-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-17-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-01-c-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-00-b.html
+/sdcard/android/layout_tests/css2.1/t140201-c536-bgpos-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t100303-c412-blockw-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t120401-scope-04-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5506-ipadn-t-01-b-a.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-06-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-15-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-26-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5521-brdr-l-00-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-02-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-46-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-02-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-66-d.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-03-c-ag.html
+/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-02-d-agi.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-04-f-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-86-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5512-ibrdr-rw-00-a.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-00-b.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltblck-01-d.html
+/sdcard/android/layout_tests/css2.1/t0402-syntax-06-f.html
+/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-03-d-ag.html
+/sdcard/android/layout_tests/css2.1/t0805-c5515-brdr-w-00-a.html
+/sdcard/android/layout_tests/css2.1/t051202-c24-first-lttr-00-b.html
+/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-02-e.html
+/sdcard/android/layout_tests/css2.1/t0804-c5510-padn-01-e-a.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltinln-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-14-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5518-brdr-t-01-e.html
+/sdcard/android/layout_tests/css2.1/t040105-atkeyw-01-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-04-c.html
+/sdcard/android/layout_tests/css2.1/t1205-c563-list-type-01-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-18-f.html
+/sdcard/android/layout_tests/css2.1/t0509-id-sel-syntax-01-f.html
+/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-01-d-ag.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-00-d.html
+/sdcard/android/layout_tests/css2.1/t1601-c547-indent-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-04-b.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-flthw-00-c-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-15-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5522-brdr-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-35-d.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-00-b.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-04-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-55-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-75-d.html
+/sdcard/android/layout_tests/css2.1/t1205-c564-list-img-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-95-d.html
+/sdcard/android/layout_tests/css2.1/t120403-visibility-00-c.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-02-b-a.html
+/sdcard/android/layout_tests/css2.1/t051103-c21-activ-ln-00-e-i.html
+/sdcard/android/layout_tests/css2.1/t0801-c412-hz-box-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-02-d-g.html
+/sdcard/android/layout_tests/css2.1/t1605-c545-txttrans-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t040105-atrule-00-b.html
+/sdcard/android/layout_tests/css2.1/t100801-c548-leadin-00-d-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-05-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-03-b-a.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-07-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-03-b.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-13-c.html
+/sdcard/android/layout_tests/css2.1/t1204-order-01-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5510-ipadn-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-04-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-13-b.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgre-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1504-c523-font-style-00-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-01-c-a.html
+/sdcard/android/layout_tests/css2.1/t1204-increment-01-c-o.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-24-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-44-d.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-64-d.html
+/sdcard/android/layout_tests/css2.1/t1204-implied-02-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-84-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5521-brdr-l-02-e.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-07-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-02-f.html
+/sdcard/android/layout_tests/css2.1/t0402-syntax-04-f.html
+/sdcard/android/layout_tests/css2.1/t1002-c5523-width-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t0805-c5519-brdr-r-00-a.html
+/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-00-e.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-12-b.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-02-c.html
+/sdcard/android/layout_tests/css2.1/t040102-keywords-01-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5503-imrgn-b-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5513-ibrdr-bw-00-a.html
+/sdcard/android/layout_tests/css2.1/css1_forward_compatible_parsing.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-03-f-g.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-02-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-13-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c5526-flthw-00-c-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-33-d.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-02-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-53-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5512-brdr-rw-03-b.html
+/sdcard/android/layout_tests/css2.1/t040109-c17-comments-01-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-73-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-93-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5511-ibrdr-tw-00-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-02-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-05-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-01-b.html
+/sdcard/android/layout_tests/css2.1/t1005-c5524-width-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-wrap-01-d-g.html
+/sdcard/android/layout_tests/css2.1/t010403-shand-font-02-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5515-brdr-w-02-b.html
+/sdcard/android/layout_tests/css2.1/t060401-c32-cascading-00-b.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltcont-00-d-g.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-11-c.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-16-c.html
+/sdcard/android/layout_tests/css2.1/t0509-id-sel-syntax-02-b.html
+/sdcard/android/layout_tests/css2.1/t090501-c5525-flt-l-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-09-c.html
+/sdcard/android/layout_tests/css2.1/t050201-c12-grouping-00-b.html
+/sdcard/android/layout_tests/css2.1/t120401-scope-03-c.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-02-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-wrap-00-e.html
+/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-03-f.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-11-b.html
+/sdcard/android/layout_tests/css2.1/t1506-c525-font-wt-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-22-d.html
+/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-01-d-ag.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-00-c-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-42-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-62-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltmult-00-d-g.html
+/sdcard/android/layout_tests/css2.1/t1401-c531-color-00-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5514-ibrdr-lw-00-a.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-09-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-82-d.html
+/sdcard/android/layout_tests/css2.1/t1604-c541-word-sp-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5515-brdr-w-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-04-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-09-b.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-05-c-ag.html
+/sdcard/android/layout_tests/css2.1/t0402-syntax-02-f.html
+/sdcard/android/layout_tests/css2.1/t0803-c5503-mrgn-b-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5517-brdr-s-00-c.html
+/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t100801-c42-ibx-ht-00-d-a.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-00-c.html
+/sdcard/android/layout_tests/css2.1/t0805-c5513-brdr-bw-03-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5506-padn-t-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t0505-c16-descendant-01-e.html
+/sdcard/android/layout_tests/css2.1/t0805-c5519-brdr-r-02-e.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-08-b.html
+/sdcard/android/layout_tests/css2.1/t051103-c21-hover-ln-00-e-i.html
+/sdcard/android/layout_tests/css2.1/t120403-content-none-00-c.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-00-b.html
+/sdcard/android/layout_tests/css2.1/t040105-import-01-b.html
+/sdcard/android/layout_tests/css2.1/t040103-case-01-c.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-11-d.html
+/sdcard/android/layout_tests/css2.1/t09-c5526c-display-00-e.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltblck-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-31-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5514-brdr-lw-03-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-51-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-71-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-09-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-91-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwrap-00-b.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-fit-00-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-29-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-01-e-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t1004-c43-rpl-ibx-00-d-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-49-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-69-d.html
+/sdcard/android/layout_tests/css2.1/t1204-multiple-00-c.html
+/sdcard/android/layout_tests/css2.1/t140201-c533-bgimage-01-b-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-89-d.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-03-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-mrgn-l-02-c.html
+/sdcard/android/layout_tests/css2.1/t0805-c5518-brdr-t-00-a.html
+/sdcard/android/layout_tests/css2.1/t010403-shand-font-00-b.html
+/sdcard/android/layout_tests/css2.1/t0510-c25-pseudo-elmnt-00-c.html
+/sdcard/android/layout_tests/css2.1/t0803-c5505-imrgn-00-a-ag.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-imrgn-r-05-b-ag.html
+/sdcard/android/layout_tests/css2.1/t060402-c31-important-00-b.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-00-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c414-flt-03-c.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-07-c.html
+/sdcard/android/layout_tests/css2.1/t1204-order-00-c.html
+/sdcard/android/layout_tests/css2.1/t120401-scope-01-c.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-00-d.html
+/sdcard/android/layout_tests/css2.1/t0402-c71-fwd-parsing-01-f.html
+/sdcard/android/layout_tests/css2.1/t1604-c542-letter-sp-01-b-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5520-brdr-b-01-e.html
+/sdcard/android/layout_tests/css2.1/t140201-c536-bgpos-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-20-d.html
+/sdcard/android/layout_tests/css2.1/t0509-c15-ids-01-e.html
+/sdcard/android/layout_tests/css2.1/t1204-reset-01-c-o.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-40-d.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-03-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-60-d.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltwidth-02-c-g.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltclr-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-07-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-80-d.html
+/sdcard/android/layout_tests/css2.1/t1204-implied-01-c.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-18-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-ipadn-r-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-03-b.html
+/sdcard/android/layout_tests/css2.1/t140201-c534-bgreps-02-c-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-38-d.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-07-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-58-d.html
+/sdcard/android/layout_tests/css2.1/t0803-c5505-mrgn-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t100801-c544-valgn-04-d-agi.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-78-d.html
+/sdcard/android/layout_tests/css2.1/t100801-c548-ln-ht-02-b-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-98-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-01-b-a.html
+/sdcard/android/layout_tests/css2.1/t040105-atrule-03-b.html
+/sdcard/android/layout_tests/css2.1/t1507-c526-font-sz-02-b-a.html
+/sdcard/android/layout_tests/css2.1/t0805-c5522-ibrdr-00-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5502-mrgn-r-03-c.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-06-b.html
+/sdcard/android/layout_tests/css2.1/t0905-c5525-fltmrgn-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t051103-dom-hover-02-c-io.html
+/sdcard/android/layout_tests/css2.1/t0804-c5506-ipadn-t-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t040304-c64-uri-00-a-g.html
+/sdcard/android/layout_tests/css2.1/t0803-c5501-mrgn-t-00-b-a.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-07-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-27-d.html
+/sdcard/android/layout_tests/css2.1/t0805-c5511-brdr-tw-03-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-47-d.html
+/sdcard/android/layout_tests/css2.1/t060403-c21-pseu-id-00-e-i.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-67-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-87-d.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-01-b.html
+/sdcard/android/layout_tests/css2.1/t0603-c11-import-00-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-04-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1503-c522-font-family-00-b.html
+/sdcard/android/layout_tests/css2.1/t090501-c414-flt-ln-01-d-g.html
+/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-03-e.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-15-b.html
+/sdcard/android/layout_tests/css2.1/t040105-atkeyw-02-b.html
+/sdcard/android/layout_tests/css2.1/t0805-c5519-ibrdr-r-00-a.html
+/sdcard/android/layout_tests/css2.1/t040103-ident-05-c.html
+/sdcard/android/layout_tests/css2.1/t0602-inherit-bdr-pad-b-00.html
+/sdcard/android/layout_tests/css2.1/t040302-c61-rel-len-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-00-c-ag.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-ipadn-l-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t0805-c5520-ibrdr-b-00-a.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-05-b.html
+/sdcard/android/layout_tests/css2.1/t1008-c44-ln-box-03-d-ag.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-16-d.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-01-b.html
+/sdcard/android/layout_tests/css2.1/t100304-c43-rpl-bbx-01-d-g.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-36-d.html
+/sdcard/android/layout_tests/css2.1/t1001-abs-pos-cb-05-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-56-d.html
+/sdcard/android/layout_tests/css2.1/t0804-c5509-padn-l-02-f.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-76-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-96-d.html
+/sdcard/android/layout_tests/css2.1/t051202-c26-psudo-nest-00-c.html
+/sdcard/android/layout_tests/css2.1/t040105-atrule-01-b.html
+/sdcard/android/layout_tests/css2.1/t0804-c5508-ipadn-b-02-b-a.html
+/sdcard/android/layout_tests/css2.1/t0803-c5501-imrgn-t-00-b-ag.html
+/sdcard/android/layout_tests/css2.1/t140201-c532-bgcolor-01-b.html
+/sdcard/android/layout_tests/css2.1/t1508-c527-font-08-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-04-b.html
+/sdcard/android/layout_tests/css2.1/t040103-case-00-b.html
+/sdcard/android/layout_tests/css2.1/t1504-c543-txt-decor-00-d-g.html
+/sdcard/android/layout_tests/css2.1/t0805-c5516-brdr-c-00-a.html
+/sdcard/android/layout_tests/css2.1/t0804-c5506-ipadn-t-02-b-a.html
+/sdcard/android/layout_tests/css2.1/t1204-increment-00-c-o.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-05-d.html
+/sdcard/android/layout_tests/css2.1/t1202-counter-14-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-25-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-45-d.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-65-d.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-02-d.html
+/sdcard/android/layout_tests/css2.1/t1602-c546-txt-align-00-b.html
+/sdcard/android/layout_tests/css2.1/t170602-bdr-conflct-w-85-d.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-05-c.html
+/sdcard/android/layout_tests/css2.1/t040103-escapes-08-b.html
+/sdcard/android/layout_tests/css2.1/t0803-c5504-imrgn-l-01-b-ag.html
+/sdcard/android/layout_tests/css2.1/t1002-c5523-width-00-b-g.html
+/sdcard/android/layout_tests/css2.1/t0804-c5507-padn-r-03-f.html
+/sdcard/android/layout_tests/css2.1/t0402-syntax-05-f.html
+/sdcard/android/layout_tests/css2.1/t1205-c561-list-displ-00-b.html
+/sdcard/android/layout_tests/css2.1/t0511-c21-pseud-link-01-e.html
+/sdcard/android/layout_tests/css2.1/t051201-c23-first-line-00-b.html
+/sdcard/android/layout_tests/css2.1/t1202-counters-13-b.html
+/sdcard/android/layout_tests/css2.1/t140201-c533-bgimage-00-a.html
+/sdcard/android/layout_tests/css2.1/t040105-atkeyw-00-b.html
+/sdcard/android/layout_tests/css1/color_and_background/background_color.html
+/sdcard/android/layout_tests/css1/color_and_background/color.html
+/sdcard/android/layout_tests/css1/color_and_background/background.html
+/sdcard/android/layout_tests/css1/color_and_background/background_repeat.html
+/sdcard/android/layout_tests/css1/color_and_background/background_image.html
+/sdcard/android/layout_tests/css1/color_and_background/background_position.html
+/sdcard/android/layout_tests/css1/color_and_background/background_attachment.html
+/sdcard/android/layout_tests/css1/pseudo/firstline.html
+/sdcard/android/layout_tests/css1/pseudo/pseudo_elements_in_selectors.html
+/sdcard/android/layout_tests/css1/pseudo/multiple_pseudo_elements.html
+/sdcard/android/layout_tests/css1/pseudo/firstletter.html
+/sdcard/android/layout_tests/css1/pseudo/anchor.html
+/sdcard/android/layout_tests/css1/text_properties/text_align.html
+/sdcard/android/layout_tests/css1/text_properties/line_height.html
+/sdcard/android/layout_tests/css1/text_properties/text_transform.html
+/sdcard/android/layout_tests/css1/text_properties/word_spacing.html
+/sdcard/android/layout_tests/css1/text_properties/letter_spacing.html
+/sdcard/android/layout_tests/css1/text_properties/vertical_align.html
+/sdcard/android/layout_tests/css1/text_properties/text_indent.html
+/sdcard/android/layout_tests/css1/text_properties/text_decoration.html
+/sdcard/android/layout_tests/css1/basic/containment.html
+/sdcard/android/layout_tests/css1/basic/id_as_selector.html
+/sdcard/android/layout_tests/css1/basic/comments.html
+/sdcard/android/layout_tests/css1/basic/class_as_selector.html
+/sdcard/android/layout_tests/css1/basic/contextual_selectors.html
+/sdcard/android/layout_tests/css1/basic/inheritance.html
+/sdcard/android/layout_tests/css1/basic/grouping.html
+/sdcard/android/layout_tests/css1/font_properties/font_weight.html
+/sdcard/android/layout_tests/css1/font_properties/font_size.html
+/sdcard/android/layout_tests/css1/font_properties/font.html
+/sdcard/android/layout_tests/css1/font_properties/font_style.html
+/sdcard/android/layout_tests/css1/font_properties/font_family.html
+/sdcard/android/layout_tests/css1/font_properties/font_variant.html
+/sdcard/android/layout_tests/css1/units/percentage_units.html
+/sdcard/android/layout_tests/css1/units/color_units.html
+/sdcard/android/layout_tests/css1/units/length_units.html
+/sdcard/android/layout_tests/css1/units/urls.html
+/sdcard/android/layout_tests/css1/cascade/important.html
+/sdcard/android/layout_tests/css1/cascade/cascade_order.html
+/sdcard/android/layout_tests/css1/box_properties/border_width.html
+/sdcard/android/layout_tests/css1/box_properties/margin.html
+/sdcard/android/layout_tests/css1/box_properties/width.html
+/sdcard/android/layout_tests/css1/box_properties/padding_left.html
+/sdcard/android/layout_tests/css1/box_properties/margin_left_inline.html
+/sdcard/android/layout_tests/css1/box_properties/clear.html
+/sdcard/android/layout_tests/css1/box_properties/border_left_width.html
+/sdcard/android/layout_tests/css1/box_properties/margin_left.html
+/sdcard/android/layout_tests/css1/box_properties/padding_top.html
+/sdcard/android/layout_tests/css1/box_properties/padding_bottom.html
+/sdcard/android/layout_tests/css1/box_properties/border_style_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_top_width_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_top_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_style.html
+/sdcard/android/layout_tests/css1/box_properties/border_top.html
+/sdcard/android/layout_tests/css1/box_properties/margin_bottom_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_bottom_width.html
+/sdcard/android/layout_tests/css1/box_properties/margin_bottom.html
+/sdcard/android/layout_tests/css1/box_properties/float_elements_in_series.html
+/sdcard/android/layout_tests/css1/box_properties/float_on_text_elements.html
+/sdcard/android/layout_tests/css1/box_properties/padding.html
+/sdcard/android/layout_tests/css1/box_properties/border_right_width_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_right_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_right_width.html
+/sdcard/android/layout_tests/css1/box_properties/margin_right.html
+/sdcard/android/layout_tests/css1/box_properties/border_width_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_inline.html
+/sdcard/android/layout_tests/css1/box_properties/clear_float.html
+/sdcard/android/layout_tests/css1/box_properties/border.html
+/sdcard/android/layout_tests/css1/box_properties/padding_left_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_left_width_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_left_inline.html
+/sdcard/android/layout_tests/css1/box_properties/padding_top_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_left.html
+/sdcard/android/layout_tests/css1/box_properties/padding_bottom_inline.html
+/sdcard/android/layout_tests/css1/box_properties/margin_top_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_top_width.html
+/sdcard/android/layout_tests/css1/box_properties/border_bottom_width_inline.html
+/sdcard/android/layout_tests/css1/box_properties/acid_test.html
+/sdcard/android/layout_tests/css1/box_properties/border_bottom_inline.html
+/sdcard/android/layout_tests/css1/box_properties/margin_top.html
+/sdcard/android/layout_tests/css1/box_properties/border_bottom.html
+/sdcard/android/layout_tests/css1/box_properties/padding_right_inline.html
+/sdcard/android/layout_tests/css1/box_properties/float_margin.html
+/sdcard/android/layout_tests/css1/box_properties/padding_right.html
+/sdcard/android/layout_tests/css1/box_properties/padding_inline.html
+/sdcard/android/layout_tests/css1/box_properties/float.html
+/sdcard/android/layout_tests/css1/box_properties/height.html
+/sdcard/android/layout_tests/css1/box_properties/margin_right_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_color_inline.html
+/sdcard/android/layout_tests/css1/box_properties/border_right.html
+/sdcard/android/layout_tests/css1/box_properties/border_color.html
+/sdcard/android/layout_tests/css1/box_properties/margin_inline.html
+/sdcard/android/layout_tests/css1/conformance/forward_compatible_parsing.html
+/sdcard/android/layout_tests/css1/formatting_model/floating_elements.html
+/sdcard/android/layout_tests/css1/formatting_model/horizontal_formatting.html
+/sdcard/android/layout_tests/css1/formatting_model/vertical_formatting.html
+/sdcard/android/layout_tests/css1/formatting_model/height_of_lines.html
+/sdcard/android/layout_tests/css1/formatting_model/inline_elements.html
+/sdcard/android/layout_tests/css1/formatting_model/canvas.html
+/sdcard/android/layout_tests/css1/formatting_model/replaced_elements.html
+/sdcard/android/layout_tests/css1/classification/list_style_type.html
+/sdcard/android/layout_tests/css1/classification/list_style_image.html
+/sdcard/android/layout_tests/css1/classification/list_style_position.html
+/sdcard/android/layout_tests/css1/classification/display.html
+/sdcard/android/layout_tests/css1/classification/list_style.html
+/sdcard/android/layout_tests/css1/classification/white_space.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/insertTbodyRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendCellsRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendColGroup1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendCol1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/insertTbodyExpand1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/dom/appendCells1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug56024.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-14.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug11945.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-18.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug72393.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug23847.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug7121-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug27993-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug7243.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-3.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1647.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-7.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug101759.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug2479-5.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14007-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-11.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1010.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-15.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14159-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug25707.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug47163.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug91057.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug131020-3.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug19526.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14489.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug73629.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1725.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-4.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug106336.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-8.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug22122.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug10216.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug14007-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug106966.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug32205-4.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug42043.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug178855.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-12.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug92868_1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug21518.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug45621.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-16.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug65372.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug59252.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug29058-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug17826.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug67915-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug46268-4.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1128.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1164.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/97619.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-5.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug10140.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-9.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug32205-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug61042-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug104898.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug8499.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug9879-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug128876.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-13.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug58402-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug24880-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug85016.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-17.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug80762-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug18770.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug33784.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3105.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1055-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug89315.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug92647-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug1262.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug7113.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3517.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug220653.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug4294.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-6.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug6933.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug51000.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug11331.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug61042-2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/bugs/bug3166-10.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/other/empty_cells.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/other/test4.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/col_span2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/columns.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/captions1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/cols1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/backgrounds.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/captions2.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/captions3.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/conflicts.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/core/standards1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/collapsing_borders/bug41262-5.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/collapsing_borders/bug41262-6.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/collapsing_borders/bug41262-1.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_below.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-cell.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow_row.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_hidden_tr.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-column.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/tables_caption_align_right.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-column-group.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-row-group.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_hidden.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_row_sibling.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_lhs.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_tbody.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_rules_rows.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_rules_all.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_above.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_table.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_void.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_hsides.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_right.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_hidden_tbody.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_layers-show.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_caption_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-cell.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_below.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_table_caption.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_hidden_table.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_rules_cols.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_cell.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-row.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_align_right.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-row.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_tbody_sibling.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_rules_cols.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_border.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_colgroup_width_px.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-quirks.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_box.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_rules_rows.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_hsides.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_left.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_caption_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_hidden_table.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-row-group.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_bottom.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_rhs.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_frame_vsides.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_cell_sibling.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_layers-hide.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/tables_cellspacing_pct.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_position-table-column-group.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_lhs.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_fixed-bg.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_td_dynamic_deactivate.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_style_reflow_row.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_rhs.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_above.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/x_table_frame_vsides.xml
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow_tbody.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/backgr_border-table-column.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_caption_top.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/table_overflow_dirty_reflow_table.html
+/sdcard/android/layout_tests/tables/mozilla_expected_failures/marvin/tables_caption_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteCellsRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteRowsShrink1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsRebuild2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteCol1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteCol2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertColGroups1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteCol3.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertColGroups2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteCellsShrink1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteTbodyExpand1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteCellsShrink2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/tableDom.html
+/sdcard/android/layout_tests/tables/mozilla/dom/appendCol2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/appendTbodyExpand1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteTbodyRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteColGroup1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteColGroup2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertRowsExpand1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/appendRowsExpand1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/deleteRowsRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCols1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCols2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertRowsRebuild1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsExpand1.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCols3.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCellsExpand2.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCols4.html
+/sdcard/android/layout_tests/tables/mozilla/dom/insertCols5.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30418.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug14159-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46623-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug24661.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30692.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug53690-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug88035-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug51727.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug81934.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug68912.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug60992.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug92647-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug120107.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1271.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug28928.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug103533.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4093.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2267.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug92868.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4429.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5538.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug106816.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10009.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug149275-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug32205-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug13118.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1802s.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10296-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug647.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug48028-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug72359.xml
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug25367.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1430.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1224.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug67915-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug45486.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug113424.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug108340.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3454.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4849-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug11321.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2886.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug219693-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug42443.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug54450.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug269566.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12709.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug80762-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug21918.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1302.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug25663.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug55527.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug7112-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1055-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug69382-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug17587.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2516.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4803.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug19599.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1188.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3718.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug110566.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug106158-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5188.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug215629.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug154780.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug137388-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10039.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5798.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-3a.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug25074.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug27038-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/45621.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug25086.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug43854-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug34538.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug131020.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug7121-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4501.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug53891.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8032-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-5.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug63785.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug113235-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug69187.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9024.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug120364.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug109043.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug220536.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-5.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2973.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug222467.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug6674.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug99948.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug277062.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug127267.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30332-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10036.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug16012.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2997.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug17130-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug650.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug14323.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10565.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug52505.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug29314.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug13169.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30559.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug29326.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug55545.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug18359.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3037-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug82946-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug55694.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug6304.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3263.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug101674.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug123862.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug221784-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug275625.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug106795.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug22513.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug57300.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug51037.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug119786.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12908-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug15247.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46623-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug34176.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug53690-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug24880.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug41890.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug88035-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug50695-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1163-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8411.xml
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1802.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3260.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug97138.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9123-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3309-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3191.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1296.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug222336.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2773.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8381.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug194024.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2947.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5838.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug60013.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug138725.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug11026.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug175455-4.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug58402-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug43039.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug48028-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug24627.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug35662.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug21299.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug26178.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug18664.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug23299.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug88524.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug48827.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1318.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4427.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug6184.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug11384s.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5835.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4576.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug133948.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9879-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug11944.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug13196.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug20579.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug29058-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug96334.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug7112-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug60749.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug59354.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug69382-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug27993-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug57378.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-4.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug98196.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9072.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2585.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug145572.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug137388-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5799.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug157890.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug196870.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug73321.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug18440.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug965.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug131020-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug43854-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug96343.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46368-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8032-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1067-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2065.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug97383.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug113235-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3681-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9271-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1809.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2962.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-6.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2469.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8950.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug133756-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2886-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug159108.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4849.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug25004.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12910.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug43204.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug20804.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug23072.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug19061-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10269-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug13526.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug52506.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug27038-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46480-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug42187.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2050.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3103.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug39209.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug38916.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug82946-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3037-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4523.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug67864.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8361.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2981-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2684.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4385.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug126742.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12910-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug8858.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug709.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug16252.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug33137.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug45350.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12908-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug92143.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug14159-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug50695-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug29429.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1261.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4520.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46944.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/adforce_imgis_com.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug18955.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug227123.xml
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3309-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9123-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug7342.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug83786.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4382.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug24200.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug641-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug625.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug32205-5.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug56201.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug32841.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug44505.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug45055-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug15544.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug40828.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1800.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug6404.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2509.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-4.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4739.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-4.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug13105.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug149275-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug32205-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12008.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10296-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug727.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug278385.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug13484.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug15933.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug60807.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug93363.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug14929.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug86708.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug57828.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug11384q.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2954.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2479-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug139524-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug219693-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug137388-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30273.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-3.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug22246-2a.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12384.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug44523.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug60804.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug86220.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug32447.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug17138.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug56405.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug26553.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1220.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug29058-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug33855.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug29157.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2123.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug19356.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug28933.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46368-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug18558.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug102145-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1067-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1474.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3681-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4284.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug4527.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug9271-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2296.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug106158-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2757.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug128229.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug133756-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug5797.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug278266.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug23235.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug19061-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10269-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug963.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug27038-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug12268.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug45055.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug7471.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug75250.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46480-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30985.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46924.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug56563.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug23994.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug113235-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug99923.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug55789.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2981-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-4.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug7714.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug222846.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug68998.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug30332-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug17130-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug51140.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug23151.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug10633.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug24503.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug28341.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug47432.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug101201.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug17168.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug46268-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug78162.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug17548.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug100334.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug57828-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1818-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug2763.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug1828.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug221784-1.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug3977.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug131020_iframe.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug641-2.html
+/sdcard/android/layout_tests/tables/mozilla/bugs/bug22019.html
+/sdcard/android/layout_tests/tables/mozilla/other/move_row.html
+/sdcard/android/layout_tests/tables/mozilla/other/nestedTables.html
+/sdcard/android/layout_tests/tables/mozilla/other/wa_table_tr_align.html
+/sdcard/android/layout_tests/tables/mozilla/other/ms.html
+/sdcard/android/layout_tests/tables/mozilla/other/cell_widths.html
+/sdcard/android/layout_tests/tables/mozilla/other/test3.html
+/sdcard/android/layout_tests/tables/mozilla/other/cellspacing.html
+/sdcard/android/layout_tests/tables/mozilla/other/nested2.html
+/sdcard/android/layout_tests/tables/mozilla/other/test6.html
+/sdcard/android/layout_tests/tables/mozilla/other/padding.html
+/sdcard/android/layout_tests/tables/mozilla/other/body_col.html
+/sdcard/android/layout_tests/tables/mozilla/other/wa_table_thtd_rowspan.html
+/sdcard/android/layout_tests/tables/mozilla/other/slashlogo.html
+/sdcard/android/layout_tests/tables/mozilla/images/adforce_imgis_com.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_auto.html
+/sdcard/android/layout_tests/tables/mozilla/core/captions.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_fixPer.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_autoFix.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_autoPer.html
+/sdcard/android/layout_tests/tables/mozilla/core/row_span.html
+/sdcard/android/layout_tests/tables/mozilla/core/cell_heights.html
+/sdcard/android/layout_tests/tables/mozilla/core/misc.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_autoFixPer.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_fix.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_per.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_auto.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_span.html
+/sdcard/android/layout_tests/tables/mozilla/core/margins.html
+/sdcard/android/layout_tests/tables/mozilla/core/borders.html
+/sdcard/android/layout_tests/tables/mozilla/core/table_frame.html
+/sdcard/android/layout_tests/tables/mozilla/core/table_rules.html
+/sdcard/android/layout_tests/tables/mozilla/core/table_heights.html
+/sdcard/android/layout_tests/tables/mozilla/core/nested1.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_autoFix.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_auto_fixPer.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_autoPer.html
+/sdcard/android/layout_tests/tables/mozilla/core/bloomberg.html
+/sdcard/android/layout_tests/tables/mozilla/core/one_row.html
+/sdcard/android/layout_tests/tables/mozilla/core/table_widths.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_autoFixPer.html
+/sdcard/android/layout_tests/tables/mozilla/core/box_sizing.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_fix.html
+/sdcard/android/layout_tests/tables/mozilla/core/col_widths_fix_per.html
+/sdcard/android/layout_tests/tables/mozilla/collapsing_borders/bug41262-3.html
+/sdcard/android/layout_tests/tables/mozilla/collapsing_borders/bug41262-4.html
+/sdcard/android/layout_tests/tables/mozilla/collapsing_borders/bug127040.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_green.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_olive.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_teal_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_width_pct.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_olive_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_0.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-row-group.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_maroon_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_width_rel.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_lime.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_navy.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-column.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_nowrap.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_style.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_bgcolor_rgb.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_green_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_char.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_span.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_bgcolor_rgb.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_silver_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_rules_groups.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_gray.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_bgcolor_rgb.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellspacing.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_width_px.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_navy_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_yellow.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_width.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_green.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-cell.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_silver.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_border_px.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_colspan.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellspacing_pct.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_nowrap.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_char.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_blue.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_navy.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_lime_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_aqua_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_rowspan.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_bgcolor_name.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_rowspan.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_navy_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_red.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_gray.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_justify.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_fuchsia.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_white_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_maroon_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_rules_none.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_caption_align_bot.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellpadding_pct.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_yellow_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_colspan.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_justify.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_colspan.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_nowrap.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_lime_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_aqua_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_border_none.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_1.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_row_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_maroon.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_frame_border.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_blue.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_width_px.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_silver_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_width_rel.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_index.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_row_th_nowrap.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_black_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_width.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_cellpadding_pct.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_gray_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_olive_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_id.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_char.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/body_col.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-row.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_fuchsia.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_cellpadding.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_frame_void.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_rowspan.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_char.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_purple.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_rules_groups.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_gray_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_class.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_width_pct.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/body_tfoot.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_span.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_width_pct.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_yellow_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_height.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_white.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_frame_box.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_yellow.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_width_px.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_char.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_row_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_2.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_aqua.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_fuchsia_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/td_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/col_span.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_row_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_purple_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_red_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_width_pct.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_green_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_border.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_white_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_fuchsia_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_default.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_align_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_silver.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_red.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_black.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_overflow_td_dynamic_deactivate.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_cellpadding.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_align_right.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_rowspan.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_cellspacing.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_rules_none.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_white.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_align_justify.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_rules_all.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_blue_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_black_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_align_left.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_right.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_caption_align_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_id.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_col_span.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_bgcolor_name.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_height.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_teal.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_height.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_olive.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_height.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/body_thead.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_maroon.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_simple-table-column-group.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/table_overflow_hidden_td.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_black.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_layers-opacity.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_bgcolor_name.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_red_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_blue_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_valign_top.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_lime.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/th_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_width_percent.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_width.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_teal_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_valign_middle.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_width_px.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_valign_baseline.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_align_char.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/backgr_position-table.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_char.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_th_width.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tfoot_align_center.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tbody_align_justify.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_bgcolor_rgb.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_purple_rgb.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/colgroup_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_td_colspan.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_caption_align_top.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_table_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_valign_middle.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_colgroup_align_center.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/thead_valign_baseline.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_thead_style.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tbody_class.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_border_3.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_align_left.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tr_valign_bottom.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/body_tbody.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_td_bgcolor_name.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_bgcolor_teal.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_tfoot_align_justify.xml
+/sdcard/android/layout_tests/tables/mozilla/marvin/tables_bgcolor_purple.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/tr_valign_bottom.html
+/sdcard/android/layout_tests/tables/mozilla/marvin/x_th_id.xml
+/sdcard/android/layout_tests/css3/css3-modsel-33.html
+/sdcard/android/layout_tests/css3/css3-modsel-35.html
+/sdcard/android/layout_tests/css3/css3-modsel-36.html
+/sdcard/android/layout_tests/css3/css3-modsel-37.html
+/sdcard/android/layout_tests/transitions/transition-drt-api.html
diff --git a/tests/DumpRenderTree/assets/results/layout_tests_passed.txt b/tests/DumpRenderTree/assets/results/layout_tests_passed.txt
index fbceabd..37a4bbe 100644
--- a/tests/DumpRenderTree/assets/results/layout_tests_passed.txt
+++ b/tests/DumpRenderTree/assets/results/layout_tests_passed.txt
@@ -1,3 +1,1051 @@
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrlastchild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementnormalize.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechildnode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetattributenodenull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnfirstitem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrparentnodenull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnattrnode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementsetattributenodenull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementnormalize2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforeinvalidnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodechildnodesappendchild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrfirstchild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue05.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatagetlength.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrinsertdataoffsetnegative.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementinvalidcharacterexception.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittexttwo.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrsetvalue1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonegetparentnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreatetextnode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateelement.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistreturnlastitem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrchildnodes1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrdeletedataoffsetnegative.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementretrieveallattributes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateelement1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_domimplementationfeaturenoversion.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrprevioussiblingnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagnamespecialvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildnodeancestor.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagnamenomatch.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildgetnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedataend.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedataexceedslengthofarg.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_notationssetnameditem1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildinvalidnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore7.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetprevioussiblingnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodehaschildnodesfalse.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnlastitem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetfirstchildnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_notationsremovenameditem1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforedocfragment.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataappenddata.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrspecifiedvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrgetvalue1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnewchilddiffdocument.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_domimplementationfeaturenull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrreplacedataoffsetnegative.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenewchildexists.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue06.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexnotzero.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textwithnomarkup.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_entitiessetnameditem1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrsetvalue2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetelementsbytagnametotallength.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateattribute1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexgetlengthofemptylist.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementchangeattributevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetnextsiblingnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapinuseattributeerr.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrchildnodes2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrcreatetextnode2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodechildnodesempty.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataappenddatagetdata.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedataend.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetlastchildnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrcreatetextnode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonefalsenocopytext.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrreplacedataoffsetgreater.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeparentnode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapnotfounderr.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementretrieveattrvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildoldchildnonexistent.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbefore.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodehaschildnodes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreateentref1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrgetvalue2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementretrievetagname.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrspecifiedvaluechanged.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenewchilddiffdocument.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrreplacedatacountnegative.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedatabegining.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreateelement.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrinsertdataoffsetgreater.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textparseintolistofelements.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue07.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetownerdocumentnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedatamiddle.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildinvalidnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementremoveattributenode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrsubstringoffsetgreater.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedatamiddle.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatasubstringexceedsvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetrootnode.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatainsertdataend.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonenodetrue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapchildnoderange.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapnumberofnodes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue01.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetimplementation.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildchildexists.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild3.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetelementsbytagnamelength.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodeattributes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrsubstringnegativeoffset.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechildgetnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrsubstringcountnegative.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementnotfounderr.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentfragmentnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrdeletedataoffsetgreater.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatasubstringvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetownerdocument.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementassociatedattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementinvalidcharacterexception1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textindexsizeerroffsetoutofbounds.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedatagetlengthanddata.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnodeancestor.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue08.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittextthree.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreateelementcasesensitive.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore3.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodeattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdataindexsizeerrdeletedatacountnegative.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnewchildexists.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_domimplementationfeaturexml.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementreplaceexistingattributegevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementcreatenewattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrnextsiblingnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrremovechild1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapwrongdocumenterr.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapreturnnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue02.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild4.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementinuseattributeerr.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetlastchild.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetattributenode.html
+/sdcard/android/layout_tests/dom/html/level1/core/documentgetdoctypenodtd.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditemreturnvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedataexceedslengthofdata.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodeattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetdoctype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditemthatexists.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreatedocumentfragment.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_commentgetcomment.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attreffectivevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittextfour.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforenodeancestor.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore4.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textindexsizeerrnegativeoffset.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodetextnodeattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentnodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatadeletedataexceedslength.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_textsplittextone.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentfragmentnodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatagetdata.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatainsertdatabeginning.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetnextsibling.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistreturnfirstitem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrremovechild2.html
+/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreatepi.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue03.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild5.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrhaschildnodes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrreplacechild1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrnormalize.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodedocumentfragmentnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementreplaceexistingattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchildnewchilddiffdocument.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelisttraverselist.html
+/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreateentref.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatasetnodevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_entitiesremovenameditem1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore5.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagname.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrcreatedocumentfragment.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrclonenode1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapremovenameditem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementaddnewattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexequalzero.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodechildnodes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementempty.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatainsertdatamiddle.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreatecomment.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetprevioussibling.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforerefchildnonexistent.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementremoveattributeaftercreate.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_noderemovechildoldchildnonexistent.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementwrongdocumenterr.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_characterdatareplacedatabegining.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeattributenodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecommentnodeattributes.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodevalue04.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentinvalidcharacterexceptioncreateattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementremoveattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrappendchild6.html
+/sdcard/android/layout_tests/dom/html/level1/core/documentinvalidcharacterexceptioncreatepi1.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeelementnodetype.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrname.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapgetnameditem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgettagname.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditem.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeinsertbeforerefchildnull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrreplacechild2.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeparentnodenull.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodecloneattributescopied.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonenodefalse.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodereplacechildnodename.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementgetelementsbytagnameaccessnodelist.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeclonetruecopytext.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_attrinsertbefore6.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodelistindexgetlength.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_elementreplaceattributewithself.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentcreateattribute.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodeappendchilddocfragment.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_namednodemapsetnameditemwithnewvalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_documentgetelementsbytagnamevalue.html
+/sdcard/android/layout_tests/dom/html/level1/core/hc_nodegetfirstchild.html
+/sdcard/android/layout_tests/dom/html/level2/events/EventTargetCast01.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent12.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent04.html
+/sdcard/android/layout_tests/dom/html/level2/events/createEvent02.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent08.html
+/sdcard/android/layout_tests/dom/html/level2/events/initEvent04.html
+/sdcard/android/layout_tests/dom/html/level2/events/DocumentEventCast01.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent01.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent13.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent05.html
+/sdcard/android/layout_tests/dom/html/level2/events/initEvent01.html
+/sdcard/android/layout_tests/dom/html/level2/events/createEvent03.html
+/sdcard/android/layout_tests/dom/html/level2/events/initEvent05.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent09.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent10.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent02.html
+/sdcard/android/layout_tests/dom/html/level2/events/initEvent02.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent06.html
+/sdcard/android/layout_tests/dom/html/level2/events/createEvent04.html
+/sdcard/android/layout_tests/dom/html/level2/events/initEvent06.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent11.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent03.html
+/sdcard/android/layout_tests/dom/html/level2/events/createEvent01.html
+/sdcard/android/layout_tests/dom/html/level2/events/dispatchEvent07.html
+/sdcard/android/layout_tests/dom/html/level2/events/initEvent03.html
+/sdcard/android/layout_tests/dom/html/level2/events/createEvent05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement87.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/hasFeature04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement26.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement141.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement37.html
+/sdcard/android/layout_tests/dom/html/level2/html/table12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIsIndexElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameSetElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement27.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement90.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/table45.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement124.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement40.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement30.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptGroupElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement73.html
+/sdcard/android/layout_tests/dom/html/level2/html/table28.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/anchor02.html
+/sdcard/android/layout_tests/dom/html/level2/html/object09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement27.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement107.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement23.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument25.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement56.html
+/sdcard/android/layout_tests/dom/html/level2/html/table31.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/object12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement30.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement89.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement110.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/hasFeature06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement28.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement143.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement39.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIsIndexElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement29.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement92.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/table47.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement126.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement42.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement75.html
+/sdcard/android/layout_tests/dom/html/level2/html/table50.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/anchor04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement29.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement109.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement25.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument27.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement58.html
+/sdcard/android/layout_tests/dom/html/level2/html/table33.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/area01.html
+/sdcard/android/layout_tests/dom/html/level2/html/object14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement32.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement112.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDivElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLUListElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement145.html
+/sdcard/android/layout_tests/dom/html/level2/html/button01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement61.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCaptionElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement94.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFieldSetElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/table49.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLIElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement128.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMapElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement44.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement77.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/table52.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/anchor06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement131.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLParagraphElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement27.html
+/sdcard/android/layout_tests/dom/html/level2/html/table02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement80.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/table35.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/area03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement34.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement114.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement30.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLStyleElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/button03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement63.html
+/sdcard/android/layout_tests/dom/html/level2/html/table18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement96.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement46.html
+/sdcard/android/layout_tests/dom/html/level2/html/table21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/object02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLQuoteElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement79.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement100.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement133.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement29.html
+/sdcard/android/layout_tests/dom/html/level2/html/table04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement82.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/table37.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement36.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement116.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement32.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/basefont01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLStyleElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement22.html
+/sdcard/android/layout_tests/dom/html/level2/html/button05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement65.html
+/sdcard/android/layout_tests/dom/html/level2/html/table40.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement98.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement48.html
+/sdcard/android/layout_tests/dom/html/level2/html/table23.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/object04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLPreElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement22.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOListElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement102.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement135.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement51.html
+/sdcard/android/layout_tests/dom/html/level2/html/table06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement84.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/table39.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/hasFeature01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement23.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement38.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement118.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement34.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseFontElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement24.html
+/sdcard/android/layout_tests/dom/html/level2/html/button07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement67.html
+/sdcard/android/layout_tests/dom/html/level2/html/table42.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement121.html
+/sdcard/android/layout_tests/dom/html/level2/html/dlist01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement70.html
+/sdcard/android/layout_tests/dom/html/level2/html/table25.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMenuElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFontElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement24.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement104.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument22.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement137.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement53.html
+/sdcard/android/layout_tests/dom/html/level2/html/table08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement86.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/hasFeature03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement25.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement140.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement36.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseFontElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameSetElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement26.html
+/sdcard/android/layout_tests/dom/html/level2/html/button09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement69.html
+/sdcard/android/layout_tests/dom/html/level2/html/table44.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement123.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement72.html
+/sdcard/android/layout_tests/dom/html/level2/html/table27.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/anchor01.html
+/sdcard/android/layout_tests/dom/html/level2/html/object08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement26.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement106.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement22.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/body01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument24.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement139.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement55.html
+/sdcard/android/layout_tests/dom/html/level2/html/table30.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/object11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement88.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHtmlElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTitleElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/hasFeature05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement27.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement142.html
+/sdcard/android/layout_tests/dom/html/level2/html/doc01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/AppletsCollection.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement38.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIsIndexElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement28.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement91.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/table46.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement30.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement125.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement41.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLParamElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement31.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptGroupElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement74.html
+/sdcard/android/layout_tests/dom/html/level2/html/table29.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/anchor03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement28.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement108.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement24.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument26.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement57.html
+/sdcard/android/layout_tests/dom/html/level2/html/table32.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/object13.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement31.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement111.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLabelElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement29.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement144.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement60.html
+/sdcard/android/layout_tests/dom/html/level2/html/table15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLModElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement93.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFieldSetElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/table48.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLIElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement127.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement43.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement76.html
+/sdcard/android/layout_tests/dom/html/level2/html/table51.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/anchor05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement130.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement26.html
+/sdcard/android/layout_tests/dom/html/level2/html/table01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement59.html
+/sdcard/android/layout_tests/dom/html/level2/html/table34.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/area02.html
+/sdcard/android/layout_tests/dom/html/level2/html/object15.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement33.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement113.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLUListElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBRElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/button02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLButtonElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement62.html
+/sdcard/android/layout_tests/dom/html/level2/html/table17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLegendElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement95.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionsCollection06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement129.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMapElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement45.html
+/sdcard/android/layout_tests/dom/html/level2/html/table20.html
+/sdcard/android/layout_tests/dom/html/level2/html/object01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement78.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/table53.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement22.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement17.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement132.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement28.html
+/sdcard/android/layout_tests/dom/html/level2/html/table03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement81.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/table36.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/area04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement20.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement35.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement115.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDlistElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement31.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLStyleElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement21.html
+/sdcard/android/layout_tests/dom/html/level2/html/button04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement64.html
+/sdcard/android/layout_tests/dom/html/level2/html/table19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement97.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement47.html
+/sdcard/android/layout_tests/dom/html/level2/html/table22.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/object03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOListElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLQuoteElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement101.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement19.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement134.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLScriptElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement50.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement83.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/table38.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHeadingElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement22.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement37.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement117.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement33.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDirectoryElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement23.html
+/sdcard/android/layout_tests/dom/html/level2/html/button06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement66.html
+/sdcard/android/layout_tests/dom/html/level2/html/table41.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement40.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement99.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement120.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement16.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAppletElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement49.html
+/sdcard/android/layout_tests/dom/html/level2/html/table24.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFontElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/object05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLCollection11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLImageElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement23.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOListElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement103.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement136.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement52.html
+/sdcard/android/layout_tests/dom/html/level2/html/table07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLSelectElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableColElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement85.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement09.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAnchorElement14.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/hasFeature02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement24.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement39.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement119.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement35.html
+/sdcard/android/layout_tests/dom/html/level2/html/table10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBaseFontElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement25.html
+/sdcard/android/layout_tests/dom/html/level2/html/button08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement68.html
+/sdcard/android/layout_tests/dom/html/level2/html/table43.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLInputElement12.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTextAreaElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableRowElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFrameElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement122.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement18.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFormElement04.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLAreaElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLObjectElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement71.html
+/sdcard/android/layout_tests/dom/html/level2/html/table26.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLIFrameElement06.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLFontElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/object07.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableCellElement10.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableElement25.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement105.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLLinkElement08.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLOptionElement05.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement21.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLMetaElement02.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLBodyElement01.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLDocument23.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement138.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLHRElement03.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLTableSectionElement11.html
+/sdcard/android/layout_tests/dom/html/level2/html/HTMLElement54.html
+/sdcard/android/layout_tests/dom/html/level2/html/table09.html
+/sdcard/android/layout_tests/dom/html/level2/html/object10.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_notationsremovenameditemns1.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_entitiessetnameditemns1.html
+/sdcard/android/layout_tests/dom/html/level2/core/setAttributeNS10.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_nodedocumentfragmentnormalize2.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_namednodemapinvalidtype1.html
+/sdcard/android/layout_tests/dom/html/level2/core/createAttributeNS06.html
+/sdcard/android/layout_tests/dom/html/level2/core/createDocumentType04.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_notationssetnameditemns1.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_entitiesremovenameditemns1.html
+/sdcard/android/layout_tests/dom/html/level2/core/hc_nodedocumentfragmentnormalize1.html
+/sdcard/android/layout_tests/dom/html/level2/core/createDocument08.html
+/sdcard/android/layout_tests/plugins/createScriptableObject-before-start.html
+/sdcard/android/layout_tests/plugins/get-empty-url.html
+/sdcard/android/layout_tests/plugins/return-error-from-new-stream-callback-in-full-frame-plugin.html
+/sdcard/android/layout_tests/editing/style/temporary-span-crash.html
+/sdcard/android/layout_tests/editing/style/4230923.html
+/sdcard/android/layout_tests/editing/inserting/5549929-1.html
+/sdcard/android/layout_tests/editing/inserting/6104369.html
+/sdcard/android/layout_tests/editing/inserting/5803706-2.html
+/sdcard/android/layout_tests/editing/inserting/5685601-2.html
+/sdcard/android/layout_tests/editing/inserting/5607069-1.html
+/sdcard/android/layout_tests/editing/inserting/5803706-1.html
+/sdcard/android/layout_tests/editing/inserting/5685601-1.html
+/sdcard/android/layout_tests/editing/inserting/5994480.html
+/sdcard/android/layout_tests/editing/inserting/6104369-2.html
+/sdcard/android/layout_tests/editing/inserting/insert-before-link-1.html
+/sdcard/android/layout_tests/editing/inserting/5378847.html
+/sdcard/android/layout_tests/editing/inserting/5685601-3.html
+/sdcard/android/layout_tests/editing/execCommand/19403.html
+/sdcard/android/layout_tests/editing/execCommand/default-parameters.html
+/sdcard/android/layout_tests/editing/execCommand/19455.html
+/sdcard/android/layout_tests/editing/execCommand/19087.html
+/sdcard/android/layout_tests/editing/execCommand/empty-span-removal.html
+/sdcard/android/layout_tests/editing/execCommand/5469868.html
+/sdcard/android/layout_tests/editing/execCommand/5575101-1.html
+/sdcard/android/layout_tests/editing/execCommand/findString-3.html
+/sdcard/android/layout_tests/editing/execCommand/16049.html
+/sdcard/android/layout_tests/editing/execCommand/19653-1.html
+/sdcard/android/layout_tests/editing/execCommand/arguments-combinations.html
+/sdcard/android/layout_tests/editing/execCommand/5575101-3.html
+/sdcard/android/layout_tests/editing/execCommand/5770834-1.html
+/sdcard/android/layout_tests/editing/execCommand/5483526.html
+/sdcard/android/layout_tests/editing/execCommand/5658933-1.html
+/sdcard/android/layout_tests/editing/execCommand/6355786.html
+/sdcard/android/layout_tests/editing/execCommand/5604313.html
+/sdcard/android/layout_tests/editing/execCommand/19653-3.html
+/sdcard/android/layout_tests/editing/execCommand/5763082.html
+/sdcard/android/layout_tests/editing/execCommand/6444148.html
+/sdcard/android/layout_tests/editing/execCommand/4976800.html
+/sdcard/android/layout_tests/editing/execCommand/4928635.html
+/sdcard/android/layout_tests/editing/execCommand/4920742-2.html
+/sdcard/android/layout_tests/editing/execCommand/4917055.html
+/sdcard/android/layout_tests/editing/execCommand/5575101-2.html
+/sdcard/android/layout_tests/editing/execCommand/12244.html
+/sdcard/android/layout_tests/editing/execCommand/19653-2.html
+/sdcard/android/layout_tests/editing/execCommand/4916235.html
+/sdcard/android/layout_tests/editing/execCommand/5458246.html
+/sdcard/android/layout_tests/editing/execCommand/toggle-styles.html
+/sdcard/android/layout_tests/editing/pasteboard/5761530-2.html
+/sdcard/android/layout_tests/editing/pasteboard/6018653.html
+/sdcard/android/layout_tests/editing/pasteboard/4930986-1.html
+/sdcard/android/layout_tests/editing/pasteboard/5780697-1.html
+/sdcard/android/layout_tests/editing/pasteboard/4930986-3.html
+/sdcard/android/layout_tests/editing/pasteboard/5245519.html
+/sdcard/android/layout_tests/editing/pasteboard/5521237.html
+/sdcard/android/layout_tests/editing/pasteboard/newlines-around-floating-or-positioned.html
+/sdcard/android/layout_tests/editing/pasteboard/5078739.html
+/sdcard/android/layout_tests/editing/pasteboard/createMarkup-assert.xml
+/sdcard/android/layout_tests/editing/pasteboard/4930986-2.html
+/sdcard/android/layout_tests/editing/pasteboard/5480736.html
+/sdcard/android/layout_tests/editing/selection/5497643.html
+/sdcard/android/layout_tests/editing/selection/5825350-1.html
+/sdcard/android/layout_tests/editing/selection/setBaseAndExtent-revert-selection.html
+/sdcard/android/layout_tests/editing/selection/selection-invalid-offset.html
+/sdcard/android/layout_tests/editing/selection/rangeCount.html
+/sdcard/android/layout_tests/editing/selection/5714333.html
+/sdcard/android/layout_tests/editing/selection/select-line.html
+/sdcard/android/layout_tests/editing/selection/doubleclick-whitespace-crash.html
+/sdcard/android/layout_tests/editing/selection/containsNode.html
+/sdcard/android/layout_tests/editing/selection/select-all-user-select-none.html
+/sdcard/android/layout_tests/editing/selection/selectAllChildren.html
+/sdcard/android/layout_tests/editing/selection/find-in-text-control.html
+/sdcard/android/layout_tests/editing/selection/extend.html
+/sdcard/android/layout_tests/editing/selection/5241148.html
+/sdcard/android/layout_tests/editing/selection/cleared-by-relayout.html
+/sdcard/android/layout_tests/editing/selection/5825350-2.html
+/sdcard/android/layout_tests/editing/selection/5794920-1.html
+/sdcard/android/layout_tests/editing/selection/5779984-1.html
+/sdcard/android/layout_tests/editing/selection/deleteFromDocument.html
+/sdcard/android/layout_tests/editing/undo/4059423-1.html
+/sdcard/android/layout_tests/editing/undo/4059423-2.html
+/sdcard/android/layout_tests/editing/undo/5658727.html
+/sdcard/android/layout_tests/editing/undo/5738768.html
+/sdcard/android/layout_tests/editing/deleting/2610675-2.html
+/sdcard/android/layout_tests/editing/deleting/5847330-2.html
+/sdcard/android/layout_tests/editing/deleting/6026335.html
+/sdcard/android/layout_tests/editing/deleting/2610675-1.html
+/sdcard/android/layout_tests/editing/deleting/5847330-1.html
+/sdcard/android/layout_tests/editing/deleting/5433862-1.html
+/sdcard/android/layout_tests/editing/deleting/5495723.html
+/sdcard/android/layout_tests/editing/deleting/5290534.html
+/sdcard/android/layout_tests/editing/deleting/2610675-3.html
/sdcard/android/layout_tests/fast/replaced/object-param-no-name.html
/sdcard/android/layout_tests/fast/dynamic/subtree-common-root.html
/sdcard/android/layout_tests/fast/dynamic/hovered-detach.html
@@ -15,6 +1063,7 @@
/sdcard/android/layout_tests/fast/text/find-backwards.html
/sdcard/android/layout_tests/fast/text/large-text-composed-char-dos.html
/sdcard/android/layout_tests/fast/text/find-case-folding.html
+/sdcard/android/layout_tests/fast/text/text-shadow-extreme-value.html
/sdcard/android/layout_tests/fast/text/line-breaks-after-ideographic-comma-or-full-stop.html
/sdcard/android/layout_tests/fast/encoding/gbk/chinese.html
/sdcard/android/layout_tests/fast/encoding/gbk/x-euc-cn.html
@@ -68,12 +1117,10 @@
/sdcard/android/layout_tests/fast/encoding/pseudo-xml-3.html
/sdcard/android/layout_tests/fast/encoding/pseudo-xml.html
/sdcard/android/layout_tests/fast/encoding/tag-in-title.html
-/sdcard/android/layout_tests/fast/encoding/yahoo-mail.html
-/sdcard/android/layout_tests/fast/encoding/ahram-org-eg.html
-/sdcard/android/layout_tests/fast/encoding/noscript-in-head.html
/sdcard/android/layout_tests/fast/encoding/script-in-head.html
/sdcard/android/layout_tests/fast/encoding/css-cached-bom.html
/sdcard/android/layout_tests/fast/encoding/mispositioned-meta.html
+/sdcard/android/layout_tests/fast/encoding/preload-encoding.html
/sdcard/android/layout_tests/fast/multicol/gap-non-negative.html
/sdcard/android/layout_tests/fast/multicol/content-height-zero-crash.html
/sdcard/android/layout_tests/fast/doctypes/doctype-at-end.html
@@ -106,6 +1153,7 @@
/sdcard/android/layout_tests/fast/events/no-blur-on-page-leave.html
/sdcard/android/layout_tests/fast/events/onload-name-collision.html
/sdcard/android/layout_tests/fast/events/div-focus.html
+/sdcard/android/layout_tests/fast/events/related-target.html
/sdcard/android/layout_tests/fast/events/overflow-events.html
/sdcard/android/layout_tests/fast/events/create-document-crash-on-attach-event.html
/sdcard/android/layout_tests/fast/events/no-blur-on-enter-button.html
@@ -113,6 +1161,8 @@
/sdcard/android/layout_tests/fast/events/shadow-boundary-crossing.html
/sdcard/android/layout_tests/fast/events/submit-reset-nested-bubble.html
/sdcard/android/layout_tests/fast/events/nested-event-remove-node-crash.html
+/sdcard/android/layout_tests/fast/events/onsubmit-bubbling.html
+/sdcard/android/layout_tests/fast/events/onload-fires-twice.html
/sdcard/android/layout_tests/fast/events/mousedown_in_scrollbar.html
/sdcard/android/layout_tests/fast/events/window-load-capture.html
/sdcard/android/layout_tests/fast/events/event-instanceof.html
@@ -128,6 +1178,8 @@
/sdcard/android/layout_tests/fast/events/event-targets.html
/sdcard/android/layout_tests/fast/events/space-scroll-event.html
/sdcard/android/layout_tests/fast/events/onload-after-document-close-no-subresource.html
+/sdcard/android/layout_tests/fast/events/nested-window-event.html
+/sdcard/android/layout_tests/fast/events/selectstart-during-autoscroll.html
/sdcard/android/layout_tests/fast/events/stopPropagation-checkbox.html
/sdcard/android/layout_tests/fast/events/tab-crash-with-image-map.html
/sdcard/android/layout_tests/fast/events/simulated-key-state.html
@@ -166,10 +1218,59 @@
/sdcard/android/layout_tests/fast/regex/slow.html
/sdcard/android/layout_tests/fast/regex/malformed-escapes.html
/sdcard/android/layout_tests/fast/regex/early-acid3-86.html
-/sdcard/android/layout_tests/fast/regex/test1.html
/sdcard/android/layout_tests/fast/regex/alternative-length-miscalculation.html
/sdcard/android/layout_tests/fast/regex/test4.html
/sdcard/android/layout_tests/fast/regex/non-capturing-backtracking.html
+/sdcard/android/layout_tests/fast/js/kde/Boolean.html
+/sdcard/android/layout_tests/fast/js/kde/function.html
+/sdcard/android/layout_tests/fast/js/kde/function_length.html
+/sdcard/android/layout_tests/fast/js/kde/const.html
+/sdcard/android/layout_tests/fast/js/kde/constructor_length.html
+/sdcard/android/layout_tests/fast/js/kde/statements.html
+/sdcard/android/layout_tests/fast/js/kde/math.html
+/sdcard/android/layout_tests/fast/js/kde/assignments.html
+/sdcard/android/layout_tests/fast/js/kde/crash-1.html
+/sdcard/android/layout_tests/fast/js/kde/delete.html
+/sdcard/android/layout_tests/fast/js/kde/var_decl_init.html
+/sdcard/android/layout_tests/fast/js/kde/literals.html
+/sdcard/android/layout_tests/fast/js/kde/eval.html
+/sdcard/android/layout_tests/fast/js/kde/j-comment-3.html
+/sdcard/android/layout_tests/fast/js/kde/StringObject.html
+/sdcard/android/layout_tests/fast/js/kde/crash-2.html
+/sdcard/android/layout_tests/fast/js/kde/exception_propagation.html
+/sdcard/android/layout_tests/fast/js/kde/conditional.html
+/sdcard/android/layout_tests/fast/js/kde/scope.html
+/sdcard/android/layout_tests/fast/js/kde/parse.html
+/sdcard/android/layout_tests/fast/js/kde/function_arguments.html
+/sdcard/android/layout_tests/fast/js/kde/arguments-scope.html
+/sdcard/android/layout_tests/fast/js/kde/lval-exceptions.html
+/sdcard/android/layout_tests/fast/js/kde/operators.html
+/sdcard/android/layout_tests/fast/js/kde/Array.html
+/sdcard/android/layout_tests/fast/js/kde/md5-1.html
+/sdcard/android/layout_tests/fast/js/kde/object_prototype_tostring.html
+/sdcard/android/layout_tests/fast/js/kde/Date-setYear.html
+/sdcard/android/layout_tests/fast/js/kde/GlobalObject.html
+/sdcard/android/layout_tests/fast/js/kde/prototype_proto.html
+/sdcard/android/layout_tests/fast/js/kde/evil-n.html
+/sdcard/android/layout_tests/fast/js/kde/RegExp.html
+/sdcard/android/layout_tests/fast/js/kde/cast.html
+/sdcard/android/layout_tests/fast/js/kde/j-comment-4.html
+/sdcard/android/layout_tests/fast/js/kde/iteration.html
+/sdcard/android/layout_tests/fast/js/kde/comment-1.html
+/sdcard/android/layout_tests/fast/js/kde/Prototype.html
+/sdcard/android/layout_tests/fast/js/kde/completion.html
+/sdcard/android/layout_tests/fast/js/kde/exceptions.html
+/sdcard/android/layout_tests/fast/js/kde/md5-2.html
+/sdcard/android/layout_tests/fast/js/kde/Error.html
+/sdcard/android/layout_tests/fast/js/kde/function_constructor.html
+/sdcard/android/layout_tests/fast/js/kde/object_prototype.html
+/sdcard/android/layout_tests/fast/js/kde/empty.html
+/sdcard/android/layout_tests/fast/js/kde/inbuilt_function_proto.html
+/sdcard/android/layout_tests/fast/js/kde/func-decl.html
+/sdcard/android/layout_tests/fast/js/kde/comment-2.html
+/sdcard/android/layout_tests/fast/js/kde/inbuilt_function_tostring.html
+/sdcard/android/layout_tests/fast/js/kde/Object.html
+/sdcard/android/layout_tests/fast/js/kde/prototype_length.html
/sdcard/android/layout_tests/fast/js/pic/cached-single-entry-transition.html
/sdcard/android/layout_tests/fast/js/pic/cached-prototype-setter.html
/sdcard/android/layout_tests/fast/js/pic/get-empty-string.html
@@ -226,7 +1327,6 @@
/sdcard/android/layout_tests/fast/js/do-while-semicolon.html
/sdcard/android/layout_tests/fast/js/regexp-divequal.html
/sdcard/android/layout_tests/fast/js/named-function-expression.html
-/sdcard/android/layout_tests/fast/js/array-iterate-backwards.html
/sdcard/android/layout_tests/fast/js/constructor-attributes.html
/sdcard/android/layout_tests/fast/js/array-some.html
/sdcard/android/layout_tests/fast/js/missing-title-end-tag-js.html
@@ -345,7 +1445,6 @@
/sdcard/android/layout_tests/fast/js/date-constructor.html
/sdcard/android/layout_tests/fast/js/date-big-setdate.html
/sdcard/android/layout_tests/fast/js/array-every.html
-/sdcard/android/layout_tests/fast/js/function-toString-parentheses.html
/sdcard/android/layout_tests/fast/js/array-functions-non-arrays.html
/sdcard/android/layout_tests/fast/js/while-expression-value.html
/sdcard/android/layout_tests/fast/js/string-replace-3.html
@@ -393,6 +1492,7 @@
/sdcard/android/layout_tests/fast/js/throw-from-array-sort.html
/sdcard/android/layout_tests/fast/js/slash-lineterminator-parse.html
/sdcard/android/layout_tests/fast/js/dot-node-base-exception.html
+/sdcard/android/layout_tests/fast/js/toString-stack-overflow.html
/sdcard/android/layout_tests/fast/js/codegen-peephole-locals.html
/sdcard/android/layout_tests/fast/js/constant-count.html
/sdcard/android/layout_tests/fast/js/regexp-compile.html
@@ -431,8 +1531,6 @@
/sdcard/android/layout_tests/fast/dom/HTMLTableElement/tBodies.html
/sdcard/android/layout_tests/fast/dom/HTMLTableElement/rows.html
/sdcard/android/layout_tests/fast/dom/HTMLDocument/write-multiple-calls.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/document-special-properties.html
-/sdcard/android/layout_tests/fast/dom/HTMLDocument/url-getset.html
/sdcard/android/layout_tests/fast/dom/HTMLDocument/writeln-call.html
/sdcard/android/layout_tests/fast/dom/HTMLDocument/document-plugins.html
/sdcard/android/layout_tests/fast/dom/HTMLDocument/title-get.html
@@ -559,6 +1657,12 @@
/sdcard/android/layout_tests/fast/dom/Window/alert-undefined.html
/sdcard/android/layout_tests/fast/dom/Window/window-open-top.html
/sdcard/android/layout_tests/fast/dom/Window/window-appendages-cleared.html
+/sdcard/android/layout_tests/fast/dom/Window/global-opener-function.html
+/sdcard/android/layout_tests/fast/dom/Window/window-property-shadowing.html
+/sdcard/android/layout_tests/fast/dom/Window/remove-timeout-crash.html
+/sdcard/android/layout_tests/fast/dom/Window/window-custom-prototype.html
+/sdcard/android/layout_tests/fast/dom/Window/timeout-callback-scope.html
+/sdcard/android/layout_tests/fast/dom/Window/window-property-shadowing-name.html
/sdcard/android/layout_tests/fast/dom/Window/window-open-parent-no-parent.html
/sdcard/android/layout_tests/fast/dom/Window/closure-access-after-navigation-iframe.html
/sdcard/android/layout_tests/fast/dom/HTMLTableRowElement/cells.html
@@ -611,23 +1715,7 @@
/sdcard/android/layout_tests/fast/dom/css-dom-read.html
/sdcard/android/layout_tests/fast/dom/image-object.html
/sdcard/android/layout_tests/fast/dom/gc-5.html
-/sdcard/android/layout_tests/fast/dom/node-filter-gc.html
-/sdcard/android/layout_tests/fast/dom/noscript-canvas-in-created-html-document.html
-/sdcard/android/layout_tests/fast/dom/DOMParser-assign-variable.html
-/sdcard/android/layout_tests/fast/dom/timer-clear-interval-in-handler.html
-/sdcard/android/layout_tests/fast/dom/implementation-createHTMLDocument.html
-/sdcard/android/layout_tests/fast/dom/iframe-document.html
-/sdcard/android/layout_tests/fast/dom/document-all-input.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-href-put-crash.html
-/sdcard/android/layout_tests/fast/dom/getelementsbytagnamens-mixed-namespaces.html
-/sdcard/android/layout_tests/fast/dom/object-plugin-hides-properties.html
-/sdcard/android/layout_tests/fast/dom/gc-2.html
-/sdcard/android/layout_tests/fast/dom/computed-style-set-property.html
-/sdcard/android/layout_tests/fast/dom/inner-text-001.html
-/sdcard/android/layout_tests/fast/dom/css-selectorText.html
-/sdcard/android/layout_tests/fast/dom/replace-first-child.html
-/sdcard/android/layout_tests/fast/dom/importNode-null.html
-/sdcard/android/layout_tests/fast/dom/select-selectedIndex-multiple.html
+/sdcard/android/layout_tests/fast/dom/cssTarget-crash.html
/sdcard/android/layout_tests/fast/dom/xmlhttprequest-invalid-values.html
/sdcard/android/layout_tests/fast/dom/space-to-text.html
/sdcard/android/layout_tests/fast/dom/css-set-property-exception.html
@@ -643,6 +1731,7 @@
/sdcard/android/layout_tests/fast/dom/getelementbyname-invalidation.html
/sdcard/android/layout_tests/fast/dom/capturing-event-listeners.html
/sdcard/android/layout_tests/fast/dom/title-text-property.html
+/sdcard/android/layout_tests/fast/dom/null-page-show-modal-dialog-crash.html
/sdcard/android/layout_tests/fast/dom/incompatible-operations.html
/sdcard/android/layout_tests/fast/dom/xmlhttprequest-html-response-encoding.html
/sdcard/android/layout_tests/fast/dom/inner-text-rtl.html
@@ -671,7 +1760,6 @@
/sdcard/android/layout_tests/fast/dom/document-all-select.html
/sdcard/android/layout_tests/fast/dom/anchor-backslash.html
/sdcard/android/layout_tests/fast/dom/css-mediarule-functions.html
-/sdcard/android/layout_tests/fast/dom/gc-acid3.html
/sdcard/android/layout_tests/fast/dom/duplicate-ids-document-order.html
/sdcard/android/layout_tests/fast/dom/exception-no-frame-inline-script-crash.html
/sdcard/android/layout_tests/fast/dom/XMLSerializer-doctype2.html
@@ -686,6 +1774,14 @@
/sdcard/android/layout_tests/fast/dom/createElement.html
/sdcard/android/layout_tests/fast/dom/createElement-with-column.xml
/sdcard/android/layout_tests/fast/dom/simultaneouslyRegsiteredTimerFireOrder.html
+/sdcard/android/layout_tests/fast/dom/clone-node-form-elements-with-attr.html
+/sdcard/android/layout_tests/fast/dom/setAttributeNS.html
+/sdcard/android/layout_tests/fast/dom/anchor-toString.html
+/sdcard/android/layout_tests/fast/dom/dom-add-optionelement.html
+/sdcard/android/layout_tests/fast/dom/location-assign.html
+/sdcard/android/layout_tests/fast/dom/documenturi-affects-relative-paths.html
+/sdcard/android/layout_tests/fast/dom/javascript-backslash.html
+/sdcard/android/layout_tests/fast/dom/setAttribute-using-initial-input-value.html
/sdcard/android/layout_tests/fast/dom/generic-form-element-assert.html
/sdcard/android/layout_tests/fast/dom/css-shortHands.html
/sdcard/android/layout_tests/fast/dom/dom-instanceof.html
@@ -713,7 +1809,6 @@
/sdcard/android/layout_tests/fast/dom/exception-no-frame-timeout-crash.html
/sdcard/android/layout_tests/fast/dom/title-text-property-2.html
/sdcard/android/layout_tests/fast/dom/no-elements.html
-/sdcard/android/layout_tests/fast/dom/non-numeric-values-numeric-parameters.html
/sdcard/android/layout_tests/fast/dom/gc-4.html
/sdcard/android/layout_tests/fast/dom/inner-width-height.html
/sdcard/android/layout_tests/fast/dom/XMLSerializer-doctype.html
@@ -723,14 +1818,6 @@
/sdcard/android/layout_tests/fast/dom/gc-1.html
/sdcard/android/layout_tests/fast/dom/select-selectedIndex-bug-12942.html
/sdcard/android/layout_tests/fast/dom/frame-contentWindow-crash.html
-/sdcard/android/layout_tests/fast/dom/namednodemap-namelookup.html
-/sdcard/android/layout_tests/fast/dom/null-document-location-replace-crash.html
-/sdcard/android/layout_tests/fast/dom/htmlcollection-detectability.html
-/sdcard/android/layout_tests/fast/dom/documenturi-assigned-junk-implies-relative-urls-do-not-resolve.html
-/sdcard/android/layout_tests/fast/dom/collection-namedItem-via-item.html
-/sdcard/android/layout_tests/fast/dom/set-inner-text-newlines.html
-/sdcard/android/layout_tests/fast/dom/document-dir-property.html
-/sdcard/android/layout_tests/fast/dom/undetectable-style-filter.html
/sdcard/android/layout_tests/fast/dom/domListEnumeration.html
/sdcard/android/layout_tests/fast/dom/destroy-selected-radio-button-crash.html
/sdcard/android/layout_tests/fast/dom/script-add.html
@@ -742,6 +1829,12 @@
/sdcard/android/layout_tests/fast/dom/attribute-namespaces-get-set.html
/sdcard/android/layout_tests/fast/dom/innerHTML-escaping-attribute.html
/sdcard/android/layout_tests/fast/dom/null-document-xmlhttprequest-open.html
+/sdcard/android/layout_tests/fast/dom/null-document-location-put-crash.html
+/sdcard/android/layout_tests/fast/dom/ImageDocument-image-deletion.html
+/sdcard/android/layout_tests/fast/dom/document-scripts.html
+/sdcard/android/layout_tests/fast/gradients/crash-on-remove.html
+/sdcard/android/layout_tests/fast/xpath/xpath-empty-string.html
+/sdcard/android/layout_tests/fast/invalid/test-case-tr-th-td-should-not-close-dl-list.html
/sdcard/android/layout_tests/fast/invalid/nestedh3s-rapidweaver.html
/sdcard/android/layout_tests/fast/forms/element-by-name.html
/sdcard/android/layout_tests/fast/forms/HTMLOptionElement_selected.html
@@ -751,7 +1844,6 @@
/sdcard/android/layout_tests/fast/forms/textfield-focus-out.html
/sdcard/android/layout_tests/fast/forms/willvalidate-000.html
/sdcard/android/layout_tests/fast/forms/form-data-encoding-normalization-overrun.html
-/sdcard/android/layout_tests/fast/forms/select-reset.html
/sdcard/android/layout_tests/fast/forms/input-named-action-overrides-action-attribute.html
/sdcard/android/layout_tests/fast/forms/empty-get.html
/sdcard/android/layout_tests/fast/forms/display-none-in-onchange-keyboard.html
@@ -762,18 +1854,25 @@
/sdcard/android/layout_tests/fast/forms/autofocus-opera-006.html
/sdcard/android/layout_tests/fast/forms/activate-and-disabled-elements.html
/sdcard/android/layout_tests/fast/forms/form-get-multipart2.html
+/sdcard/android/layout_tests/fast/forms/tabs-with-modifiers.html
+/sdcard/android/layout_tests/fast/forms/menulist-no-renderer-onmousedown.html
+/sdcard/android/layout_tests/fast/forms/saved-state-adoptNode-crash.html
/sdcard/android/layout_tests/fast/forms/select-replace-option.html
/sdcard/android/layout_tests/fast/forms/textarea-setvalue-submit.html
+/sdcard/android/layout_tests/fast/forms/11423.html
/sdcard/android/layout_tests/fast/forms/cursor-position.html
/sdcard/android/layout_tests/fast/forms/willvalidate-007.html
/sdcard/android/layout_tests/fast/forms/input-changing-value.html
/sdcard/android/layout_tests/fast/forms/double-focus.html
/sdcard/android/layout_tests/fast/forms/form-data-encoding-2.html
/sdcard/android/layout_tests/fast/forms/focus.html
+/sdcard/android/layout_tests/fast/forms/willvalidate-004.html
/sdcard/android/layout_tests/fast/forms/button-in-forms-collection.html
+/sdcard/android/layout_tests/fast/forms/input-text-enter.html
/sdcard/android/layout_tests/fast/forms/input-delete.html
/sdcard/android/layout_tests/fast/forms/placeholder-non-textfield.html
/sdcard/android/layout_tests/fast/forms/element-order.html
+/sdcard/android/layout_tests/fast/forms/form-post-urlencoded.html
/sdcard/android/layout_tests/fast/forms/willvalidate-001.html
/sdcard/android/layout_tests/fast/forms/option-constructor-selected.html
/sdcard/android/layout_tests/fast/forms/8250.html
@@ -809,12 +1908,11 @@
/sdcard/android/layout_tests/fast/forms/select-index-setter.html
/sdcard/android/layout_tests/fast/forms/option-change-single-selected.html
/sdcard/android/layout_tests/fast/forms/listbox-scroll-after-options-removed.html
+/sdcard/android/layout_tests/fast/forms/input-selection-hidden.html
+/sdcard/android/layout_tests/fast/forms/input-type-change-in-onfocus-keyboard.html
/sdcard/android/layout_tests/fast/forms/willvalidate-002.html
+/sdcard/android/layout_tests/fast/forms/option-in-optgroup-removal.html
/sdcard/android/layout_tests/fast/forms/form-data-encoding.html
-/sdcard/android/layout_tests/fast/forms/input-appearance-elementFromPoint.html
-/sdcard/android/layout_tests/fast/forms/select-set-inner.html
-/sdcard/android/layout_tests/fast/forms/missing-action.html
-/sdcard/android/layout_tests/fast/forms/textarea-scrollbar-height.html
/sdcard/android/layout_tests/fast/forms/textarea-default-value-leading-newline.html
/sdcard/android/layout_tests/fast/forms/autofocus-opera-008.html
/sdcard/android/layout_tests/fast/forms/listbox-typeahead-empty.html
@@ -828,9 +1926,9 @@
/sdcard/android/layout_tests/fast/forms/input-setvalue-selection.html
/sdcard/android/layout_tests/fast/forms/autofocus-opera-002.html
/sdcard/android/layout_tests/fast/forms/old-names.html
-/sdcard/android/layout_tests/fast/forms/willvalidate-006.html
/sdcard/android/layout_tests/fast/forms/focus-style-pending.html
/sdcard/android/layout_tests/fast/forms/textarea-hard-linewrap-empty.html
+/sdcard/android/layout_tests/fast/forms/input-type-change-in-onfocus-mouse.html
/sdcard/android/layout_tests/fast/forms/document-write.html
/sdcard/android/layout_tests/fast/forms/slow-click.html
/sdcard/android/layout_tests/fast/forms/autofocus-attribute.html
@@ -985,6 +2083,7 @@
/sdcard/android/layout_tests/fast/loader/data-url-encoding-html.html
/sdcard/android/layout_tests/fast/loader/file-URL-with-port-number.html
/sdcard/android/layout_tests/fast/loader/link-no-URL.html
+/sdcard/android/layout_tests/fast/xsl/xslt-fragment-in-empty-doc.html
/sdcard/android/layout_tests/fast/canvas/pattern-with-transform.html
/sdcard/android/layout_tests/fast/canvas/gradient-addColorStop-with-invalid-color.html
/sdcard/android/layout_tests/fast/canvas/canvas-gradient-without-path.html
@@ -1041,6 +2140,63 @@
/sdcard/android/layout_tests/fast/frames/location-change.html
/sdcard/android/layout_tests/fast/frames/frame-base-url.html
/sdcard/android/layout_tests/fast/frames/iframe-display-none.html
-/sdcard/android/layout_tests/fast/frames/frame-display-none-focus.html
-/sdcard/android/layout_tests/fast/reflections/teardown-crash.html
-/sdcard/android/layout_tests/fast/reflections/reflection-computed-style.html
+/sdcard/android/layout_tests/animations/transition-and-animation-2.html
+/sdcard/android/layout_tests/animations/import-crash.html
+/sdcard/android/layout_tests/animations/empty-keyframes.html
+/sdcard/android/layout_tests/animations/width-using-ems.html
+/sdcard/android/layout_tests/animations/keyframes-out-of-order.html
+/sdcard/android/layout_tests/geolocation/geolocation-not-implemented.html
+/sdcard/android/layout_tests/traversal/node-iterator-003.html
+/sdcard/android/layout_tests/traversal/node-iterator-005.html
+/sdcard/android/layout_tests/traversal/node-iterator-007.html
+/sdcard/android/layout_tests/traversal/tree-walker-001.html
+/sdcard/android/layout_tests/traversal/node-iterator-009.html
+/sdcard/android/layout_tests/traversal/tree-walker-003.html
+/sdcard/android/layout_tests/traversal/tree-walker-005.html
+/sdcard/android/layout_tests/traversal/exception-forwarding.html
+/sdcard/android/layout_tests/traversal/stay-within-root.html
+/sdcard/android/layout_tests/traversal/node-iterator-002.html
+/sdcard/android/layout_tests/traversal/node-iterator-004.html
+/sdcard/android/layout_tests/traversal/node-iterator-006.html
+/sdcard/android/layout_tests/traversal/node-iterator-006a.html
+/sdcard/android/layout_tests/traversal/tree-walker-002.html
+/sdcard/android/layout_tests/traversal/node-iterator-008.html
+/sdcard/android/layout_tests/traversal/tree-walker-004.html
+/sdcard/android/layout_tests/traversal/tree-walker-006.html
+/sdcard/android/layout_tests/traversal/size-zero-run.html
+/sdcard/android/layout_tests/traversal/acid3-test-2.html
+/sdcard/android/layout_tests/traversal/tree-walker-filter-1.html
+/sdcard/android/layout_tests/traversal/node-iterator-001.html
+/sdcard/android/layout_tests/css2.1/atrule_longest_match.html
+/sdcard/android/layout_tests/css1/units/zero-duration-without-units.html
+/sdcard/android/layout_tests/css3/khtml-background-size-0x0-bmp.html
+/sdcard/android/layout_tests/transitions/transition-end-event-all-properties.html
+/sdcard/android/layout_tests/transitions/transition-end-event-window.html
+/sdcard/android/layout_tests/transitions/transition-end-event-multiple-03.html
+/sdcard/android/layout_tests/transitions/interrupted-all-transition.html
+/sdcard/android/layout_tests/transitions/transition-end-event-set-none.html
+/sdcard/android/layout_tests/transitions/zero-duration-without-units.html
+/sdcard/android/layout_tests/transitions/zero-duration-with-non-zero-delay-start.html
+/sdcard/android/layout_tests/transitions/inherit-other-props.html
+/sdcard/android/layout_tests/transitions/transition-end-event-multiple-04.html
+/sdcard/android/layout_tests/transitions/transition-duration-cleared-in-transitionend-crash.html
+/sdcard/android/layout_tests/transitions/interrupt-zero-duration.html
+/sdcard/android/layout_tests/transitions/retargetted-transition.html
+/sdcard/android/layout_tests/transitions/override-transition-crash.html
+/sdcard/android/layout_tests/transitions/transition-end-event-left.html
+/sdcard/android/layout_tests/transitions/matched-transform-functions.html
+/sdcard/android/layout_tests/transitions/transition-end-event-multiple-01.html
+/sdcard/android/layout_tests/transitions/transform-op-list-match.html
+/sdcard/android/layout_tests/transitions/interrupt-transform-transition.html
+/sdcard/android/layout_tests/transitions/transition-end-event-container.html
+/sdcard/android/layout_tests/transitions/transition-end-event-nested.html
+/sdcard/android/layout_tests/transitions/change-values-during-transition.html
+/sdcard/android/layout_tests/transitions/transition-end-event-attributes.html
+/sdcard/android/layout_tests/transitions/inherit.html
+/sdcard/android/layout_tests/transitions/transition-end-event-create.html
+/sdcard/android/layout_tests/transitions/transition-end-event-multiple-02.html
+/sdcard/android/layout_tests/transitions/shadow.html
+/sdcard/android/layout_tests/transitions/transition-end-event-transform.html
+/sdcard/android/layout_tests/transitions/transition-timing-function.html
+/sdcard/android/layout_tests/transitions/transform-op-list-no-match.html
+/sdcard/android/layout_tests/transitions/transition-end-event-destroy-renderer.html
diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py
index 5409a0c..50ccb24 100755
--- a/tests/DumpRenderTree/assets/run_layout_tests.py
+++ b/tests/DumpRenderTree/assets/run_layout_tests.py
@@ -61,7 +61,8 @@ def DumpRenderTreeFinished(adb_cmd):
adb_output = subprocess.Popen(shell_cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
return adb_output.strip() == "#DONE"
-def DiffResults(marker, new_results, old_results, diff_results, strip_reason):
+def DiffResults(marker, new_results, old_results, diff_results, strip_reason,
+ new_count_first=True):
""" Given two result files, generate diff and
write to diff_results file. All arguments are absolute paths
to files.
@@ -85,21 +86,25 @@ def DiffResults(marker, new_results, old_results, diff_results, strip_reason):
for i in range(0, len(cdict)):
cdict[i] = cdict[i].split(' ')[0] + "\n"
- # Find results in new_results missing in old_results
- new_count=0
- for line in ndict:
- if line not in cdict:
- diff_file.writelines("+ " + line)
- new_count += 1
-
- # Find results in old_results missing in new_results
- missing_count=0
- for line in cdict:
- if line not in ndict:
- diff_file.writelines("- " + line)
- missing_count += 1
-
- logging.info(marker + " >>> " + str(new_count) + " new, " + str(missing_count) + " misses")
+ params = {
+ "new": [0, ndict, cdict, "+"],
+ "miss": [0, cdict, ndict, "-"]
+ }
+ if new_count_first:
+ order = ["new", "miss"]
+ else:
+ order = ["miss", "new"]
+
+ for key in order:
+ for line in params[key][1]:
+ if line not in params[key][2]:
+ if line[-1] != "\n":
+ line += "\n";
+ diff_file.writelines(params[key][3] + line)
+ params[key][0] += 1
+
+ logging.info(marker + " >>> " + str(params["new"][0]) + " new, " +
+ str(params["miss"][0]) + " misses")
diff_file.writelines("\n\n")
@@ -121,12 +126,12 @@ def CompareResults(ref_dir, results_dir):
if os.path.exists(diff_result):
os.remove(diff_result)
- files=["passed", "failed", "nontext", "crashed"]
+ files=["crashed", "failed", "passed", "nontext"]
for f in files:
result_file_name = "layout_tests_" + f + ".txt"
DiffResults(f, os.path.join(results_dir, result_file_name),
os.path.join(ref_dir, result_file_name), diff_result,
- f == "failed")
+ False, files != "passed")
logging.info("Detailed diffs are in " + diff_result)
def main(options, args):
diff --git a/tests/DumpRenderTree/assets/run_reliability_tests.py b/tests/DumpRenderTree/assets/run_reliability_tests.py
index 076c508..23f93df 100755
--- a/tests/DumpRenderTree/assets/run_reliability_tests.py
+++ b/tests/DumpRenderTree/assets/run_reliability_tests.py
@@ -14,10 +14,12 @@ import os
import subprocess
import sys
import time
+from Numeric import *
TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt"
+TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt"
HTTP_URL_FILE = "urllist_http"
HTTPS_URL_FILE = "urllist_https"
NUM_URLS = 25
@@ -62,6 +64,43 @@ def Bugreport(url, bugreport_dir, adb_cmd):
os.system(cmd)
+def ProcessPageLoadTime(raw_log):
+ """Processes the raw page load time logged by test app."""
+ log_handle = open(raw_log, "r")
+ load_times = {}
+
+ for line in log_handle:
+ line = line.strip()
+ pair = line.split("|")
+ if len(pair) != 2:
+ logging.info("Line has more than one '|': " + line)
+ continue
+ if pair[0] not in load_times:
+ load_times[pair[0]] = []
+ try:
+ pair[1] = int(pair[1])
+ except ValueError:
+ logging.info("Lins has non-numeric load time: " + line)
+ continue
+ load_times[pair[0]].append(pair[1])
+
+ log_handle.close()
+
+ # rewrite the average time to file
+ log_handle = open(raw_log, "w")
+ for url, times in load_times.iteritems():
+ # calculate std
+ arr = array(times)
+ avg = average(arr)
+ d = arr - avg
+ std = sqrt(sum(d * d) / len(arr))
+ output = ("%-70s%-10d%-10d%-12.2f%-12.2f%s\n" %
+ (url, min(arr), max(arr), avg, std,
+ array2string(arr)))
+ log_handle.write(output)
+ log_handle.close()
+
+
def main(options, args):
"""Send the url list to device and start testing, restart if crashed."""
@@ -125,6 +164,7 @@ def main(options, args):
# clean up previous results
RemoveDeviceFile(adb_cmd, TEST_STATUS_FILE)
RemoveDeviceFile(adb_cmd, TEST_TIMEOUT_FILE)
+ RemoveDeviceFile(adb_cmd, TEST_LOAD_TIME_FILE)
logging.info("Running the test ...")
@@ -141,8 +181,13 @@ def main(options, args):
# Call ReliabilityTestsAutoTest#startReliabilityTests
test_cmd = (test_cmd_prefix + " -e class "
"com.android.dumprendertree.ReliabilityTest#"
- "runReliabilityTest -e timeout %s -e delay %s %s" %
- (str(timeout_ms), str(manual_delay), test_cmd_postfix))
+ "runReliabilityTest -e timeout %s -e delay %s" %
+ (str(timeout_ms), str(manual_delay)))
+
+ if options.logtime:
+ test_cmd += " -e logtime true"
+
+ test_cmd += test_cmd_postfix
adb_output = subprocess.Popen(test_cmd, shell=True,
stdout=subprocess.PIPE,
@@ -176,12 +221,20 @@ def main(options, args):
else:
logging.info("No crash found.")
+ # get timeout file from sdcard
test_cmd = (adb_cmd + "pull \"" + TEST_TIMEOUT_FILE + "\" \""
+ timedout_file + "\"")
-
subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()
+ if options.logtime:
+ # get logged page load times from sdcard
+ test_cmd = (adb_cmd + "pull \"" + TEST_LOAD_TIME_FILE + "\" \""
+ + options.logtime + "\"")
+ subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).communicate()
+ ProcessPageLoadTime(options.logtime)
+
if "__main__" == __name__:
option_parser = optparse.OptionParser()
@@ -206,5 +259,8 @@ if "__main__" == __name__:
option_parser.add_option("-b", "--bugreport",
default=".",
help="the directory to store bugreport for crashes")
+ option_parser.add_option("-l", "--logtime",
+ default=None,
+ help="Logs page load time for each url to the file")
opts, arguments = option_parser.parse_args()
main(opts, arguments)
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
index 57e06a1..e00d3ad 100755
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
@@ -69,11 +69,16 @@ public class LayoutTestsAutoRunner extends InstrumentationTestRunner {
String r = (String)icicle.get("rebaseline");
this.mRebaseline = (r != null && r.toLowerCase().equals("true"));
super.onCreate(icicle);
+
+ String logtime = (String) icicle.get("logtime");
+ this.mLogtime = (logtime != null
+ && logtime.toLowerCase().equals("true"));
}
public String mTestPath = null;
public int mTimeoutInMillis = 0;
public int mDelay = 0;
public boolean mRebaseline = false;
+ public boolean mLogtime = false;
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index 22c458c..16973be 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -1,6 +1,7 @@
package com.android.dumprendertree;
import android.os.Handler;
+import android.os.Message;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
@@ -15,43 +16,44 @@ import java.io.InputStream;
import java.io.OutputStream;
public class ReliabilityTest extends ActivityInstrumentationTestCase2<ReliabilityTestActivity> {
-
+
private static final String LOGTAG = "ReliabilityTest";
private static final String PKG_NAME = "com.android.dumprendertree";
private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
+ private static final String TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt";
private static final String TEST_DONE = "#DONE";
static final String RELIABILITY_TEST_RUNNER_FILES[] = {
"run_reliability_tests.py"
};
-
+
public ReliabilityTest() {
super(PKG_NAME, ReliabilityTestActivity.class);
}
-
+
public void runReliabilityTest() throws Throwable {
ReliabilityTestActivity activity = getActivity();
LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation();
-
+
File testListFile = new File(TEST_LIST_FILE);
if(!testListFile.exists())
throw new FileNotFoundException("test list file not found.");
-
+
BufferedReader listReader = new BufferedReader(
new FileReader(testListFile));
-
+
//always try to resume first, hence cleaning up status will be the
//responsibility of driver scripts
String lastUrl = readTestStatus();
if(lastUrl != null && !TEST_DONE.equals(lastUrl))
fastForward(listReader, lastUrl);
-
+
String url = null;
Handler handler = null;
boolean timeoutFlag = false;
long start, elapsed;
-
+
//read from BufferedReader instead of populating a list in advance,
//this will avoid excessive memory usage in case of a large list
while((url = listReader.readLine()) != null) {
@@ -65,9 +67,13 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
//use message to send new URL to avoid interacting with
//WebView in non-UI thread
handler = activity.getHandler();
- handler.sendMessage(handler.obtainMessage(
- ReliabilityTestActivity.MSG_NAVIGATE,
- runner.mTimeoutInMillis, runner.mDelay, url));
+ Message msg = handler.obtainMessage(
+ ReliabilityTestActivity.MSG_NAVIGATE,
+ runner.mTimeoutInMillis, runner.mDelay);
+ msg.getData().putString(ReliabilityTestActivity.MSG_NAV_URL, url);
+ msg.getData().putBoolean(ReliabilityTestActivity.MSG_NAV_LOGTIME,
+ runner.mLogtime);
+ handler.sendMessage(msg);
timeoutFlag = activity.waitUntilDone();
elapsed = System.currentTimeMillis() - start;
if(elapsed < 1000) {
@@ -79,6 +85,9 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
if(timeoutFlag) {
writeTimeoutFile(url);
}
+ if(runner.mLogtime) {
+ writeLoadTime(url, activity.getPageLoadTime());
+ }
System.runFinalization();
System.gc();
System.gc();
@@ -87,7 +96,7 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
activity.finish();
listReader.close();
}
-
+
public void copyRunnerAssetsToCache() {
try {
String out_dir = getActivity().getApplicationContext()
@@ -112,7 +121,7 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
Log.e(LOGTAG, "Cannot extract scripts for testing.", e);
}
}
-
+
private void updateTestStatus(String s) {
// write last tested url into status file
try {
@@ -124,7 +133,7 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
Log.e(LOGTAG, "Cannot update file " + TEST_STATUS_FILE, e);
}
}
-
+
private String readTestStatus() {
// read out the test name it stopped last time.
String status = null;
@@ -141,12 +150,12 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
}
return status;
}
-
+
private void fastForward(BufferedReader testListReader, String lastUrl) {
//fastforward the BufferedReader to the position right after last url
if(lastUrl == null)
return;
-
+
String line = null;
try {
while((line = testListReader.readLine()) != null) {
@@ -160,7 +169,7 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
}
private void writeTimeoutFile(String s) {
- //append to the file containing the list of timeout urls
+ //append to the file containing the list of timeout urls
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(TEST_TIMEOUT_FILE, true));
@@ -171,4 +180,16 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit
Log.e(LOGTAG, "Cannot update file " + TEST_TIMEOUT_FILE, e);
}
}
+
+ private void writeLoadTime(String s, long time) {
+ //append to the file containing the list of timeout urls
+ try {
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(TEST_LOAD_TIME_FILE, true));
+ bos.write((s + '|' + time + '\n').getBytes());
+ bos.close();
+ } catch (Exception e) {
+ Log.e(LOGTAG, "Cannot update file " + TEST_LOAD_TIME_FILE, e);
+ }
+ }
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
index cbec104..5ddd0b3 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
@@ -21,52 +21,57 @@ import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
public class ReliabilityTestActivity extends Activity {
-
+
public static final String TEST_URL_ACTION = "com.andrdoid.dumprendertree.TestUrlAction";
public static final String PARAM_URL = "URL";
public static final String PARAM_TIMEOUT = "Timeout";
public static final int RESULT_TIMEOUT = 0xDEAD;
public static final int MSG_TIMEOUT = 0xC001;
public static final int MSG_NAVIGATE = 0xC002;
-
+ public static final String MSG_NAV_URL = "url";
+ public static final String MSG_NAV_LOGTIME = "logtime";
+
private static final String LOGTAG = "ReliabilityTestActivity";
-
+
private WebView webView;
private SimpleWebViewClient webViewClient;
private SimpleChromeClient chromeClient;
private Handler handler;
private boolean timeoutFlag;
+ private boolean logTime;
private boolean pageDone;
private Object pageDoneLock;
private int pageStartCount;
private int manualDelay;
+ private long startTime;
+ private long pageLoadTime;
private PageDoneRunner pageDoneRunner = new PageDoneRunner();
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
-
+
LinearLayout contentView = new LinearLayout(this);
contentView.setOrientation(LinearLayout.VERTICAL);
setContentView(contentView);
setTitle("Idle");
-
+
webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
-
+
webViewClient = new SimpleWebViewClient();
chromeClient = new SimpleChromeClient();
webView.setWebViewClient(webViewClient);
webView.setWebChromeClient(chromeClient);
-
+
contentView.addView(webView, new LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT, 0.0f));
-
+
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -76,15 +81,16 @@ public class ReliabilityTestActivity extends Activity {
return;
case MSG_NAVIGATE:
manualDelay = msg.arg2;
- navigate((String)msg.obj, msg.arg1);
+ navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
+ logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
return;
}
}
};
-
+
pageDoneLock = new Object();
}
-
+
public void reset() {
synchronized (pageDoneLock) {
pageDone = false;
@@ -93,49 +99,54 @@ public class ReliabilityTestActivity extends Activity {
pageStartCount = 0;
chromeClient.resetJsTimeout();
}
-
+
private void navigate(String url, int timeout) {
if(url == null) {
Log.v(LOGTAG, "URL is null, cancelling...");
finish();
}
webView.stopLoading();
+ if(logTime) {
+ webView.clearCache(true);
+ }
+ startTime = System.currentTimeMillis();
Log.v(LOGTAG, "Navigating to URL: " + url);
webView.loadUrl(url);
-
+
if(timeout != 0) {
//set a timer with specified timeout (in ms)
handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
timeout);
}
}
-
+
@Override
protected void onDestroy() {
Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
super.onDestroy();
}
-
+
private boolean isPageDone() {
synchronized (pageDoneLock) {
return pageDone;
}
}
-
+
private void setPageDone(boolean pageDone) {
synchronized (pageDoneLock) {
this.pageDone = pageDone;
pageDoneLock.notifyAll();
}
}
-
+
private void handleTimeout() {
int progress = webView.getProgress();
webView.stopLoading();
Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
timeoutFlag = true;
+ handler.postDelayed(pageDoneRunner, manualDelay);
}
-
+
public boolean waitUntilDone() {
validateNotAppThread();
synchronized (pageDoneLock) {
@@ -149,11 +160,11 @@ public class ReliabilityTestActivity extends Activity {
}
return timeoutFlag;
}
-
+
public Handler getHandler() {
return handler;
}
-
+
private final void validateNotAppThread() {
if (ActivityThread.currentActivityThread() != null) {
throw new RuntimeException(
@@ -161,8 +172,12 @@ public class ReliabilityTestActivity extends Activity {
}
}
+ public long getPageLoadTime() {
+ return pageLoadTime;
+ }
+
class SimpleWebViewClient extends WebViewClient {
-
+
@Override
public void onReceivedError(WebView view, int errorCode, String description,
String failingUrl) {
@@ -170,50 +185,52 @@ public class ReliabilityTestActivity extends Activity {
+ ", description=" + description
+ ", url=" + failingUrl);
}
-
+
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
//ignore certificate error
Log.v(LOGTAG, "Received SSL error: " + error.toString());
handler.proceed();
}
-
+
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
String realm) {
- //cancel http auth request
+ // cancel http auth request
handler.cancel();
}
-
+
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
pageStartCount++;
Log.v(LOGTAG, "onPageStarted: " + url);
}
-
+
@Override
public void onPageFinished(WebView view, String url) {
Log.v(LOGTAG, "onPageFinished: " + url);
- handler.postDelayed(new WebViewStatusChecker(), 500);
+ // let handleTimeout take care of finishing the page
+ if(!timeoutFlag)
+ handler.postDelayed(new WebViewStatusChecker(), 500);
}
}
-
+
class SimpleChromeClient extends WebChromeClient {
-
+
private int timeoutCounter = 0;
-
+
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
result.confirm();
return true;
}
-
+
@Override
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
result.confirm();
return true;
}
-
+
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
result.confirm();
@@ -226,32 +243,32 @@ public class ReliabilityTestActivity extends Activity {
result.confirm();
return true;
}
-
+
@Override
public boolean onJsTimeout() {
timeoutCounter++;
Log.v(LOGTAG, "JavaScript timeout, count=" + timeoutCounter);
return timeoutCounter > 2;
}
-
+
public void resetJsTimeout() {
timeoutCounter = 0;
}
-
+
@Override
public void onReceivedTitle(WebView view, String title) {
ReliabilityTestActivity.this.setTitle(title);
}
}
-
+
class WebViewStatusChecker implements Runnable {
-
+
private int initialStartCount;
-
+
public WebViewStatusChecker() {
initialStartCount = pageStartCount;
}
-
+
public void run() {
if (initialStartCount == pageStartCount) {
//perform cleanup
@@ -261,11 +278,12 @@ public class ReliabilityTestActivity extends Activity {
}
}
}
-
+
class PageDoneRunner implements Runnable {
-
+
public void run() {
Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
+ pageLoadTime = System.currentTimeMillis() - startTime;
setPageDone(true);
}
}
diff --git a/tests/backup/backup_helper_test.cpp b/tests/backup/backup_helper_test.cpp
index f087941..04358ad 100644
--- a/tests/backup/backup_helper_test.cpp
+++ b/tests/backup/backup_helper_test.cpp
@@ -38,6 +38,8 @@ Test TESTS[] = {
{ "backup_helper_test_empty", backup_helper_test_empty, 0, false },
{ "backup_helper_test_four", backup_helper_test_four, 0, false },
{ "backup_helper_test_files", backup_helper_test_files, 0, false },
+ { "backup_helper_test_null_base", backup_helper_test_null_base, 0, false },
+ { "backup_helper_test_missing_file", backup_helper_test_missing_file, 0, false },
{ "backup_helper_test_data_writer", backup_helper_test_data_writer, 0, false },
{ "backup_helper_test_data_reader", backup_helper_test_data_reader, 0, false },
{ 0, NULL, 0, false}
diff --git a/tests/backup/src/com/android/backuptest/BackupTestAgent.java b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
index 11e520e..a370d69 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestAgent.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestAgent.java
@@ -30,7 +30,8 @@ public class BackupTestAgent extends BackupAgent
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) {
Log.d(TAG, "onBackup");
- FileBackupHelper.performBackup(this, oldState, data, newState, new String[] {
+ FileBackupHelper helper = new FileBackupHelper(this);
+ helper.performBackup(oldState, data, newState, new String[] {
BackupTestActivity.FILE_NAME
});
}
diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk
new file mode 100644
index 0000000..a6df98e
--- /dev/null
+++ b/tests/permission/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_PACKAGE_NAME := FrameworkPermissionTests
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/permission/AndroidManifest.xml b/tests/permission/AndroidManifest.xml
new file mode 100644
index 0000000..b19bf00
--- /dev/null
+++ b/tests/permission/AndroidManifest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2009 Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.framework.permission.tests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ The test declared in this instrumentation can be run via this command
+ "adb shell am instrument -w com.android.framework.permission.tests/android.test.InstrumentationTestRunner"
+ -->
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.framework.permission.tests"
+ android:label="Tests for private API framework permissions"/>
+
+</manifest>
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
new file mode 100644
index 0000000..14d3d73
--- /dev/null
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -0,0 +1,182 @@
+package com.android.framework.permission.tests;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.content.res.Configuration;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * TODO: Remove this. This is only a placeholder, need to implement this.
+ */
+public class ActivityManagerPermissionTests extends TestCase {
+ IActivityManager mAm;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mAm = ActivityManagerNative.getDefault();
+ }
+
+ @SmallTest
+ public void testREORDER_TASKS() {
+ try {
+ mAm.moveTaskToFront(-1);
+ fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mAm.moveTaskToBack(-1);
+ fail("IActivityManager.moveTaskToBack did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mAm.moveTaskBackwards(-1);
+ fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testCHANGE_CONFIGURATION() {
+ try {
+ mAm.updateConfiguration(new Configuration());
+ fail("IActivityManager.updateConfiguration did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSET_DEBUG_APP() {
+ try {
+ mAm.setDebugApp(null, false, false);
+ fail("IActivityManager.setDebugApp did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSET_PROCESS_LIMIT() {
+ try {
+ mAm.setProcessLimit(10);
+ fail("IActivityManager.setProcessLimit did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testALWAYS_FINISH() {
+ try {
+ mAm.setAlwaysFinish(false);
+ fail("IActivityManager.setAlwaysFinish did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSIGNAL_PERSISTENT_PROCESSES() {
+ try {
+ mAm.signalPersistentProcesses(-1);
+ fail("IActivityManager.signalPersistentProcesses did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testFORCE_BACK() {
+ try {
+ mAm.unhandledBack();
+ fail("IActivityManager.unhandledBack did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSET_ACTIVITY_WATCHER() {
+ try {
+ mAm.setActivityWatcher(null);
+ fail("IActivityManager.setActivityWatcher did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSHUTDOWN() {
+ try {
+ mAm.shutdown(0);
+ fail("IActivityManager.shutdown did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSTOP_APP_SWITCHES() {
+ try {
+ mAm.stopAppSwitches();
+ fail("IActivityManager.stopAppSwitches did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mAm.resumeAppSwitches();
+ fail("IActivityManager.resumeAppSwitches did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+}
diff --git a/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
new file mode 100644
index 0000000..b690c45
--- /dev/null
+++ b/tests/permission/src/com/android/framework/permission/tests/PmPermissionsTests.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.permission.tests;
+
+import junit.framework.TestCase;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Verify PackageManager api's that require specific permissions.
+ */
+public class PmPermissionsTests extends AndroidTestCase {
+ private PackageManager mPm;
+ private String mPkgName = "com.android.framework.permission.tests";
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mPm = getContext().getPackageManager();
+ }
+
+ /*
+ * This test verifies that PackageManger.getPackageSizeInfo enforces permission
+ * android.permission.GET_PACKAGE_SIZE
+ */
+ @SmallTest
+ public void testGetPackageSize() {
+ try {
+ mPm.getPackageSizeInfo(mPkgName, null);
+ fail("PackageManager.getPackageSizeInfo" +
+ "did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /*
+ * This test verifies that PackageManger.DeleteApplicationCacheFiles enforces permission
+ * android.permission.DELETE_CACHE_FILES
+ */
+ @SmallTest
+ public void testDeleteApplicationCacheFiles() {
+ try {
+ mPm.deleteApplicationCacheFiles(mPkgName, null);
+ fail("PackageManager.deleteApplicationCacheFiles" +
+ "did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /*
+ * This test verifies that PackageManger.installPackage enforces permission
+ * android.permission.INSTALL_PACKAGES
+ */
+ @SmallTest
+ public void testInstallPackage() {
+ try {
+ mPm.installPackage(null, null, 0, null);
+ fail("PackageManager.installPackage" +
+ "did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /*
+ * This test verifies that PackageManger.freeStorage
+ * enforces permission android.permission.CLEAR_APP_CACHE
+ */
+ @SmallTest
+ public void testFreeStorage1() {
+ try {
+ mPm.freeStorage(100000, null);
+ fail("PackageManager.freeStorage " +
+ "did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /*
+ * This test verifies that PackageManger.freeStorageAndNotify
+ * enforces permission android.permission.CLEAR_APP_CACHE
+ */
+ @SmallTest
+ public void testFreeStorage2() {
+ try {
+ mPm.freeStorageAndNotify(100000, null);
+ fail("PackageManager.freeStorageAndNotify" +
+ " did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /*
+ * This test verifies that PackageManger.clearApplicationUserData
+ * enforces permission android.permission.CLEAR_APP_USER_DATA
+ */
+ @SmallTest
+ public void testClearApplicationUserData() {
+ try {
+ mPm.clearApplicationUserData(mPkgName, null);
+ fail("PackageManager.clearApplicationUserData" +
+ "did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /*
+ * This test verifies that PackageManger.deletePackage
+ * enforces permission android.permission.DELETE_PACKAGES
+ */
+ @SmallTest
+ public void testDeletePackage() {
+ try {
+ mPm.deletePackage(mPkgName, null, 0);
+ fail("PackageManager.deletePackage" +
+ "did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
new file mode 100644
index 0000000..3f1e27e
--- /dev/null
+++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
@@ -0,0 +1,50 @@
+package com.android.framework.permission.tests;
+
+import com.android.internal.os.BinderInternal;
+
+import android.os.Binder;
+import android.os.IPermissionController;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManagerNative;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * TODO: Remove this. This is only a placeholder, need to implement this.
+ */
+public class ServiceManagerPermissionTests extends TestCase {
+ @SmallTest
+ public void testAddService() {
+ try {
+ // The security in the service manager is that you can't replace
+ // a service that is already published.
+ Binder binder = new Binder();
+ ServiceManager.addService("activity", binder);
+ fail("ServiceManager.addService did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @SmallTest
+ public void testSetPermissionController() {
+ try {
+ IPermissionController pc = new IPermissionController.Stub() {
+ public boolean checkPermission(java.lang.String permission, int pid, int uid) {
+ return true;
+ }
+ };
+ ServiceManagerNative.asInterface(BinderInternal.getContextObject())
+ .setPermissionController(pc);
+ fail("IServiceManager.setPermissionController did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+}
diff --git a/tests/permission/src/com/android/framework/permission/tests/SettingsPermissionsTests.java b/tests/permission/src/com/android/framework/permission/tests/SettingsPermissionsTests.java
new file mode 100644
index 0000000..f55998f
--- /dev/null
+++ b/tests/permission/src/com/android/framework/permission/tests/SettingsPermissionsTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.permission.tests;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.provider.Settings;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+/**
+ * Verify that accessing private-API protected Settings require specific permissions.
+ */
+public class SettingsPermissionsTests extends AndroidTestCase {
+
+ private ContentResolver mContentResolver;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContentResolver = getContext().getContentResolver();
+ }
+
+ /**
+ * Verify that writing to the GServices table in Settings provider requires permissions.
+ * <p>Tests Permission:
+ * {@link android.Manifest.permission#WRITE_GSERVICES}
+ */
+ @MediumTest
+ public void testWriteGServices() {
+ try {
+ ContentValues values = new ContentValues();
+ values.put("url", "android");
+ mContentResolver.insert(Settings.Gservices.CONTENT_URI, values);
+ fail("Write into Gservices provider did not throw SecurityException as expected.");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+} \ No newline at end of file
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
new file mode 100644
index 0000000..8ab2a10
--- /dev/null
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -0,0 +1,409 @@
+package com.android.framework.permission.tests;
+
+import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.IWindowManager;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import junit.framework.TestCase;
+
+/**
+ * TODO: Remove this. This is only a placeholder, need to implement this.
+ */
+public class WindowManagerPermissionTests extends TestCase {
+ IWindowManager mWm;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mWm = IWindowManager.Stub.asInterface(
+ ServiceManager.getService("window"));
+ }
+
+ @SmallTest
+ public void testMANAGE_APP_TOKENS() {
+ try {
+ mWm.pauseKeyDispatching(null);
+ fail("IWindowManager.pauseKeyDispatching did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.resumeKeyDispatching(null);
+ fail("IWindowManager.resumeKeyDispatching did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setEventDispatching(true);
+ fail("IWindowManager.setEventDispatching did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.addWindowToken(null, 0);
+ fail("IWindowManager.addWindowToken did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.removeWindowToken(null);
+ fail("IWindowManager.removeWindowToken did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.addAppToken(0, null, 0, 0, false);
+ fail("IWindowManager.addAppToken did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setAppGroupId(null, 0);
+ fail("IWindowManager.setAppGroupId did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.updateOrientationFromAppTokens(new Configuration(), null);
+ fail("IWindowManager.updateOrientationFromAppTokens did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setAppOrientation(null, 0);
+ mWm.addWindowToken(null, 0);
+ fail("IWindowManager.setAppOrientation did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setFocusedApp(null, false);
+ fail("IWindowManager.setFocusedApp did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.prepareAppTransition(0);
+ fail("IWindowManager.prepareAppTransition did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.executeAppTransition();
+ fail("IWindowManager.executeAppTransition did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setAppStartingWindow(null, "foo", 0, null, 0, 0, null, false);
+ fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setAppWillBeHidden(null);
+ fail("IWindowManager.setAppWillBeHidden did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setAppVisibility(null, false);
+ fail("IWindowManager.setAppVisibility did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.startAppFreezingScreen(null, 0);
+ fail("IWindowManager.startAppFreezingScreen did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.stopAppFreezingScreen(null, false);
+ fail("IWindowManager.stopAppFreezingScreen did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.removeAppToken(null);
+ fail("IWindowManager.removeAppToken did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.moveAppToken(0, null);
+ fail("IWindowManager.moveAppToken did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.moveAppTokensToTop(null);
+ fail("IWindowManager.moveAppTokensToTop did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.moveAppTokensToBottom(null);
+ fail("IWindowManager.moveAppTokensToBottom did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testINJECT_EVENTS() {
+ try {
+ mWm.injectKeyEvent(new KeyEvent(0, 0), false);
+ fail("IWindowManager.injectKeyEvent did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.injectPointerEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0), false);
+ fail("IWindowManager.injectPointerEvent did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.injectTrackballEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0), false);
+ fail("IWindowManager.injectTrackballEvent did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testDISABLE_KEYGUARD() {
+ Binder token = new Binder();
+ try {
+ mWm.disableKeyguard(token, "foo");
+ fail("IWindowManager.disableKeyguard did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.reenableKeyguard(token);
+ fail("IWindowManager.reenableKeyguard did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.exitKeyguardSecurely(null);
+ fail("IWindowManager.exitKeyguardSecurely did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSET_ANIMATION_SCALE() {
+ try {
+ mWm.setAnimationScale(0, 1);
+ fail("IWindowManager.setAnimationScale did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.setAnimationScales(new float[1]);
+ fail("IWindowManager.setAnimationScales did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testREAD_INPUT_STATE() {
+ try {
+ mWm.getSwitchState(0);
+ fail("IWindowManager.getSwitchState did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.getSwitchStateForDevice(0, 0);
+ fail("IWindowManager.getSwitchStateForDevice did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.getScancodeState(0);
+ fail("IWindowManager.getScancodeState did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.getScancodeStateForDevice(0, 0);
+ fail("IWindowManager.getScancodeStateForDevice did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.getKeycodeState(0);
+ fail("IWindowManager.getKeycodeState did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+
+ try {
+ mWm.getKeycodeStateForDevice(0, 0);
+ fail("IWindowManager.getKeycodeStateForDevice did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+
+ @SmallTest
+ public void testSET_ORIENTATION() {
+ try {
+ mWm.setRotation(0, true, 0);
+ mWm.getSwitchState(0);
+ fail("IWindowManager.setRotation did not throw SecurityException as"
+ + " expected");
+ } catch (SecurityException e) {
+ // expected
+ } catch (RemoteException e) {
+ fail("Unexpected remote exception");
+ }
+ }
+}
diff --git a/tests/sketch/Android.mk b/tests/sketch/Android.mk
deleted file mode 100644
index 814e370..0000000
--- a/tests/sketch/Android.mk
+++ /dev/null
@@ -1,8 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := Sketch
-
-include $(BUILD_PACKAGE)
diff --git a/tests/sketch/AndroidManifest.xml b/tests/sketch/AndroidManifest.xml
deleted file mode 100755
index b8a13f6..0000000
--- a/tests/sketch/AndroidManifest.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008-2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.gesture.example">
-
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
- <application android:icon="@drawable/icon" android:label="@string/app_name">
-
- <activity
- android:name="com.android.gesture.example.GestureEntry"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <activity android:name="com.android.gesture.example.GestureLibViewer"/>
-
- <activity
- android:name="com.android.gesture.example.ContactListGestureOverlay"
- android:label="@string/overlay_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- </application>
-</manifest>
diff --git a/tests/sketch/res/drawable/icon.png b/tests/sketch/res/drawable/icon.png
deleted file mode 100755
index 7502484..0000000
--- a/tests/sketch/res/drawable/icon.png
+++ /dev/null
Binary files differ
diff --git a/tests/sketch/res/layout/demo.xml b/tests/sketch/res/layout/demo.xml
deleted file mode 100755
index c3a78cf..0000000
--- a/tests/sketch/res/layout/demo.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <Spinner
- android:id="@+id/spinner"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:drawSelectorOnTop="true"
- android:prompt="@string/recognition_result"/>
-
- <android.gesture.GestureOverlayView
- android:id="@+id/drawingpad"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1" />
-
-</LinearLayout>
diff --git a/tests/sketch/res/layout/gestureviewer.xml b/tests/sketch/res/layout/gestureviewer.xml
deleted file mode 100755
index e4cca52..0000000
--- a/tests/sketch/res/layout/gestureviewer.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <Spinner
- android:id="@+id/spinner"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:drawSelectorOnTop="true"
- android:prompt="@string/recognition_result"/>
-
- <android.gesture.GestureOverlayView
- android:id="@+id/drawingpad"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1" />
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <Button
- android:id="@+id/previous"
- android:text="@string/previous"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- <Button
- android:id="@+id/remove"
- android:text="@string/remove"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- <Button
- android:id="@+id/next"
- android:text="@string/next"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
- </LinearLayout>
-
-</LinearLayout>
diff --git a/tests/sketch/res/layout/newgesture_dialog.xml b/tests/sketch/res/layout/newgesture_dialog.xml
deleted file mode 100755
index 91e7645..0000000
--- a/tests/sketch/res/layout/newgesture_dialog.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <EditText
- android:id="@+id/gesturename_edit"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="20dip"
- android:scrollHorizontally="true"
- android:autoText="false"
- android:capitalize="none"
- android:gravity="fill_horizontal"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
-</LinearLayout>
diff --git a/tests/sketch/src/com/android/gesture/example/ContactAdapter.java b/tests/sketch/src/com/android/gesture/example/ContactAdapter.java
deleted file mode 100644
index 008a972..0000000
--- a/tests/sketch/src/com/android/gesture/example/ContactAdapter.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gesture.example;
-
-import android.app.Activity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-
-class ContactAdapter extends ArrayAdapter<ContactItem> {
-
- private LayoutInflater mInflater;
-
- public ContactAdapter(Activity activity, ArrayList<ContactItem> contacts) {
- super(activity, 0, contacts);
- mInflater = activity.getLayoutInflater();
- }
-
- @Override
- public ContactItem getItem(int position) {
- return super.getItem(position);
- }
-
- @Override
- public long getItemId(int position) {
- return getItem(position).itemID;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final ContactItem info = getItem(position);
-
- View view = convertView;
- if (view == null) {
- view = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
- view.setTag(view.findViewById(android.R.id.text1));
- }
-
- final TextView textView = (TextView)view.getTag();
- textView.setText(info.toString());
-
- return view;
- }
-
- public int search(String query) {
- if (query != null && query.length() > 0) {
- int start = 0;
- int end = getCount() - 1;
- int index = binarySearch(query, start, end);
- for (index = index - 1; index >= 0; index--) {
- String str = getItem(index).toString().toLowerCase();
- if (!str.startsWith(query)) {
- return index + 1;
- }
- if (index == 0) {
- return 0;
- }
- }
- return -1;
- } else {
- return -1;
- }
- }
-
- private int binarySearch(String prefix, int start, int end) {
- if (start > end) {
- return -1;
- }
- int mid = (start + end) / 2;
- String str = getItem(mid).toString().toLowerCase();
- if (prefix.compareTo(str) <= 0) {
- if (str.startsWith(prefix)) {
- return mid;
- } else {
- return binarySearch(prefix, start, mid - 1);
- }
- } else {
- return binarySearch(prefix, mid + 1, end);
- }
- }
-
-}
diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
deleted file mode 100644
index 7865a5c..0000000
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gesture.example;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Intent;
-import android.database.Cursor;
-import android.os.Bundle;
-import android.provider.Contacts.People;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.widget.AdapterView;
-import android.widget.ListView;
-
-import android.gesture.Gesture;
-import android.gesture.GestureOverlayView;
-import android.gesture.LetterRecognizer;
-import android.gesture.Prediction;
-import android.gesture.LetterRecognizers;
-
-import java.util.ArrayList;
-
-public class ContactListGestureOverlay extends Activity {
- private static final String LOG_TAG = "ContactListGestureOverlay";
- private static final String SORT_ORDER = People.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
- private static final String[] CONTACTS_PROJECTION = new String[] {
- People._ID, // 0
- People.DISPLAY_NAME, // 1
- };
-
- private ContactAdapter mContactAdapter;
-
- private ListView mContactList;
- private LetterRecognizer mRecognizer;
- private GestureOverlayView mOverlay;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
- setContentView(R.layout.overlaydemo);
-
- // create a letter recognizer
- mRecognizer = LetterRecognizers.fromType(this,
- LetterRecognizers.RECOGNIZER_LATIN_LOWERCASE);
- mOverlay = (GestureOverlayView) findViewById(R.id.overlay);
-
- // load the contact list
- mContactList = (ListView) findViewById(R.id.list);
- registerForContextMenu(mContactList);
- mContactList.setTextFilterEnabled(true);
- mContactList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
- if (!mOverlay.isGesturing()) {
- Intent intent = new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(
- People.CONTENT_URI, id));
- startActivity(intent);
- }
- }
- });
-
- ContentResolver resolver = getContentResolver();
- Cursor cursor = resolver.query(People.CONTENT_URI, CONTACTS_PROJECTION, null, null,
- SORT_ORDER);
- ArrayList<ContactItem> list = new ArrayList<ContactItem>();
- while (cursor.moveToNext()) {
- list.add(new ContactItem(cursor.getLong(0), cursor.getString(1)));
- }
- mContactAdapter = new ContactAdapter(this, list);
- mContactList.setAdapter(mContactAdapter);
-
- mOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
- mOverlay.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {
- public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
- ArrayList<Prediction> predictions = mRecognizer.recognize(gesture);
- if (!predictions.isEmpty()) {
- Log.v(LOG_TAG, "1st Prediction : " + predictions.get(0).name +
- " @" + predictions.get(0).score);
- Log.v(LOG_TAG, "2nd Prediction : " + predictions.get(1).name +
- " @" + predictions.get(1).score);
- Log.v(LOG_TAG, "3rd Prediction : " + predictions.get(2).name +
- " @" + predictions.get(2).score);
- int index = mContactAdapter.search(predictions.get(0).name);
- if (index != -1) {
- mContactList.setSelection(index);
- }
- }
- }
- });
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/example/GestureEntry.java b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
deleted file mode 100644
index 8dbec99..0000000
--- a/tests/sketch/src/com/android/gesture/example/GestureEntry.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gesture.example;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.Environment;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.gesture.Gesture;
-
-import android.gesture.GestureOverlayView;
-import android.gesture.Prediction;
-import android.gesture.GestureLibraries;
-import android.gesture.GestureLibrary;
-
-import java.io.File;
-import java.util.ArrayList;
-
-public class GestureEntry extends Activity {
-
- private static final String PARCEL_KEY = "gesture";
-
- static final String GESTURE_FILE_NAME =
- Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +
- "demo_library.gestures";
-
- private static final int DIALOG_NEW_ENTRY = 1;
-
- private static final int NEW_ID = Menu.FIRST;
-
- private static final int VIEW_ID = Menu.FIRST + 1;
-
- private GestureOverlayView mGesturePad;
-
- private Spinner mRecognitionResult;
-
- private GestureLibrary mGestureStore;
-
- private boolean mChangedByRecognizer = false;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.demo);
-
- // init the gesture library
- mGestureStore = GestureLibraries.fromFile(GESTURE_FILE_NAME);
- mGestureStore.load();
-
- // create the spinner for showing the recognition results
- // the spinner also allows a user to correct a prediction
- mRecognitionResult = (Spinner) findViewById(R.id.spinner);
- mRecognitionResult.setOnItemSelectedListener(new OnItemSelectedListener() {
-
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- // correct the recognition result by adding the new example
- if (!mChangedByRecognizer) {
- mGestureStore.addGesture(parent.getSelectedItem().toString(), mGesturePad
- .getGesture());
- } else {
- mChangedByRecognizer = false;
- }
- }
-
- public void onNothingSelected(AdapterView<?> parent) {
-
- }
-
- });
-
- // create the area for drawing a gesture
- mGesturePad = (GestureOverlayView) findViewById(R.id.drawingpad);
- mGesturePad.setBackgroundColor(Color.BLACK);
- mGesturePad.addOnGestureListener(new GestureOverlayView.OnGestureListener() {
- public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
- recognize(overlay.getGesture());
- }
-
- public void onGesture(GestureOverlayView overlay, MotionEvent event) {
- }
-
- public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
- overlay.clear(false);
- }
-
- public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
- }
- });
-
- if (savedInstanceState != null) {
- Gesture gesture = (Gesture) savedInstanceState.getParcelable(PARCEL_KEY);
- if (gesture != null) {
- mGesturePad.setGesture(gesture);
- }
- }
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- LayoutInflater factory = LayoutInflater.from(this);
- final View textEntryView = factory.inflate(R.layout.newgesture_dialog, null);
- return new AlertDialog.Builder(GestureEntry.this).setTitle(
- R.string.newgesture_text_entry).setView(textEntryView).setPositiveButton(
- R.string.newgesture_dialog_ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- EditText edittext = (EditText) ((AlertDialog) dialog)
- .findViewById(R.id.gesturename_edit);
- String text = edittext.getText().toString().trim();
- if (text.length() > 0) {
- mGestureStore.addGesture(text, mGesturePad.getGesture());
- }
- }
- }).setNegativeButton(R.string.newgesture_dialog_cancel,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- }
- }).create();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- super.onCreateOptionsMenu(menu);
- menu.add(0, NEW_ID, 0, R.string.newgesture).setShortcut('0', 'n').setIcon(
- android.R.drawable.ic_menu_add);
- menu.add(0, VIEW_ID, 0, R.string.viewgesture).setShortcut('1', 'v').setIcon(
- android.R.drawable.ic_menu_view);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case NEW_ID:
- if (mGesturePad.getGesture() != null) {
- showDialog(DIALOG_NEW_ENTRY);
- }
- break;
-
- case VIEW_ID:
- startActivityForResult(new Intent(this, GestureLibViewer.class), VIEW_ID);
- break;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- mGestureStore.load();
- mGesturePad.clear(false);
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mGestureStore.save();
- }
-
- @Override
- protected void onPrepareDialog(int id, Dialog dialog) {
- super.onPrepareDialog(id, dialog);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- Gesture gesture = mGesturePad.getGesture();
- if (gesture != null) {
- outState.putParcelable(PARCEL_KEY, gesture);
- }
- mGestureStore.save();
- }
-
- private void recognize(Gesture gesture) {
- mChangedByRecognizer = true;
- ArrayList<Prediction> predictions = mGestureStore.recognize(gesture);
- ArrayAdapter<Prediction> adapter = new ArrayAdapter<Prediction>(this,
- android.R.layout.simple_spinner_item, predictions);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mRecognitionResult.setAdapter(adapter);
- }
-
-}
diff --git a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
deleted file mode 100755
index f5bf683..0000000
--- a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2008-2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gesture.example;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.Spinner;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.gesture.Gesture;
-
-import android.gesture.GestureOverlayView;
-import android.gesture.GestureLibraries;
-import android.gesture.GestureLibrary;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * GestureLibViewer gives an example on how to browse existing gestures and
- * removing unwanted gestures.
- */
-
-public class GestureLibViewer extends Activity {
-
- private GestureOverlayView mGesturePad;
-
- private Spinner mGestureCategory;
-
- private GestureLibrary mGesureStore;
-
- private ArrayList<Gesture> mGestures;
-
- private int mCurrentGestureIndex;
-
- private class RemoveGestureListener implements OnClickListener {
- public void onClick(View v) {
- if (mGestures.isEmpty()) {
- return;
- }
-
- String name = (String) mGestureCategory.getSelectedItem();
- Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesureStore.removeGesture(name, gesture);
-
- mGestures = mGesureStore.getGestures(name);
-
- if (mGestures == null) {
- // delete the entire entry
- mCurrentGestureIndex = 0;
- ArrayList<String> list = new ArrayList<String>();
- list.addAll(mGesureStore.getGestureEntries());
- Collections.sort(list);
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(GestureLibViewer.this,
- android.R.layout.simple_spinner_item, list);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mGestureCategory.setAdapter(adapter);
- } else {
- if (mCurrentGestureIndex > mGestures.size() - 1) {
- mCurrentGestureIndex--;
- }
- gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setGesture(gesture);
- mGesturePad.invalidate();
- }
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.gestureviewer);
-
- // create the area for drawing a gesture
- mGesturePad = (GestureOverlayView) findViewById(R.id.drawingpad);
- mGesturePad.setEnabled(false);
-
- // init the gesture library
- mGesureStore = GestureLibraries.fromFile(GestureEntry.GESTURE_FILE_NAME);
- mGesureStore.load();
-
- mGestureCategory = (Spinner) findViewById(R.id.spinner);
- ArrayList<String> list = new ArrayList<String>();
- if (!mGesureStore.getGestureEntries().isEmpty()) {
- list.addAll(mGesureStore.getGestureEntries());
- Collections.sort(list);
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_spinner_item, list);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mGestureCategory.setAdapter(adapter);
- mGestures = mGesureStore.getGestures(list.get(0));
- mCurrentGestureIndex = 0;
- Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setGesture(gesture);
- }
-
- mGestureCategory.setOnItemSelectedListener(new OnItemSelectedListener() {
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mGestures = mGesureStore.getGestures((String) mGestureCategory.getSelectedItem());
- if (!mGestures.isEmpty()) {
- mCurrentGestureIndex = 0;
- Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setGesture(gesture);
- }
- mGesturePad.invalidate();
- }
-
- public void onNothingSelected(AdapterView<?> parent) {
- }
-
- });
-
- Button remove = (Button) findViewById(R.id.remove);
- remove.setOnClickListener(new RemoveGestureListener());
-
- Button next = (Button) findViewById(R.id.next);
- next.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mCurrentGestureIndex >= mGestures.size() - 1) {
- return;
- }
- mCurrentGestureIndex++;
- Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setGesture(gesture);
- mGesturePad.invalidate();
- }
- });
-
- Button previous = (Button) findViewById(R.id.previous);
- previous.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- if (mCurrentGestureIndex >= 1 && !mGestures.isEmpty()) {
- mCurrentGestureIndex--;
- Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setGesture(gesture);
- mGesturePad.invalidate();
- }
- }
- });
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- mGesureStore.save();
- setResult(RESULT_OK);
- finish();
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- mGesureStore.save();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mGesureStore.save();
- }
-}
diff --git a/tests/sketch/tools/Converter.java b/tests/sketch/tools/Converter.java
deleted file mode 100644
index 5db2769..0000000
--- a/tests/sketch/tools/Converter.java
+++ /dev/null
@@ -1,225 +0,0 @@
-import java.io.File;
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Closeable;
-import java.io.DataOutputStream;
-import java.io.FileOutputStream;
-import java.io.DataInputStream;
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-
-/**
- * Converts text-based letter stores to binary-based stores.
- */
-public class Converter {
- private final File mFile;
- private static final short VERSION_NUMBER = 1;
-
- Converter(File file) {
- mFile = file;
- }
-
- private void convert() {
- boolean read = false;
-
- String[] classes = null;
- int iCount = 0;
- int hCount = 0;
- int oCount = 0;
- float[][] iWeights = null;
- float[][] oWeights = null;
-
- BufferedReader reader = null;
-
- try {
- reader = new BufferedReader(new FileReader(mFile));
-
- long start = System.nanoTime();
-
- String line = reader.readLine();
- int startIndex = 0;
- int endIndex;
- endIndex = line.indexOf(" ", startIndex);
- iCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
- startIndex = endIndex + 1;
- endIndex = line.indexOf(" ", startIndex);
- hCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
- startIndex = endIndex + 1;
- endIndex = line.length();
- oCount = Integer.parseInt(line.substring(startIndex, endIndex));
-
- classes = new String[oCount];
- line = reader.readLine();
- startIndex = 0;
-
- for (int i = 0; i < oCount; i++) {
- endIndex = line.indexOf(" ", startIndex);
- classes[i] = line.substring(startIndex, endIndex);
- startIndex = endIndex + 1;
- }
-
- iWeights = new float[hCount][];
- for (int i = 0; i < hCount; i++) {
- iWeights[i] = new float[iCount + 1];
- line = reader.readLine();
- startIndex = 0;
- for (int j = 0; j <= iCount; j++) {
- endIndex = line.indexOf(" ", startIndex);
- iWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
- startIndex = endIndex + 1;
- }
- }
-
- oWeights = new float[oCount][];
- for (int i = 0; i < oCount; i++) {
- oWeights[i] = new float[hCount + 1];
- line = reader.readLine();
- startIndex = 0;
- for (int j = 0; j <= hCount; j++) {
- endIndex = line.indexOf(" ", startIndex);
- oWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
- startIndex = endIndex + 1;
- }
- }
-
- long end = System.nanoTime();
- System.out.println("time to read text file = " +
- ((end - start) / 1000.0f / 1000.0f) + " ms");
-
- read = true;
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- close(reader);
- }
-
- if (read) {
- boolean wrote = false;
- DataOutputStream out = null;
-
- try {
- out = new DataOutputStream(new FileOutputStream(mFile));
-
- out.writeShort(VERSION_NUMBER);
- out.writeInt(iCount);
- out.writeInt(hCount);
- out.writeInt(oCount);
-
- for (String aClass : classes) {
- out.writeUTF(aClass);
- }
-
- for (float[] weights : iWeights) {
- for (float weight : weights) {
- out.writeFloat(weight);
- }
- }
-
- for (float[] weights : oWeights) {
- for (float weight : weights) {
- out.writeFloat(weight);
- }
- }
-
- out.flush();
-
- wrote = true;
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- close(out);
- }
-
- if (wrote) {
- DataInputStream in = null;
-
- try {
- in = new DataInputStream(new BufferedInputStream(new FileInputStream(mFile)));
-
- long start = System.nanoTime();
-
- in.readShort();
- iCount = in.readInt();
- hCount = in.readInt();
- oCount = in.readInt();
-
- classes = new String[oCount];
- for (int i = 0; i < classes.length; i++) {
- classes[i] = in.readUTF();
- }
-
- iWeights = new float[hCount][];
- for (int i = 0; i < iWeights.length; i++) {
- iWeights[i] = new float[iCount];
- for (int j = 0; j < iCount; j++) {
- iWeights[i][j] = in.readFloat();
- }
- }
-
- oWeights = new float[oCount][];
- for (int i = 0; i < oWeights.length; i++) {
- oWeights[i] = new float[hCount];
- for (int j = 0; j < hCount; j++) {
- oWeights[i][j] = in.readFloat();
- }
- }
-
- long end = System.nanoTime();
- System.out.println("time to read binary file = " +
- ((end - start) / 1000.0f / 1000.0f) + " ms");
-
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- close(in);
- }
- }
- }
- }
-
- private static void close(Closeable reader) {
- if (reader != null) {
- try {
- reader.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static void main(String[] args) {
- String fileName = args[0];
- if (fileName != null) {
- File file = new File(fileName);
- if (!file.exists()) {
- printHelp(fileName);
- } else {
- new Converter(file).convert();
- }
- } else {
- printHelp(null);
- }
- }
-
- private static void printHelp(String name) {
- if (name == null) {
- System.out.println("You must specify the name of the file to convert:");
- } else {
- System.out.println("The specified file does not exist: " + name);
- }
- System.out.println("java Converter [filename]");
- System.out.println("");
- System.out.println("\t[filename]\tPath to the file to convert. The file is replaced by "
- + "the conversion result.");
- }
-} \ No newline at end of file
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 76b9d0a..81db323 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -426,7 +426,7 @@ static void checkForIds(const String8& path, ResXMLParser& parser)
}
}
-static void applyFileOverlay(const sp<AaptAssets>& assets,
+static bool applyFileOverlay(const sp<AaptAssets>& assets,
const sp<ResourceTypeSet>& baseSet,
const char *resType)
{
@@ -434,7 +434,7 @@ static void applyFileOverlay(const sp<AaptAssets>& assets,
// Also add any found only in the overlay.
sp<AaptAssets> overlay = assets->getOverlay();
String8 resTypeString(resType);
-
+
// work through the linked list of overlays
while (overlay.get()) {
KeyedVector<String8, sp<ResourceTypeSet> >* overlayRes = overlay->getResources();
@@ -449,7 +449,7 @@ static void applyFileOverlay(const sp<AaptAssets>& assets,
size_t overlayCount = overlaySet->size();
for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {
size_t baseIndex = baseSet->indexOfKey(overlaySet->keyAt(overlayIndex));
- if (baseIndex != UNKNOWN_ERROR) {
+ if (baseIndex < UNKNOWN_ERROR) {
// look for same flavor. For a given file (strings.xml, for example)
// there may be a locale specific or other flavors - we want to match
// the same flavor.
@@ -475,9 +475,10 @@ static void applyFileOverlay(const sp<AaptAssets>& assets,
}
} else {
// this group doesn't exist (a file that's only in the overlay)
- // add it
- baseSet->add(overlaySet->keyAt(overlayIndex),
- overlaySet->valueAt(overlayIndex));
+ fprintf(stderr, "aapt: error: "
+ "*** Resource file '%s' exists only in an overlay\n",
+ overlaySet->keyAt(overlayIndex).string());
+ return false;
}
}
// this overlay didn't have resources for this type
@@ -485,7 +486,7 @@ static void applyFileOverlay(const sp<AaptAssets>& assets,
// try next overlay
overlay = overlay->getOverlay();
}
- return;
+ return true;
}
void addTagAttribute(const sp<XMLNode>& node, const char* ns8,
@@ -611,13 +612,15 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
current = current->getOverlay();
}
// apply the overlay files to the base set
- applyFileOverlay(assets, drawables, "drawable");
- applyFileOverlay(assets, layouts, "layout");
- applyFileOverlay(assets, anims, "anim");
- applyFileOverlay(assets, xmls, "xml");
- applyFileOverlay(assets, raws, "raw");
- applyFileOverlay(assets, colors, "color");
- applyFileOverlay(assets, menus, "menu");
+ if (!applyFileOverlay(assets, drawables, "drawable") ||
+ !applyFileOverlay(assets, layouts, "layout") ||
+ !applyFileOverlay(assets, anims, "anim") ||
+ !applyFileOverlay(assets, xmls, "xml") ||
+ !applyFileOverlay(assets, raws, "raw") ||
+ !applyFileOverlay(assets, colors, "color") ||
+ !applyFileOverlay(assets, menus, "menu")) {
+ return UNKNOWN_ERROR;
+ }
bool hasErrors = false;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 66607a3..b004664 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -729,6 +729,7 @@ status_t compileResourceFile(Bundle* bundle,
String16 curType;
int32_t curFormat = ResTable_map::TYPE_ANY;
bool curIsBag = false;
+ bool curIsBagReplaceOnOverwrite = false;
bool curIsStyled = false;
bool curIsPseudolocalizable = false;
bool localHasErrors = false;
@@ -1171,6 +1172,7 @@ status_t compileResourceFile(Bundle* bundle,
curTag = &array16;
curType = array16;
curIsBag = true;
+ curIsBagReplaceOnOverwrite = true;
ssize_t formatIdx = block.indexOfAttribute(NULL, "format");
if (formatIdx >= 0) {
String16 formatStr = String16(block.getAttributeStringValue(
@@ -1189,12 +1191,14 @@ status_t compileResourceFile(Bundle* bundle,
curType = array16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING;
curIsBag = true;
+ curIsBagReplaceOnOverwrite = true;
curIsPseudolocalizable = true;
} else if (strcmp16(block.getElementName(&len), integer_array16.string()) == 0) {
curTag = &integer_array16;
curType = array16;
curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_INTEGER;
curIsBag = true;
+ curIsBagReplaceOnOverwrite = true;
} else {
SourcePos(in->getPrintableSource(), block.getLineNumber()).error(
"Found tag %s where item is expected\n",
@@ -1229,9 +1233,10 @@ status_t compileResourceFile(Bundle* bundle,
}
if (!localHasErrors) {
- err = outTable->startBag(SourcePos(in->getPrintableSource(), block.getLineNumber()),
- myPackage, curType, ident, parentIdent, &curParams,
- overwrite);
+ err = outTable->startBag(SourcePos(in->getPrintableSource(),
+ block.getLineNumber()), myPackage, curType, ident,
+ parentIdent, &curParams,
+ overwrite, curIsBagReplaceOnOverwrite);
if (err != NO_ERROR) {
hasErrors = localHasErrors = true;
}
@@ -1511,8 +1516,9 @@ status_t ResourceTable::addEntry(const SourcePos& sourcePos,
String8(value).string());
}
#endif
-
- sp<Entry> e = getEntry(package, type, name, sourcePos, params, doSetIndex);
+
+ sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
+ params, doSetIndex);
if (e == NULL) {
return UNKNOWN_ERROR;
}
@@ -1529,6 +1535,7 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos,
const String16& name,
const String16& bagParent,
const ResTable_config* params,
+ bool overlay,
bool replace, bool isId)
{
status_t result = NO_ERROR;
@@ -1549,8 +1556,12 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos,
sourcePos.file.striing(), sourcePos.line, String8(type).string());
}
#endif
-
- sp<Entry> e = getEntry(package, type, name, sourcePos, params);
+ if (overlay && !hasBagOrEntry(package, type, name)) {
+ sourcePos.error("Can't add new bags in an overlay. See '%s'\n",
+ String8(name).string());
+ return UNKNOWN_ERROR;
+ }
+ sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
if (e == NULL) {
return UNKNOWN_ERROR;
}
@@ -1571,7 +1582,7 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos,
return result;
}
- if (replace) {
+ if (overlay && replace) {
return e->emptyBag(sourcePos);
}
return result;
@@ -1604,8 +1615,7 @@ status_t ResourceTable::addBag(const SourcePos& sourcePos,
sourcePos.file.striing(), sourcePos.line, String8(type).string());
}
#endif
-
- sp<Entry> e = getEntry(package, type, name, sourcePos, params);
+ sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
if (e == NULL) {
return UNKNOWN_ERROR;
}
@@ -2888,7 +2898,7 @@ status_t ResourceTable::Entry::setItem(const SourcePos& sourcePos,
mItem.sourcePos.file.string(), mItem.sourcePos.line);
return UNKNOWN_ERROR;
}
-
+
mType = TYPE_ITEM;
mItem = item;
mItemFormat = format;
@@ -3208,11 +3218,17 @@ status_t ResourceTable::Type::addPublic(const SourcePos& sourcePos,
sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
const SourcePos& sourcePos,
const ResTable_config* config,
- bool doSetIndex)
+ bool doSetIndex,
+ bool overlay)
{
int pos = -1;
sp<ConfigList> c = mConfigs.valueFor(entry);
if (c == NULL) {
+ if (overlay == true) {
+ sourcePos.error("Resource %s appears in overlay but not"
+ " in the base package.\n", String8(entry).string());
+ return NULL;
+ }
c = new ConfigList(entry, sourcePos);
mConfigs.add(entry, c);
pos = (int)mOrderedConfigs.size();
@@ -3511,6 +3527,7 @@ sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
const String16& type,
const String16& name,
const SourcePos& sourcePos,
+ bool overlay,
const ResTable_config* config,
bool doSetIndex)
{
@@ -3518,7 +3535,7 @@ sp<ResourceTable::Entry> ResourceTable::getEntry(const String16& package,
if (t == NULL) {
return NULL;
}
- return t->getEntry(name, sourcePos, config, doSetIndex);
+ return t->getEntry(name, sourcePos, config, doSetIndex, overlay);
}
sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index 665232b..ec4331a 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -96,6 +96,7 @@ public:
const String16& name,
const String16& bagParent,
const ResTable_config* params = NULL,
+ bool overlay = false,
bool replace = false,
bool isId = false);
@@ -417,7 +418,8 @@ public:
sp<Entry> getEntry(const String16& entry,
const SourcePos& pos,
const ResTable_config* config = NULL,
- bool doSetIndex = false);
+ bool doSetIndex = false,
+ bool overlay = false);
const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
@@ -501,6 +503,7 @@ private:
const String16& type,
const String16& name,
const SourcePos& pos,
+ bool overlay,
const ResTable_config* config = NULL,
bool doSetIndex = false);
sp<const Entry> getEntry(uint32_t resID,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix.java b/tools/layoutlib/bridge/src/android/graphics/Matrix.java
index 3f9a993..18c0e17 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix.java
@@ -24,8 +24,8 @@ import java.awt.geom.AffineTransform;
*/
public class Matrix extends _Original_Matrix {
- float mValues[] = new float[9];
-
+ float mValues[] = new float[9];
+
/**
* Create an identity matrix
*/
@@ -40,7 +40,7 @@ public class Matrix extends _Original_Matrix {
public Matrix(Matrix src) {
set(src);
}
-
+
/**
* Creates a Matrix object from the float array. The array becomes the internal storage
* of the object.
@@ -50,14 +50,14 @@ public class Matrix extends _Original_Matrix {
assert data.length != 9;
mValues = data;
}
-
+
@Override
public void finalize() throws Throwable {
// pass
}
-
+
//---------- Custom Methods
-
+
/**
* Adds the given transformation to the current Matrix
* <p/>This in effect does this = this*matrix
@@ -65,17 +65,17 @@ public class Matrix extends _Original_Matrix {
*/
private void addTransform(float[] matrix) {
float[] tmp = new float[9];
-
- // first row
+
+ // first row
tmp[0] = matrix[0] * mValues[0] + matrix[1] * mValues[3] + matrix[2] * mValues[6];
tmp[1] = matrix[0] * mValues[1] + matrix[1] * mValues[4] + matrix[2] * mValues[7];
tmp[2] = matrix[0] * mValues[2] + matrix[1] * mValues[5] + matrix[2] * mValues[8];
-
+
// 2nd row
tmp[3] = matrix[3] * mValues[0] + matrix[4] * mValues[3] + matrix[5] * mValues[6];
tmp[4] = matrix[3] * mValues[1] + matrix[4] * mValues[4] + matrix[5] * mValues[7];
tmp[5] = matrix[3] * mValues[2] + matrix[4] * mValues[5] + matrix[5] * mValues[8];
-
+
// 3rd row
tmp[6] = matrix[6] * mValues[0] + matrix[7] * mValues[3] + matrix[8] * mValues[6];
tmp[7] = matrix[6] * mValues[1] + matrix[7] * mValues[4] + matrix[8] * mValues[7];
@@ -84,16 +84,16 @@ public class Matrix extends _Original_Matrix {
// copy the result over to mValues
mValues = tmp;
}
-
+
public AffineTransform getTransform() {
return new AffineTransform(mValues[0], mValues[1], mValues[2],
mValues[3], mValues[4], mValues[5]);
}
-
+
public boolean hasPerspective() {
return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
}
-
+
//----------
/**
@@ -109,7 +109,7 @@ public class Matrix extends _Original_Matrix {
}
}
}
-
+
return true;
}
@@ -122,7 +122,7 @@ public class Matrix extends _Original_Matrix {
public boolean rectStaysRect() {
return (computeTypeMask() & kRectStaysRect_Mask) != 0;
}
-
+
/**
* (deep) copy the src matrix into this matrix. If src is null, reset this
* matrix to the identity matrix.
@@ -151,10 +151,10 @@ public class Matrix extends _Original_Matrix {
return false;
}
}
-
+
return true;
}
-
+
return false;
}
@@ -179,7 +179,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = dy;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
}
/**
@@ -200,7 +200,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = -py;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
// scale
addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 });
@@ -219,7 +219,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = 0;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
}
/**
@@ -240,13 +240,13 @@ public class Matrix extends _Original_Matrix {
mValues[5] = -py;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
// scale
double rad = Math.toRadians(degrees);
float cos = (float)Math.cos(rad);
float sin = (float)Math.sin(rad);
- addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
+ addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
// translate back the pivot
addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
}
@@ -268,7 +268,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = 0;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
}
/**
@@ -289,10 +289,10 @@ public class Matrix extends _Original_Matrix {
mValues[5] = -py;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
// scale
- addTransform(new float[] { cosValue, -sinValue, 0, sinValue, cosValue, 0, 0, 0, 1 });
+ addTransform(new float[] { cosValue, -sinValue, 0, sinValue, cosValue, 0, 0, 0, 1 });
// translate back the pivot
addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
}
@@ -308,7 +308,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = 0;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
}
/**
@@ -329,7 +329,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = -py;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
// scale
addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
@@ -348,7 +348,7 @@ public class Matrix extends _Original_Matrix {
mValues[5] = 0;
mValues[6] = 0;
mValues[7] = 0;
- mValues[7] = 1;
+ mValues[8] = 1;
}
/**
@@ -366,10 +366,10 @@ public class Matrix extends _Original_Matrix {
tmp.addTransform(a.mValues);
set(tmp);
}
-
+
return true;
}
-
+
@Override
public boolean setConcat(_Original_Matrix a, _Original_Matrix b) {
throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
@@ -384,7 +384,7 @@ public class Matrix extends _Original_Matrix {
// create a matrix that will be multiply by this
Matrix m = new Matrix(new float[] { 1, 0, dx, 0, 1, dy, 0, 0, 1 });
m.addTransform(this.mValues);
-
+
System.arraycopy(m.mValues, 0, mValues, 0, 9);
return true;
}
@@ -399,7 +399,7 @@ public class Matrix extends _Original_Matrix {
m.setScale(sx, sy, px, py);
m.addTransform(mValues);
set(m);
-
+
return true;
}
@@ -413,7 +413,7 @@ public class Matrix extends _Original_Matrix {
m.setScale(sx, sy);
m.addTransform(mValues);
set(m);
-
+
return true;
}
@@ -427,7 +427,7 @@ public class Matrix extends _Original_Matrix {
m.setRotate(degrees, px, py);
m.addTransform(mValues);
set(m);
-
+
return true;
}
@@ -441,7 +441,7 @@ public class Matrix extends _Original_Matrix {
m.setRotate(degrees);
m.addTransform(mValues);
set(m);
-
+
return true;
}
@@ -455,7 +455,7 @@ public class Matrix extends _Original_Matrix {
m.setSkew(kx, ky, px, py);
m.addTransform(mValues);
set(m);
-
+
return true;
}
@@ -469,7 +469,7 @@ public class Matrix extends _Original_Matrix {
m.setSkew(kx, ky);
m.addTransform(mValues);
set(m);
-
+
return true;
}
@@ -481,10 +481,10 @@ public class Matrix extends _Original_Matrix {
Matrix m = new Matrix(other);
other.addTransform(mValues);
set(m);
-
+
return true;
}
-
+
@Override
public boolean preConcat(_Original_Matrix other) {
throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
@@ -513,7 +513,7 @@ public class Matrix extends _Original_Matrix {
addTransform(new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 });
// translate back the pivot
addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-
+
return true;
}
@@ -540,10 +540,10 @@ public class Matrix extends _Original_Matrix {
double rad = Math.toRadians(degrees);
float cos = (float)Math.cos(rad);
float sin = (float)Math.sin(rad);
- addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
+ addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
// translate back the pivot
addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-
+
return true;
}
@@ -557,7 +557,7 @@ public class Matrix extends _Original_Matrix {
float cos = (float)Math.cos(rad);
float sin = (float)Math.sin(rad);
addTransform(new float[] { cos, -sin, 0, sin, cos, 0, 0, 0, 1 });
-
+
return true;
}
@@ -574,7 +574,7 @@ public class Matrix extends _Original_Matrix {
addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
// translate back the pivot
addTransform(new float[] { 1, 0, px, 0, 1, py, 0, 0, 1 });
-
+
return true;
}
@@ -585,7 +585,7 @@ public class Matrix extends _Original_Matrix {
@Override
public boolean postSkew(float kx, float ky) {
addTransform(new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
-
+
return true;
}
@@ -595,7 +595,7 @@ public class Matrix extends _Original_Matrix {
*/
public boolean postConcat(Matrix other) {
addTransform(other.mValues);
-
+
return true;
}
@@ -603,7 +603,7 @@ public class Matrix extends _Original_Matrix {
public boolean postConcat(_Original_Matrix other) {
throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
}
-
+
/** Controlls how the src rect should align into the dst rect for
setRectToRect().
*/
@@ -634,7 +634,7 @@ public class Matrix extends _Original_Matrix {
*/
END (3);
- // the native values must match those in SkMatrix.h
+ // the native values must match those in SkMatrix.h
ScaleToFit(int nativeInt) {
this.nativeInt = nativeInt;
}
@@ -655,7 +655,7 @@ public class Matrix extends _Original_Matrix {
if (dst == null || src == null) {
throw new NullPointerException();
}
-
+
if (src.isEmpty()) {
reset();
return false;
@@ -689,7 +689,7 @@ public class Matrix extends _Original_Matrix {
} else {
diff = dst.height() - src.height() * sy;
}
-
+
if (stf == ScaleToFit.CENTER) {
diff = diff / 2;
}
@@ -712,12 +712,12 @@ public class Matrix extends _Original_Matrix {
mValues[8] = 1;
return true;
}
-
+
@Override
public boolean setRectToRect(RectF src, RectF dst, _Original_Matrix.ScaleToFit stf) {
throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
}
-
+
/**
* Set the matrix such that the specified src points would map to the
* specified dst points. The "points" are represented as an array of floats,
@@ -749,7 +749,7 @@ public class Matrix extends _Original_Matrix {
public boolean invert(Matrix inverse) {
throw new UnsupportedOperationException("STUB NEEDED");
}
-
+
@Override
public boolean invert(_Original_Matrix inverse) {
throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN");
@@ -772,7 +772,7 @@ public class Matrix extends _Original_Matrix {
checkPointArrays(src, srcIndex, dst, dstIndex, pointCount);
throw new UnsupportedOperationException("STUB NEEDED");
}
-
+
/**
* Apply this matrix to the array of 2D vectors specified by src, and write
* the transformed vectors into the array of vectors specified by dst. The
@@ -790,7 +790,7 @@ public class Matrix extends _Original_Matrix {
checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount);
throw new UnsupportedOperationException("STUB NEEDED");
}
-
+
/**
* Apply this matrix to the array of 2D points specified by src, and write
* the transformed points into the array of points specified by dst. The
@@ -883,7 +883,7 @@ public class Matrix extends _Original_Matrix {
public float mapRadius(float radius) {
throw new UnsupportedOperationException("STUB NEEDED");
}
-
+
/** Copy 9 values from the matrix into the array.
*/
@Override
@@ -907,7 +907,7 @@ public class Matrix extends _Original_Matrix {
}
System.arraycopy(values, 0, mValues, 0, mValues.length);
}
-
+
@SuppressWarnings("unused")
private final static int kIdentity_Mask = 0;
private final static int kTranslate_Mask = 0x01; //!< set if the matrix has translation
@@ -917,7 +917,7 @@ public class Matrix extends _Original_Matrix {
private final static int kRectStaysRect_Mask = 0x10;
@SuppressWarnings("unused")
private final static int kUnknown_Mask = 0x80;
-
+
@SuppressWarnings("unused")
private final static int kAllMasks = kTranslate_Mask |
kScale_Mask |
@@ -942,43 +942,43 @@ public class Matrix extends _Original_Matrix {
if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
mask |= kPerspective_Mask;
}
-
+
if (mValues[2] != 0. || mValues[5] != 0.) {
mask |= kTranslate_Mask;
}
-
+
float m00 = mValues[0];
float m01 = mValues[1];
float m10 = mValues[3];
float m11 = mValues[4];
-
+
if (m01 != 0. || m10 != 0.) {
mask |= kAffine_Mask;
}
-
+
if (m00 != 1. || m11 != 1.) {
mask |= kScale_Mask;
}
-
+
if ((mask & kPerspective_Mask) == 0) {
// map non-zero to 1
int im00 = m00 != 0 ? 1 : 0;
int im01 = m01 != 0 ? 1 : 0;
int im10 = m10 != 0 ? 1 : 0;
int im11 = m11 != 0 ? 1 : 0;
-
+
// record if the (p)rimary and (s)econdary diagonals are all 0 or
// all non-zero (answer is 0 or 1)
int dp0 = (im00 | im11) ^ 1; // true if both are 0
int dp1 = im00 & im11; // true if both are 1
int ds0 = (im01 | im10) ^ 1; // true if both are 0
int ds1 = im01 & im10; // true if both are 1
-
+
// return 1 if primary is 1 and secondary is 0 or
// primary is 0 and secondary is 1
mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
}
-
+
return mask;
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index baa3d53..d0896b5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -966,6 +966,12 @@ public final class BridgeContext extends Context {
}
@Override
+ public File getSharedPrefsFile(String name) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
public SharedPreferences getSharedPreferences(String arg0, int arg1) {
// TODO Auto-generated method stub
return null;
diff --git a/vpn/java/android/net/vpn/IVpnService.aidl b/vpn/java/android/net/vpn/IVpnService.aidl
new file mode 100644
index 0000000..0e658df
--- /dev/null
+++ b/vpn/java/android/net/vpn/IVpnService.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+import android.net.vpn.VpnProfile;
+
+/**
+ * Interface to access a VPN service.
+ * {@hide}
+ */
+interface IVpnService {
+ /**
+ * Sets up the VPN connection.
+ * @param profile the profile object
+ * @param username the username for authentication
+ * @param password the corresponding password for authentication
+ */
+ boolean connect(in VpnProfile profile, String username, String password);
+
+ /**
+ * Tears down the VPN connection.
+ */
+ void disconnect();
+
+ /**
+ * Makes the service broadcast the connectivity state.
+ */
+ void checkStatus(in VpnProfile profile);
+}
diff --git a/vpn/java/android/net/vpn/L2tpIpsecProfile.java b/vpn/java/android/net/vpn/L2tpIpsecProfile.java
new file mode 100644
index 0000000..181619d
--- /dev/null
+++ b/vpn/java/android/net/vpn/L2tpIpsecProfile.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+import android.os.Parcel;
+
+/**
+ * The profile for L2TP-over-IPSec type of VPN.
+ * {@hide}
+ */
+public class L2tpIpsecProfile extends VpnProfile {
+ private static final long serialVersionUID = 1L;
+
+ private String mUserCertificate;
+ private String mCaCertificate;
+ private String mUserkey;
+
+ @Override
+ public VpnType getType() {
+ return VpnType.L2TP_IPSEC;
+ }
+
+ public void setCaCertificate(String name) {
+ mCaCertificate = name;
+ }
+
+ public String getCaCertificate() {
+ return mCaCertificate;
+ }
+
+ public void setUserCertificate(String name) {
+ mUserCertificate = name;
+ }
+
+ public String getUserCertificate() {
+ return mUserCertificate;
+ }
+
+ public void setUserkey(String name) {
+ mUserkey = name;
+ }
+
+ public String getUserkey() {
+ return mUserkey;
+ }
+
+ @Override
+ protected void readFromParcel(Parcel in) {
+ super.readFromParcel(in);
+ mCaCertificate = in.readString();
+ mUserCertificate = in.readString();
+ mUserkey = in.readString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ super.writeToParcel(parcel, flags);
+ parcel.writeString(mCaCertificate);
+ parcel.writeString(mUserCertificate);
+ parcel.writeString(mUserkey);
+ }
+}
diff --git a/vpn/java/android/net/vpn/L2tpProfile.java b/vpn/java/android/net/vpn/L2tpProfile.java
new file mode 100644
index 0000000..59d4981
--- /dev/null
+++ b/vpn/java/android/net/vpn/L2tpProfile.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+/**
+ * The profile for L2TP type of VPN.
+ * {@hide}
+ */
+public class L2tpProfile extends VpnProfile {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public VpnType getType() {
+ return VpnType.L2TP;
+ }
+}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
new file mode 100644
index 0000000..98795bd
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.util.Log;
+
+/**
+ * The class provides interface to manage all VPN-related tasks, including:
+ * <ul>
+ * <li>The list of supported VPN types.
+ * <li>API's to start/stop the service of a particular type.
+ * <li>API's to start the settings activity.
+ * <li>API's to create a profile.
+ * <li>API's to register/unregister a connectivity receiver and the keys to
+ * access the fields in a connectivity broadcast event.
+ * </ul>
+ * {@hide}
+ */
+public class VpnManager {
+ // Action for broadcasting a connectivity state.
+ private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
+ /** Key to the profile name of a connectivity broadcast event. */
+ public static final String BROADCAST_PROFILE_NAME = "profile_name";
+ /** Key to the connectivity state of a connectivity broadcast event. */
+ public static final String BROADCAST_CONNECTION_STATE = "connection_state";
+
+ public static final String PROFILES_PATH = "/data/misc/vpn/profiles";
+
+ private static final String PACKAGE_PREFIX =
+ VpnManager.class.getPackage().getName() + ".";
+
+ // Action to start VPN service
+ private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE";
+
+ // Action to start VPN settings
+ private static final String ACTION_VPN_SETTINGS = PACKAGE_PREFIX + "SETTINGS";
+
+ private static final String TAG = VpnManager.class.getSimpleName();
+
+ /**
+ * Returns all supported VPN types.
+ */
+ public static VpnType[] getSupportedVpnTypes() {
+ return VpnType.values();
+ }
+
+ private Context mContext;
+
+ /**
+ * Creates a manager object with the specified context.
+ */
+ public VpnManager(Context c) {
+ mContext = c;
+ }
+
+ /**
+ * Creates a VPN profile of the specified type.
+ *
+ * @param type the VPN type
+ * @return the profile object
+ */
+ public VpnProfile createVpnProfile(VpnType type) {
+ return createVpnProfile(type, false);
+ }
+
+ /**
+ * Creates a VPN profile of the specified type.
+ *
+ * @param type the VPN type
+ * @param customized true if the profile is custom made
+ * @return the profile object
+ */
+ public VpnProfile createVpnProfile(VpnType type, boolean customized) {
+ try {
+ VpnProfile p = (VpnProfile) type.getProfileClass().newInstance();
+ p.setCustomized(customized);
+ return p;
+ } catch (InstantiationException e) {
+ return null;
+ } catch (IllegalAccessException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Starts the VPN service to establish VPN connection.
+ */
+ public void startVpnService() {
+ mContext.startService(new Intent(ACTION_VPN_SERVICE));
+ }
+
+ /**
+ * Stops the VPN service.
+ */
+ public void stopVpnService() {
+ mContext.stopService(new Intent(ACTION_VPN_SERVICE));
+ }
+
+ /**
+ * Binds the specified ServiceConnection with the VPN service.
+ */
+ public boolean bindVpnService(ServiceConnection c) {
+ if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) {
+ Log.w(TAG, "failed to connect to VPN service");
+ return false;
+ } else {
+ Log.d(TAG, "succeeded to connect to VPN service");
+ return true;
+ }
+ }
+
+ /** Broadcasts the connectivity state of the specified profile. */
+ public void broadcastConnectivity(String profileName, VpnState s) {
+ Intent intent = new Intent(ACTION_VPN_CONNECTIVITY);
+ intent.putExtra(BROADCAST_PROFILE_NAME, profileName);
+ intent.putExtra(BROADCAST_CONNECTION_STATE, s);
+ mContext.sendBroadcast(intent);
+ }
+
+ public void registerConnectivityReceiver(BroadcastReceiver r) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(VpnManager.ACTION_VPN_CONNECTIVITY);
+ mContext.registerReceiver(r, filter);
+ }
+
+ public void unregisterConnectivityReceiver(BroadcastReceiver r) {
+ mContext.unregisterReceiver(r);
+ }
+
+ /** Starts the VPN settings activity. */
+ public void startSettingsActivity() {
+ Intent intent = new Intent(ACTION_VPN_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
+ }
+
+ /** Creates an intent to start the VPN settings activity. */
+ public Intent createSettingsActivityIntent() {
+ Intent intent = new Intent(ACTION_VPN_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return intent;
+ }
+}
diff --git a/vpn/java/android/net/vpn/VpnProfile.aidl b/vpn/java/android/net/vpn/VpnProfile.aidl
new file mode 100644
index 0000000..ad34bfc
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnProfile.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+parcelable VpnProfile;
diff --git a/vpn/java/android/net/vpn/VpnProfile.java b/vpn/java/android/net/vpn/VpnProfile.java
new file mode 100644
index 0000000..9e24da4
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnProfile.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * A VPN profile.
+ * {@hide}
+ */
+public abstract class VpnProfile implements Parcelable, Serializable {
+ private static final long serialVersionUID = 1L;
+ private String mName; // unique display name
+ private String mId; // unique identifier
+ private String mServerName; // VPN server name
+ private String mDomainSuffices; // space separated list
+ private String mRouteList; // space separated list
+ private String mSavedUsername;
+ private boolean mIsCustomized;
+ private transient VpnState mState = VpnState.IDLE;
+
+ /** Sets a user-friendly name for this profile. */
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Sets an ID for this profile. The caller should make sure the
+ * uniqueness of the ID.
+ */
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Sets the name of the VPN server. Used for DNS lookup.
+ */
+ public void setServerName(String name) {
+ mServerName = name;
+ }
+
+ public String getServerName() {
+ return mServerName;
+ }
+
+ /**
+ * Sets the domain suffices for DNS resolution.
+ *
+ * @param entries a comma-separated list of domain suffices
+ */
+ public void setDomainSuffices(String entries) {
+ mDomainSuffices = entries;
+ }
+
+ public String getDomainSuffices() {
+ return mDomainSuffices;
+ }
+
+ /**
+ * Sets the routing info for this VPN connection.
+ *
+ * @param entries a comma-separated list of routes; each entry is in the
+ * format of "(network address)/(network mask)"
+ */
+ public void setRouteList(String entries) {
+ mRouteList = entries;
+ }
+
+ public String getRouteList() {
+ return mRouteList;
+ }
+
+ public void setSavedUsername(String name) {
+ mSavedUsername = name;
+ }
+
+ public String getSavedUsername() {
+ return mSavedUsername;
+ }
+
+ public void setState(VpnState state) {
+ mState = state;
+ }
+
+ public VpnState getState() {
+ return ((mState == null) ? VpnState.IDLE : mState);
+ }
+
+ public boolean isIdle() {
+ return (mState == VpnState.IDLE);
+ }
+
+ /**
+ * Returns whether this profile is custom made (as opposed to being
+ * created by provided user interface).
+ */
+ public boolean isCustomized() {
+ return mIsCustomized;
+ }
+
+ /**
+ * Returns the VPN type of the profile.
+ */
+ public abstract VpnType getType();
+
+ void setCustomized(boolean customized) {
+ mIsCustomized = customized;
+ }
+
+ protected void readFromParcel(Parcel in) {
+ mName = in.readString();
+ mId = in.readString();
+ mServerName = in.readString();
+ mDomainSuffices = in.readString();
+ mRouteList = in.readString();
+ mSavedUsername = in.readString();
+ }
+
+ public static final Parcelable.Creator<VpnProfile> CREATOR =
+ new Parcelable.Creator<VpnProfile>() {
+ public VpnProfile createFromParcel(Parcel in) {
+ VpnType type = Enum.valueOf(VpnType.class, in.readString());
+ boolean customized = in.readInt() > 0;
+ VpnProfile p = new VpnManager(null).createVpnProfile(type,
+ customized);
+ if (p == null) return null;
+ p.readFromParcel(in);
+ return p;
+ }
+
+ public VpnProfile[] newArray(int size) {
+ return new VpnProfile[size];
+ }
+ };
+
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(getType().toString());
+ parcel.writeInt(mIsCustomized ? 1 : 0);
+ parcel.writeString(mName);
+ parcel.writeString(mId);
+ parcel.writeString(mServerName);
+ parcel.writeString(mDomainSuffices);
+ parcel.writeString(mRouteList);
+ parcel.writeString(mSavedUsername);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/vpn/java/android/net/vpn/VpnState.java b/vpn/java/android/net/vpn/VpnState.java
new file mode 100644
index 0000000..977d938
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnState.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+/**
+ * Enumeration of all VPN states.
+ *
+ * A normal VPN connection lifetime starts in {@link IDLE}. When a new
+ * connection is about to be set up, it goes to {@link CONNECTING} and then
+ * {@link CONNECTED} if successful; back to {@link IDLE} if failed.
+ * When the connection is about to be torn down, it goes to
+ * {@link DISCONNECTING} and then {@link IDLE}.
+ * {@link CANCELLED} is a state when a VPN connection attempt is aborted, and
+ * is in transition to {@link IDLE}.
+ * {@hide}
+ */
+public enum VpnState {
+ CONNECTING, DISCONNECTING, CANCELLED, CONNECTED, IDLE
+}
diff --git a/vpn/java/android/net/vpn/VpnType.java b/vpn/java/android/net/vpn/VpnType.java
new file mode 100644
index 0000000..91b0ea2
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnType.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vpn;
+
+/**
+ * Enumeration of all supported VPN types.
+ * {@hide}
+ */
+public enum VpnType {
+ L2TP_IPSEC("L2TP/IPSec", L2tpIpsecProfile.class),
+ L2TP("L2TP", L2tpProfile.class);
+
+ private String mDisplayName;
+ private Class<? extends VpnProfile> mClass;
+
+ VpnType(String displayName, Class<? extends VpnProfile> klass) {
+ mDisplayName = displayName;
+ mClass = klass;
+ }
+
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+
+ public Class<? extends VpnProfile> getProfileClass() {
+ return mClass;
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 3bee3b6..1b7c0cd 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -42,13 +42,27 @@ public class WifiConfiguration implements Parcelable {
public static final String priorityVarName = "priority";
/** {@hide} */
public static final String hiddenSSIDVarName = "scan_ssid";
+ /** {@hide} */
+ public static final String eapVarName = "eap";
+ /** {@hide} */
+ public static final String identityVarName = "identity";
+ /** {@hide} */
+ public static final String anonymousIdentityVarName = "anonymous_identity";
+ /** {@hide} */
+ public static final String clientCertVarName = "client_cert";
+ /** {@hide} */
+ public static final String caCertVarName = "ca_cert";
+ /** {@hide} */
+ public static final String privateKeyVarName = "private_key";
+ /** {@hide} */
+ public static final String privateKeyPasswdVarName = "private_key_passwd";
/**
* Recognized key management schemes.
*/
public static class KeyMgmt {
private KeyMgmt() { }
-
+
/** WPA is not used; plaintext or static WEP could be used. */
public static final int NONE = 0;
/** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
@@ -63,7 +77,7 @@ public class WifiConfiguration implements Parcelable {
public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X" };
}
-
+
/**
* Recognized security protocols.
*/
@@ -112,7 +126,7 @@ public class WifiConfiguration implements Parcelable {
public static final int CCMP = 2;
public static final String varName = "pairwise";
-
+
public static final String[] strings = { "NONE", "TKIP", "CCMP" };
}
@@ -202,7 +216,7 @@ public class WifiConfiguration implements Parcelable {
* string otherwise.
*/
public String[] wepKeys;
-
+
/** Default WEP key index, ranging from 0 to 3. */
public int wepTxKeyIndex;
@@ -249,6 +263,38 @@ public class WifiConfiguration implements Parcelable {
*/
public BitSet allowedGroupCiphers;
+ /* The following fields are used for EAP/IEEE8021X authentication */
+
+ /**
+ * The eap mode should be PEAP, TLS or TTLS.
+ * {@hide}
+ */
+ public String eap;
+ /**
+ * The identity of the user in string,
+ * which is used for the authentication.
+ * {@hide}
+ */
+ public String identity;
+ /** {@hide} */
+ public String anonymousIdentity;
+ /** The path of the client certificate file.
+ * {@hide}
+ */
+ public String clientCert;
+ /** The path of the CA certificate file.
+ * {@hide}
+ */
+ public String caCert;
+ /** The path of the private key file.
+ * {@hide}
+ */
+ public String privateKey;
+ /** The password of the private key file if encrypted.
+ * {@hide}
+ */
+ public String privateKeyPasswd;
+
public WifiConfiguration() {
networkId = -1;
SSID = null;
@@ -263,6 +309,13 @@ public class WifiConfiguration implements Parcelable {
wepKeys = new String[4];
for (int i = 0; i < wepKeys.length; i++)
wepKeys[i] = null;
+ eap = null;
+ identity = null;
+ anonymousIdentity = null;
+ clientCert = null;
+ caCert = null;
+ privateKey = null;
+ privateKeyPasswd = null;
}
public String toString() {
@@ -333,10 +386,39 @@ public class WifiConfiguration implements Parcelable {
}
}
}
- sbuf.append('\n');
+ sbuf.append('\n').append(" PSK: ");
if (this.preSharedKey != null) {
- sbuf.append(" PSK: ").append('*');
+ sbuf.append('*');
+ }
+ sbuf.append('\n').append(" eap: ");
+ if (this.eap != null) {
+ sbuf.append(eap);
}
+ sbuf.append('\n').append(" Identity: ");
+ if (this.identity != null) {
+ sbuf.append(identity);
+ }
+ sbuf.append('\n').append(" AnonymousIdentity: ");
+ if (this.anonymousIdentity != null) {
+ sbuf.append(anonymousIdentity);
+ }
+ sbuf.append('\n').append(" ClientCert: ");
+ if (this.clientCert != null) {
+ sbuf.append(clientCert);
+ }
+ sbuf.append('\n').append(" CaCert: ");
+ if (this.caCert != null) {
+ sbuf.append(caCert);
+ }
+ sbuf.append('\n').append(" PrivateKey: ");
+ if (this.privateKey != null) {
+ sbuf.append(privateKey);
+ }
+ sbuf.append('\n').append(" PrivateKeyPasswd: ");
+ if (this.privateKeyPasswd != null) {
+ sbuf.append(privateKeyPasswd);
+ }
+ sbuf.append('\n');
return sbuf.toString();
}
@@ -394,6 +476,13 @@ public class WifiConfiguration implements Parcelable {
writeBitSet(dest, allowedAuthAlgorithms);
writeBitSet(dest, allowedPairwiseCiphers);
writeBitSet(dest, allowedGroupCiphers);
+ dest.writeString(eap);
+ dest.writeString(identity);
+ dest.writeString(anonymousIdentity);
+ dest.writeString(clientCert);
+ dest.writeString(caCert);
+ dest.writeString(privateKey);
+ dest.writeString(privateKeyPasswd);
}
/** Implement the Parcelable interface {@hide} */
@@ -416,6 +505,13 @@ public class WifiConfiguration implements Parcelable {
config.allowedAuthAlgorithms = readBitSet(in);
config.allowedPairwiseCiphers = readBitSet(in);
config.allowedGroupCiphers = readBitSet(in);
+ config.eap = in.readString();
+ config.identity = in.readString();
+ config.anonymousIdentity = in.readString();
+ config.clientCert = in.readString();
+ config.caCert = in.readString();
+ config.privateKey = in.readString();
+ config.privateKeyPasswd = in.readString();
return config;
}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 3851ac0..0920567 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -79,6 +79,8 @@ public class WifiNative {
public native static int getRssiCommand();
+ public native static int getRssiApproxCommand();
+
public native static int getLinkSpeedCommand();
public native static String getMacAddressCommand();
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index e6f4130..f84bccc 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1029,7 +1029,7 @@ public class WifiStateTracker extends NetworkStateTracker {
case EVENT_POLL_INTERVAL:
if (mWifiInfo.getSupplicantState() != SupplicantState.UNINITIALIZED) {
- requestPolledInfo(mWifiInfo);
+ requestPolledInfo(mWifiInfo, true);
if (mWifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
setPollTimer();
}
@@ -1276,7 +1276,7 @@ public class WifiStateTracker extends NetworkStateTracker {
*/
public WifiInfo requestConnectionInfo() {
requestConnectionStatus(mWifiInfo);
- requestPolledInfo(mWifiInfo);
+ requestPolledInfo(mWifiInfo, false);
return mWifiInfo;
}
@@ -1331,10 +1331,14 @@ public class WifiStateTracker extends NetworkStateTracker {
* Get the dynamic information that is not reported via events.
* @param info the object into which the information should be captured.
*/
- private synchronized void requestPolledInfo(WifiInfo info)
+ private synchronized void requestPolledInfo(WifiInfo info, boolean polling)
{
int newRssi = WifiNative.getRssiCommand();
- if (newRssi != -1 && -200 < newRssi && newRssi < 100) { // screen out invalid values
+ if (newRssi != -1 && -200 < newRssi && newRssi < 256) { // screen out invalid values
+ /* some implementations avoid negative values by adding 256
+ * so we need to adjust for that here.
+ */
+ if (newRssi > 0) newRssi -= 256;
info.setRssi(newRssi);
/*
* Rather then sending the raw RSSI out every time it